[ACS-10286] Add label and aria expanded to the rule set header (#4834)

* [ACS-10286] Add proper role and aria attributes to rule section header

* [ACS-10286] Add unit tests and main rule set coverage

* [ACS-10286] Rework component to use material expansion panel

* [ACS-10286] CR changes

* [ACS-10286] excluded XAT-907

---------

Co-authored-by: Adam Świderski <adam.tomasz.swiderski@gmail.com>
This commit is contained in:
MichalKinas
2025-10-08 13:18:16 +02:00
committed by GitHub
co-authored by Adam Świderski
parent 4d88927db5
commit 199d31f1cd
6 changed files with 111 additions and 108 deletions
@@ -1,3 +1,4 @@
{
"XAT-897": "https://hyland.atlassian.net/browse/ACS-5503"
"XAT-897": "https://hyland.atlassian.net/browse/ACS-5503",
"XAT-907": "https://hyland.atlassian.net/browse/ACS-10486"
}
@@ -126,7 +126,8 @@
"LOADING_RULES": "Loading rules",
"TOGGLE_RULE_STATE": "Toggle {{ name }} rule",
"INHERITED_RULES_WILL_BE_RUN_FIRST": "Inherited rules will be run first",
"ALL_LINKED_RULES_ARE_DISABLED": "All rules linked from this rule set are disabled"
"ALL_LINKED_RULES_ARE_DISABLED": "All rules linked from this rule set are disabled",
"EDIT_LINK_LABEL": "Link rules from another folder"
},
"LINK_RULES_DIALOG": {
"TITLE": "Select a folder to link rules from",
@@ -172,7 +172,7 @@ describe('ManageRulesSmartComponent', () => {
expect(component).toBeTruthy();
expect(folderRuleSetsService.loadRuleSets).toHaveBeenCalledOnceWith(component.nodeId);
const ruleGroupingSections = unitTestingUtils.getAllByCSS(`[data-automation-id="rule-list-item"]`);
const ruleGroupingSections = unitTestingUtils.getAllByCSS('.aca-rule-list__item');
const deleteRuleBtn = unitTestingUtils.getByCSS('#delete-rule-btn');
@@ -1,87 +1,83 @@
<div
*ngIf="inheritedRuleSetGroupingItems.length > 0"
class="aca-rule-list__item"
data-automation-id="rule-list-item"
[ngClass]="{ 'aca-expanded': inheritedRuleSetsExpanded }">
<mat-accordion multi>
@if (inheritedRuleSetGroupingItems.length > 0) {
<mat-expansion-panel [expanded]="true" class="aca-rule-list__item">
<mat-expansion-panel-header class="aca-rule-list__item__header">
<mat-panel-title>
<span class="aca-rule-list__item__header__title">
{{ 'ACA_FOLDER_RULES.RULE_LIST.INHERITED_RULES' | translate }}
<mat-icon
class="aca-rule-list__item__header__title__icon"
[matTooltip]="'ACA_FOLDER_RULES.RULE_LIST.INHERITED_RULES_WILL_BE_RUN_FIRST' | translate">
info
</mat-icon>
</span>
</mat-panel-title>
</mat-expansion-panel-header>
<aca-rule-list-grouping
[items]="inheritedRuleSetGroupingItems"
[selectedRule]="selectedRule"
(selectRule)="onSelectRule($event)"
(ruleEnabledChanged)="onRuleEnabledChanged($event)"
(loadMoreRules)="onLoadMoreRules($event)"
(loadMoreRuleSets)="onLoadMoreRuleSets()" />
</mat-expansion-panel>
}
@if (mainRuleSetGroupingItems.length > 0 || isMainRuleSetLinked) {
<mat-expansion-panel [expanded]="true" class="aca-rule-list__item">
<mat-expansion-panel-header class="aca-rule-list__item__header">
<mat-panel-title>
<span class="aca-rule-list__item__header__title" data-automation-id="main-rule-set-title">
@if (isMainRuleSetOwned) {
{{ 'ACA_FOLDER_RULES.RULE_LIST.OWNED_RULES' | translate }}
} @else {
{{ 'ACA_FOLDER_RULES.RULE_LIST.LINKED_RULES' | translate }}
}
</span>
<div
tabindex="0"
class="aca-rule-list__item__header"
matRipple matRippleColor="hsla(0,0%,0%,0.05)"
(click)="inheritedRuleSetsExpanded = !inheritedRuleSetsExpanded"
(keyup.enter)="inheritedRuleSetsExpanded = !inheritedRuleSetsExpanded">
@if (!isMainRuleSetOwned) {
<mat-icon
class="aca-rule-list__item__header__icon"
tabindex="0"
aria-hidden="false"
[attr.aria-label]="'ACA_FOLDER_RULES.RULE_LIST.EDIT_LINK_LABEL' | translate"
[attr.title]="'ACA_FOLDER_RULES.RULE_LIST.EDIT_LINK_LABEL' | translate"
(keydown.enter)="onRuleSetEditLinkClicked($event)"
(keydown.enter)="onRuleSetEditLinkClicked($event)"
(click)="onRuleSetEditLinkClicked($event)">
edit
</mat-icon>
<mat-icon
class="aca-rule-list__item__header__icon"
tabindex="0"
aria-hidden="false"
[attr.aria-label]="'ACA_FOLDER_RULES.CONFIRMATION_DIALOG.DELETE_RULE_SET_LINK.TITLE' | translate"
[attr.title]="'ACA_FOLDER_RULES.CONFIRMATION_DIALOG.DELETE_RULE_SET_LINK.TITLE' | translate"
(keydown.enter)="onRuleSetUnlinkClicked($event)"
(click)="onRuleSetUnlinkClicked($event)">
link_off
</mat-icon>
}
</mat-panel-title>
<span class="aca-rule-list__item__header__title">
{{ 'ACA_FOLDER_RULES.RULE_LIST.INHERITED_RULES' | translate }}
<mat-icon class="aca-rule-list__item__header__title__icon" [matTooltip]="'ACA_FOLDER_RULES.RULE_LIST.INHERITED_RULES_WILL_BE_RUN_FIRST' | translate">
info
</mat-icon>
</span>
<mat-icon class="aca-rule-list__item__header__icon">
{{ inheritedRuleSetsExpanded ? 'expand_more' : 'chevron_right' }}
</mat-icon>
</div>
<aca-rule-list-grouping
*ngIf="inheritedRuleSetsExpanded"
[items]="inheritedRuleSetGroupingItems"
[selectedRule]="selectedRule"
(selectRule)="onSelectRule($event)"
(ruleEnabledChanged)="onRuleEnabledChanged($event)"
(loadMoreRules)="onLoadMoreRules($event)"
(loadMoreRuleSets)="onLoadMoreRuleSets()" />
</div>
<div
*ngIf="mainRuleSetGroupingItems.length > 0 || isMainRuleSetLinked"
class="aca-rule-list__item"
data-automation-id="rule-list-item"
[ngClass]="{ 'aca-expanded': mainRuleSetExpanded }">
<div
tabindex="0"
class="aca-rule-list__item__header"
matRipple matRippleColor="hsla(0,0%,0%,0.05)"
(click)="mainRuleSetExpanded = !mainRuleSetExpanded"
(keyup.enter)="mainRuleSetExpanded = !mainRuleSetExpanded">
<span class="aca-rule-list__item__header__title" data-automation-id="main-rule-set-title">
<ng-container *ngIf="isMainRuleSetOwned; else linkedRuleSet">
{{ 'ACA_FOLDER_RULES.RULE_LIST.OWNED_RULES' | translate }}
</ng-container>
<ng-template #linkedRuleSet>
{{ 'ACA_FOLDER_RULES.RULE_LIST.LINKED_RULES' | translate }}
</ng-template>
</span>
<ng-container *ngIf="!isMainRuleSetOwned">
<mat-icon class="aca-rule-list__item__header__icon" (click)="onRuleSetEditLinkClicked($event)">edit</mat-icon>
<mat-icon class="aca-rule-list__item__header__icon" (click)="onRuleSetUnlinkClicked($event)">link_off</mat-icon>
</ng-container>
<mat-icon class="aca-rule-list__item__header__icon">
{{ mainRuleSetExpanded ? 'expand_more' : 'chevron_right' }}
</mat-icon>
</div>
<ng-container *ngIf="mainRuleSetExpanded">
<aca-rule-list-grouping
*ngIf="mainRuleSetGroupingItems.length > 0; else emptyLinkedRuleSet"
[items]="mainRuleSetGroupingItems"
[selectedRule]="selectedRule"
[showEnabledToggles]="isMainRuleSetOwned"
(selectRule)="onSelectRule($event)"
(ruleEnabledChanged)="onRuleEnabledChanged($event)"
(loadMoreRules)="onLoadMoreRules($event)" />
<ng-template #emptyLinkedRuleSet>
</mat-expansion-panel-header>
@if (mainRuleSetGroupingItems.length > 0) {
<aca-rule-list-grouping
[items]="mainRuleSetGroupingItems"
[selectedRule]="selectedRule"
[showEnabledToggles]="isMainRuleSetOwned"
(selectRule)="onSelectRule($event)"
(ruleEnabledChanged)="onRuleEnabledChanged($event)"
(loadMoreRules)="onLoadMoreRules($event)" />
} @else {
<div class="aca-rule-list__item__all-linked-rules-are-disabled">
{{ 'ACA_FOLDER_RULES.RULE_LIST.ALL_LINKED_RULES_ARE_DISABLED' | translate }}
<button *ngIf="mainRuleSet?.owningFolder?.id" mat-stroked-button [routerLink]="['/nodes', mainRuleSet.owningFolder.id, 'rules']">
{{ 'ACA_FOLDER_RULES.MANAGE_RULES.TOOLBAR.ACTIONS.SEE_IN_FOLDER' | translate }}
</button>
@if (mainRuleSet?.owningFolder?.id) {
<button mat-stroked-button [routerLink]="['/nodes', mainRuleSet.owningFolder.id, 'rules']">
{{ 'ACA_FOLDER_RULES.MANAGE_RULES.TOOLBAR.ACTIONS.SEE_IN_FOLDER' | translate }}
</button>
}
</div>
</ng-template>
</ng-container>
</div>
}
</mat-expansion-panel>
}
</mat-accordion>
@@ -1,26 +1,33 @@
/* stylelint-disable selector-class-pattern */
@use '@angular/material' as mat;
.aca-rule-list {
display: flex;
flex-direction: column;
overflow-y: auto;
gap: 8px;
@include mat.expansion-overrides(
(
container-background-color: var(--theme-background-color),
header-text-color: var(--theme-text-color),
container-shape: 12px
)
);
&__item {
display: flex;
flex-direction: column;
border: 1px solid var(--theme-border-color);
border-radius: 12px;
overflow: hidden;
/* stylelint-disable-next-line declaration-no-important */
box-shadow: none !important;
.mat-expansion-panel-body {
padding: 0;
}
&__header {
display: flex;
flex-direction: row;
gap: 4px;
align-items: stretch;
cursor: pointer;
color: var(--theme-text-color);
user-select: none;
font-size: 0.9em;
padding: 0.5em 1em;
padding: 0 16px;
&.mat-expanded {
border-bottom: 1px solid var(--theme-border-color);
border-radius: 0;
}
& > * {
display: flex;
@@ -41,12 +48,6 @@
}
}
&.aca-expanded {
.aca-rule-list__item__header {
border-bottom: 1px solid var(--theme-border-color);
}
}
&__all-linked-rules-are-disabled {
display: flex;
flex-direction: column;
@@ -31,6 +31,7 @@ import { CommonModule } from '@angular/common';
import { TranslatePipe } from '@ngx-translate/core';
import { MatRippleModule } from '@angular/material/core';
import { MatIconModule } from '@angular/material/icon';
import { MatAccordion, MatExpansionPanel, MatExpansionPanelHeader, MatExpansionPanelTitle } from '@angular/material/expansion';
import { MatTooltipModule } from '@angular/material/tooltip';
import { RuleListGroupingUiComponent } from '../rule-list-grouping/rule-list-grouping.ui-component';
import { RouterModule } from '@angular/router';
@@ -47,7 +48,11 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
MatTooltipModule,
RuleListGroupingUiComponent,
RouterModule,
MatButtonModule
MatButtonModule,
MatAccordion,
MatExpansionPanel,
MatExpansionPanelHeader,
MatExpansionPanelTitle
],
selector: 'aca-rule-list',
templateUrl: './rule-list.ui-component.html',
@@ -83,7 +88,6 @@ export class RuleListUiComponent implements OnInit {
ruleSetUnlinkClicked = new EventEmitter<RuleSet>();
mainRuleSet: RuleSet = null;
inheritedRuleSetsExpanded = true;
mainRuleSetExpanded = true;
mainRuleSetGroupingItems: RuleGroupingItem[] = [];
inheritedRuleSetGroupingItems: RuleGroupingItem[] = [];