[ACS-3895] ACA - Folder Rules: inherit rule sets toggle (#2808)

* ACS-3895 - initial layout

* ACS-3895 - finished functionality

* ACS-3895 - unit tests

* ACS-3895 - deleted comments

* ACS-3895 - small fixes

* ACS-3895 - renamed ruleSettings to ruleSettingsMock

* ACS-3895 - rebase
This commit is contained in:
Nikita Maliarchuk 2022-11-24 19:07:21 +01:00 committed by GitHub
parent 654aebe964
commit 60ba8eb6ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 128 additions and 7 deletions

View File

@ -95,7 +95,8 @@
"CREATE_RULE": "Create rule",
"LINK_RULES": "Link rules",
"EDIT_RULE": "Edit",
"SEE_IN_FOLDER": "See in folder"
"SEE_IN_FOLDER": "See in folder",
"INHERIT_RULES": "Inherit rules"
}
},
"EMPTY_RULES_LIST": {

View File

@ -26,6 +26,17 @@
class="aca-manage-rules__actions-bar__title__breadcrumb"></adf-breadcrumb>
</adf-toolbar-title>
<mat-slide-toggle
data-automation-id="manage-rules-inheritance-toggle-button"
[checked]="isInheritanceEnabled"
(change)="onInheritanceToggleChange($event)"
[disabled]="isInheritanceToggleDisabled"
[labelPosition]="'before'">
{{ 'ACA_FOLDER_RULES.MANAGE_RULES.TOOLBAR.ACTIONS.INHERIT_RULES' | translate }}
</mat-slide-toggle>
<mat-divider vertical class="vertical-divider"></mat-divider>
<div class="aca-manage-rules__actions-bar__buttons">
<button
*ngIf="!(mainRuleSet$ | async)"

View File

@ -17,7 +17,18 @@
&__buttons {
display: flex;
align-items: stretch;
gap: 4px;
gap: 12px;
}
.mat-slide-toggle-label {
font-weight: 600;
font-size: 14px;
color: var(--adf-breadcrumb-item-active-color);
}
.vertical-divider {
height: 50%;
margin: 0 12px;
}
}

View File

@ -36,7 +36,7 @@ import { owningFolderIdMock, owningFolderMock } from '../mock/node.mock';
import { MatDialog } from '@angular/material/dialog';
import { ActionsService } from '../services/actions.service';
import { FolderRuleSetsService } from '../services/folder-rule-sets.service';
import { ruleMock } from '../mock/rules.mock';
import { ruleMock, ruleSettingsMock } from '../mock/rules.mock';
import { Store } from '@ngrx/store';
describe('ManageRulesSmartComponent', () => {
@ -229,4 +229,43 @@ describe('ManageRulesSmartComponent', () => {
expect(createButton).toBeFalsy();
});
});
describe('Rule inheritance toggle button', () => {
beforeEach(() => {
folderRuleSetsService.folderInfo$ = of(owningFolderMock);
folderRuleSetsService.inheritedRuleSets$ = of([]);
folderRuleSetsService.isLoading$ = of(false);
actionsService.loading$ = of(false);
});
it('should show inherit rules toggle button, and disable it when isInheritanceToggleDisabled = true', () => {
fixture.detectChanges();
const createButton = debugElement.query(By.css(`[data-automation-id="manage-rules-inheritance-toggle-button"]`));
expect(createButton).toBeTruthy();
component.isInheritanceToggleDisabled = true;
fixture.detectChanges();
expect(createButton.nativeNode.classList).toContain('mat-disabled');
});
it('should call onInheritanceToggleChange() on change', () => {
const onInheritanceToggleChangeSpy = spyOn(component, 'onInheritanceToggleChange').and.callThrough();
const updateRuleSettingsSpy = spyOn(folderRulesService, 'updateRuleSettings').and.returnValue(Promise.resolve(ruleSettingsMock));
const loadRuleSetsSpy = spyOn(folderRuleSetsService, 'loadRuleSets').and.callThrough();
fixture.detectChanges();
const inheritanceToggleBtn = fixture.debugElement.query(By.css(`[data-automation-id="manage-rules-inheritance-toggle-button"]`));
inheritanceToggleBtn.nativeElement.dispatchEvent(new Event('change'));
fixture.detectChanges();
expect(onInheritanceToggleChangeSpy).toHaveBeenCalled();
expect(updateRuleSettingsSpy).toHaveBeenCalledTimes(1);
expect(loadRuleSetsSpy).toHaveBeenCalledTimes(1);
});
});
});

View File

@ -40,6 +40,7 @@ import { ActionsService } from '../services/actions.service';
import { FolderRuleSetsService } from '../services/folder-rule-sets.service';
import { RuleSet } from '../model/rule-set.model';
import { RuleSetPickerSmartComponent } from '../rule-set-picker/rule-set-picker.smart-component';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
@Component({
selector: 'aca-manage-rules',
@ -50,6 +51,8 @@ import { RuleSetPickerSmartComponent } from '../rule-set-picker/rule-set-picker.
})
export class ManageRulesSmartComponent implements OnInit, OnDestroy {
nodeId = '';
isInheritanceEnabled = true;
isInheritanceToggleDisabled = false;
mainRuleSet$: Observable<RuleSet>;
inheritedRuleSets$: Observable<RuleSet[]>;
@ -93,6 +96,10 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
this.route.params.subscribe((params) => {
this.nodeId = params.nodeId;
if (this.nodeId) {
this.folderRulesService.getRuleSettings(this.nodeId).then((ruleSettings) => {
this.isInheritanceEnabled = ruleSettings.value;
});
this.folderRuleSetsService.loadRuleSets(this.nodeId);
}
});
@ -153,6 +160,14 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
await this.folderRulesService.updateRule(this.nodeId, rule.id, { ...rule, isEnabled });
}
async onInheritanceToggleChange(event: MatSlideToggleChange) {
this.isInheritanceToggleDisabled = true;
const ruleSettings = await this.folderRulesService.updateRuleSettings(this.nodeId, '-isInheritanceEnabled-', { value: event.checked });
this.isInheritanceEnabled = ruleSettings.value;
this.folderRuleSetsService.loadRuleSets(this.nodeId);
this.isInheritanceToggleDisabled = false;
}
onRuleDeleteButtonClicked(rule: Rule) {
this.matDialogService
.open(ConfirmDialogComponent, {

View File

@ -23,7 +23,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Rule } from '../model/rule.model';
import { Rule, RuleSettings } from '../model/rule.model';
import { RuleGroupingItem } from '../model/rule-grouping-item.model';
export const getRulesResponseMock = {
@ -170,3 +170,8 @@ export const ruleListGroupingItemsMock: RuleGroupingItem[] = [
rule: ruleMock('rule2')
}
];
export const ruleSettingsMock: RuleSettings = {
value: false,
key: '-parameter-'
};

View File

@ -58,3 +58,8 @@ export interface RuleForForm {
actions: RuleAction[];
options: RuleOptions;
}
export interface RuleSettings {
value: boolean;
key?: string;
}

View File

@ -68,7 +68,7 @@ export class FolderRuleSetsService {
inheritedRuleSets$: Observable<RuleSet[]> = this.inheritedRuleSetsSource.asObservable();
hasMoreRuleSets$: Observable<boolean> = this.hasMoreRuleSetsSource.asObservable();
folderInfo$: Observable<NodeInfo> = this.folderInfoSource.asObservable();
isLoading$ = this.isLoadingSource.asObservable();
isLoading$: Observable<boolean> = this.isLoadingSource.asObservable();
selectedRuleSet$ = this.folderRulesService.selectedRule$.pipe(
map((rule: Rule) => {

View File

@ -27,7 +27,15 @@ import { TestBed } from '@angular/core/testing';
import { CoreTestingModule } from '@alfresco/adf-core';
import { of } from 'rxjs';
import { FolderRulesService } from './folder-rules.service';
import { getMoreRulesResponseMock, getRulesResponseMock, manyRulesMock, moreRulesMock, ruleMock, rulesMock } from '../mock/rules.mock';
import {
getMoreRulesResponseMock,
getRulesResponseMock,
manyRulesMock,
moreRulesMock,
ruleMock,
ruleSettingsMock,
rulesMock
} from '../mock/rules.mock';
import { ruleSetMock } from '../mock/rule-sets.mock';
import { expect } from '@angular/flex-layout/_private-utils/testing';
import { owningFolderIdMock } from '../mock/node.mock';
@ -44,6 +52,8 @@ describe('FolderRulesService', () => {
const { id, ...mockedRuleWithoutId } = mockedRule;
const mockedRuleEntry = { entry: mockedRule };
const ruleId = mockedRule.id;
const mockedRuleSettingsEntry = { entry: ruleSettingsMock };
const key = ruleSettingsMock.key;
beforeEach(() => {
TestBed.configureTestingModule({
@ -138,4 +148,18 @@ describe('FolderRulesService', () => {
const result = await folderRulesService.updateRule(nodeId, ruleId, mockedRule, ruleSetId);
expect(result).toEqual(mockedRule);
});
it('should send correct GET request and return rule settings', async () => {
callApiSpy.withArgs(`/nodes/${nodeId}/rule-settings/${key}`, 'GET').and.returnValue(Promise.resolve(mockedRuleSettingsEntry));
const result = await folderRulesService.getRuleSettings(nodeId, key);
expect(result).toEqual(ruleSettingsMock);
});
it('should send correct PUT request to update rule settings and return them', async () => {
callApiSpy.withArgs(`/nodes/${nodeId}/rule-settings/${key}`, 'PUT', ruleSettingsMock).and.returnValue(Promise.resolve(mockedRuleSettingsEntry));
const result = await folderRulesService.updateRuleSettings(nodeId, key, ruleSettingsMock);
expect(result).toEqual(ruleSettingsMock);
});
});

View File

@ -27,7 +27,7 @@ import { Injectable } from '@angular/core';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { BehaviorSubject, from, Observable } from 'rxjs';
import { finalize, map } from 'rxjs/operators';
import { Rule, RuleForForm, RuleOptions } from '../model/rule.model';
import { Rule, RuleForForm, RuleOptions, RuleSettings } from '../model/rule.model';
import { RuleCompositeCondition } from '../model/rule-composite-condition.model';
import { RuleSimpleCondition } from '../model/rule-simple-condition.model';
import { RuleSet } from '../model/rule-set.model';
@ -152,6 +152,16 @@ export class FolderRulesService {
);
}
async getRuleSettings(nodeId: string, key: string = '-isInheritanceEnabled-'): Promise<RuleSettings> {
const response = await this.callApi(`/nodes/${nodeId}/rule-settings/${key}`, 'GET');
return response.entry;
}
async updateRuleSettings(nodeId: string, key: string, body: RuleSettings): Promise<RuleSettings> {
const response = await this.callApi(`/nodes/${nodeId}/rule-settings/${key}`, 'PUT', { ...body });
return response.entry;
}
private formatRules(res): Rule[] {
return res.list.entries.map((entry) => this.formatRule(entry.entry));
}