[ACS-6595] Add security marks for Folder Rules (#3835)

* [ACS-6595] Create dropdown box and load values for security marks action parameter

* [ACS-6595] add interface to mocked params

* [ACS-6595] change displayed value for security marks and groups to include name
This commit is contained in:
Grzegorz Jaśkowski
2024-05-10 08:16:38 +02:00
committed by GitHub
parent acb848d39d
commit eeff4b9829
4 changed files with 168 additions and 8 deletions

View File

@@ -25,9 +25,10 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CardViewBoolItemModel, CardViewComponent, CardViewSelectItemModel, CardViewTextItemModel, CoreTestingModule } from '@alfresco/adf-core';
import { RuleActionUiComponent } from './rule-action.ui-component';
import { actionLinkToCategoryTransformedMock, actionsTransformedListMock } from '../../mock/actions.mock';
import { actionLinkToCategoryTransformedMock, actionsTransformedListMock, securityActionTransformedMock } from '../../mock/actions.mock';
import { By } from '@angular/platform-browser';
import { dummyCategoriesConstraints, dummyConstraints, dummyTagsConstraints } from '../../mock/action-parameter-constraints.mock';
import { securityMarksResponseMock, updateNotificationMock } from '../../mock/security-marks.mock';
import { CategoryService, TagService } from '@alfresco/adf-content-services';
import { MatDialog } from '@angular/material/dialog';
import { HarnessLoader } from '@angular/cdk/testing';
@@ -220,4 +221,35 @@ describe('RuleActionUiComponent', () => {
});
});
});
describe('Security mark actions', () => {
beforeEach(async () => {
component.actionDefinitions = [securityActionTransformedMock];
await changeMatSelectValue('mock-action-4-definition');
});
it('should create dropdown selector for security mark action parameter', () => {
expect(getPropertiesCardView().properties[1]).toBeInstanceOf(CardViewSelectItemModel);
});
it('should load security marks on security group select and remove them on unselect', async () => {
spyOn(component['securityControlsService'], 'getSecurityMark').and.returnValue(Promise.resolve(securityMarksResponseMock));
component['cardViewUpdateService'].itemUpdated$.next(updateNotificationMock('group-1'));
await fixture.whenStable();
fixture.detectChanges();
(getPropertiesCardView().properties[1] as CardViewSelectItemModel<string>).options$.subscribe((options) => {
expect(options).toEqual([
{ key: 'mark-1-id', label: 'mark-1-name [mark-1-id]' },
{ key: 'mark-2-id', label: 'mark-2-name [mark-2-id]' }
]);
});
component['cardViewUpdateService'].itemUpdated$.next(updateNotificationMock(''));
await fixture.whenStable();
fixture.detectChanges();
(getPropertiesCardView().properties[1] as CardViewSelectItemModel<string>).options$.subscribe((options) => {
expect(options).toEqual([]);
});
});
});
});

View File

@@ -35,8 +35,8 @@ import {
CardViewUpdateService,
UpdateNotification
} from '@alfresco/adf-core';
import { ActionParameterDefinition, Category, Node } from '@alfresco/js-api';
import { of, Subject } from 'rxjs';
import { ActionParameterDefinition, Category, Node, SecurityMark } from '@alfresco/js-api';
import { from, of, Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
import {
@@ -46,7 +46,8 @@ import {
NodeAction,
TagService,
CategorySelectorDialogComponent,
CategorySelectorDialogOptions
CategorySelectorDialogOptions,
SecurityControlsService
} from '@alfresco/adf-content-services';
import { MatDialog } from '@angular/material/dialog';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
@@ -96,6 +97,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
private readonly tagsRelatedPropertiesAndAspects = ['cm:tagscope', 'cm:tagScopeCache', 'cm:taggable'];
private readonly categoriesRelatedPropertiesAndAspects = ['cm:categories', 'cm:generalclassifiable'];
private readonly paramsToFormatDisplayedValue = ['securityMarkId', 'securityGroupId'];
isFullWidth = false;
@@ -123,7 +125,8 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
private dialog: MatDialog,
private translate: TranslateService,
private tagService: TagService,
private categoryService: CategoryService
private categoryService: CategoryService,
private securityControlsService: SecurityControlsService
) {}
writeValue(action: RuleAction) {
@@ -135,6 +138,9 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
...action.params
};
this.setCardViewProperties();
if (this.parameters?.securityGroupId) {
this.loadSecurityMarkOptions();
}
}
registerOnChange(fn: (action: RuleAction) => void) {
@@ -161,6 +167,11 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
});
this.cardViewUpdateService.itemUpdated$.pipe(takeUntil(this.onDestroy$)).subscribe((updateNotification: UpdateNotification) => {
const isSecurityGroupUpdated = updateNotification.target.key === 'securityGroupId';
if (isSecurityGroupUpdated) {
this.parameters.securityMarkId = null;
}
this.parameters = this.clearEmptyParameters({
...this.parameters,
...updateNotification.changed
@@ -170,6 +181,11 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
params: this.parameters
});
this.onTouch();
if (isSecurityGroupUpdated) {
this.setCardViewProperties();
this.loadSecurityMarkOptions();
}
});
}
@@ -186,11 +202,14 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
this.onDestroy$.complete();
}
setCardViewProperties() {
setCardViewProperties(securityMarkOptions?: CardViewSelectItemOption<string>[]) {
const disabledTags = !this.tagService.areTagsEnabled();
const disabledCategories = !this.categoryService.areCategoriesEnabled();
this.cardViewItems = (this.selectedActionDefinition?.parameterDefinitions ?? []).map((paramDef) => {
const constraintsForDropdownBox = this._parameterConstraints.find((obj) => obj.name === paramDef.name);
const constraintsForDropdownBox =
paramDef.name === 'securityMarkId'
? { name: paramDef.name, constraints: securityMarkOptions || [] }
: this._parameterConstraints.find((obj) => obj.name === paramDef.name);
const cardViewPropertiesModel = {
label: paramDef.displayLabel + (paramDef.mandatory ? ' *' : ''),
key: paramDef.name,
@@ -253,7 +272,10 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
}
return new CardViewTextItemModel({
...cardViewPropertiesModel,
value: this.parameters[paramDef.name] ?? ''
value:
constraintsForDropdownBox && this.readOnly && this.paramsToFormatDisplayedValue.includes(paramDef.name)
? constraintsForDropdownBox.constraints.find((constraint) => constraint.key === this.parameters[paramDef.name])?.label ?? ''
: this.parameters[paramDef.name] ?? ''
});
}
});
@@ -368,4 +390,19 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
Object.keys(params).forEach((key) => (params[key] === null || params[key] === undefined || params[key] === '') && delete params[key]);
return params;
}
loadSecurityMarkOptions(): void {
if (this.parameters?.securityGroupId) {
from(this.securityControlsService.getSecurityMark(this.parameters.securityGroupId as string))
.pipe(map((securityMarks) => securityMarks.entries.map((entry) => this.formatSecurityMarkConstraint(entry))))
.subscribe((res) => this.setCardViewProperties(this.parseConstraintsToSelectOptions(res) as CardViewSelectItemOption<string>[]));
}
}
private formatSecurityMarkConstraint(securityMark: SecurityMark): ConstraintValue {
return {
value: securityMark.id,
label: securityMark.name
};
}
}