mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-19 17:14:45 +00:00
[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:
parent
acb848d39d
commit
eeff4b9829
@ -140,6 +140,22 @@ const actionParamLinkToCategoryTransformedMock = {
|
|||||||
displayLabel: 'Category value'
|
displayLabel: 'Category value'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const actionParamSecurityGroup: ActionParameterDefinitionTransformed = {
|
||||||
|
name: 'securityGroupId',
|
||||||
|
type: 'd:text',
|
||||||
|
multiValued: false,
|
||||||
|
mandatory: true,
|
||||||
|
displayLabel: 'Security Group Id'
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionParamSecurityMark: ActionParameterDefinitionTransformed = {
|
||||||
|
name: 'securityMarkId',
|
||||||
|
type: 'd:text',
|
||||||
|
multiValued: false,
|
||||||
|
mandatory: true,
|
||||||
|
displayLabel: 'Security Mark Id'
|
||||||
|
};
|
||||||
|
|
||||||
const action1TransformedMock: ActionDefinitionTransformed = {
|
const action1TransformedMock: ActionDefinitionTransformed = {
|
||||||
id: 'mock-action-1-definition',
|
id: 'mock-action-1-definition',
|
||||||
name: 'mock-action-1-definition',
|
name: 'mock-action-1-definition',
|
||||||
@ -176,6 +192,16 @@ export const actionLinkToCategoryTransformedMock: ActionDefinitionTransformed =
|
|||||||
parameterDefinitions: [actionParamLinkToCategoryTransformedMock]
|
parameterDefinitions: [actionParamLinkToCategoryTransformedMock]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const securityActionTransformedMock: ActionDefinitionTransformed = {
|
||||||
|
id: 'mock-action-4-definition',
|
||||||
|
name: 'mock-action-4-definition',
|
||||||
|
description: '',
|
||||||
|
title: 'mock-action-4-definition',
|
||||||
|
applicableTypes: [],
|
||||||
|
trackStatus: false,
|
||||||
|
parameterDefinitions: [actionParamSecurityGroup, actionParamSecurityMark]
|
||||||
|
};
|
||||||
|
|
||||||
export const actionsTransformedListMock: ActionDefinitionTransformed[] = [action1TransformedMock, action2TransformedMock];
|
export const actionsTransformedListMock: ActionDefinitionTransformed[] = [action1TransformedMock, action2TransformedMock];
|
||||||
|
|
||||||
export const validActionMock: RuleAction = {
|
export const validActionMock: RuleAction = {
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Alfresco Example Content Application
|
||||||
|
*
|
||||||
|
* This file is part of the Alfresco Example Content Application.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { SecurityControlsMarkResponse } from '@alfresco/adf-content-services/lib/security/services/models/security-controls-mark-response.interface';
|
||||||
|
import { UpdateNotification } from '@alfresco/adf-core';
|
||||||
|
|
||||||
|
export const securityMarksResponseMock: SecurityControlsMarkResponse = {
|
||||||
|
pagination: {
|
||||||
|
count: 2,
|
||||||
|
hasMoreItems: false,
|
||||||
|
totalItems: 2,
|
||||||
|
skipCount: 0,
|
||||||
|
maxItems: 100
|
||||||
|
},
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
id: 'mark-1-id',
|
||||||
|
name: 'mark-1-name',
|
||||||
|
groupId: 'group-1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mark-2-id',
|
||||||
|
name: 'mark-2-name',
|
||||||
|
groupId: 'group-1'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateNotificationMock = (value: string): UpdateNotification => {
|
||||||
|
return {
|
||||||
|
changed: { securityGroupId: value },
|
||||||
|
target: {
|
||||||
|
label: 'Security Group Id *',
|
||||||
|
value: '',
|
||||||
|
key: 'securityGroupId',
|
||||||
|
default: undefined,
|
||||||
|
editable: true,
|
||||||
|
clickable: true,
|
||||||
|
isEmpty: () => true,
|
||||||
|
isValid: () => true,
|
||||||
|
getValidationErrors: () => []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
@ -25,9 +25,10 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { CardViewBoolItemModel, CardViewComponent, CardViewSelectItemModel, CardViewTextItemModel, CoreTestingModule } from '@alfresco/adf-core';
|
import { CardViewBoolItemModel, CardViewComponent, CardViewSelectItemModel, CardViewTextItemModel, CoreTestingModule } from '@alfresco/adf-core';
|
||||||
import { RuleActionUiComponent } from './rule-action.ui-component';
|
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 { By } from '@angular/platform-browser';
|
||||||
import { dummyCategoriesConstraints, dummyConstraints, dummyTagsConstraints } from '../../mock/action-parameter-constraints.mock';
|
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 { CategoryService, TagService } from '@alfresco/adf-content-services';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { HarnessLoader } from '@angular/cdk/testing';
|
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([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -35,8 +35,8 @@ import {
|
|||||||
CardViewUpdateService,
|
CardViewUpdateService,
|
||||||
UpdateNotification
|
UpdateNotification
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { ActionParameterDefinition, Category, Node } from '@alfresco/js-api';
|
import { ActionParameterDefinition, Category, Node, SecurityMark } from '@alfresco/js-api';
|
||||||
import { of, Subject } from 'rxjs';
|
import { from, of, Subject } from 'rxjs';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
|
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
|
||||||
import {
|
import {
|
||||||
@ -46,7 +46,8 @@ import {
|
|||||||
NodeAction,
|
NodeAction,
|
||||||
TagService,
|
TagService,
|
||||||
CategorySelectorDialogComponent,
|
CategorySelectorDialogComponent,
|
||||||
CategorySelectorDialogOptions
|
CategorySelectorDialogOptions,
|
||||||
|
SecurityControlsService
|
||||||
} from '@alfresco/adf-content-services';
|
} from '@alfresco/adf-content-services';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
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 tagsRelatedPropertiesAndAspects = ['cm:tagscope', 'cm:tagScopeCache', 'cm:taggable'];
|
||||||
private readonly categoriesRelatedPropertiesAndAspects = ['cm:categories', 'cm:generalclassifiable'];
|
private readonly categoriesRelatedPropertiesAndAspects = ['cm:categories', 'cm:generalclassifiable'];
|
||||||
|
private readonly paramsToFormatDisplayedValue = ['securityMarkId', 'securityGroupId'];
|
||||||
|
|
||||||
isFullWidth = false;
|
isFullWidth = false;
|
||||||
|
|
||||||
@ -123,7 +125,8 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
|
|||||||
private dialog: MatDialog,
|
private dialog: MatDialog,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private tagService: TagService,
|
private tagService: TagService,
|
||||||
private categoryService: CategoryService
|
private categoryService: CategoryService,
|
||||||
|
private securityControlsService: SecurityControlsService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
writeValue(action: RuleAction) {
|
writeValue(action: RuleAction) {
|
||||||
@ -135,6 +138,9 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
|
|||||||
...action.params
|
...action.params
|
||||||
};
|
};
|
||||||
this.setCardViewProperties();
|
this.setCardViewProperties();
|
||||||
|
if (this.parameters?.securityGroupId) {
|
||||||
|
this.loadSecurityMarkOptions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnChange(fn: (action: RuleAction) => void) {
|
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) => {
|
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 = this.clearEmptyParameters({
|
||||||
...this.parameters,
|
...this.parameters,
|
||||||
...updateNotification.changed
|
...updateNotification.changed
|
||||||
@ -170,6 +181,11 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
|
|||||||
params: this.parameters
|
params: this.parameters
|
||||||
});
|
});
|
||||||
this.onTouch();
|
this.onTouch();
|
||||||
|
|
||||||
|
if (isSecurityGroupUpdated) {
|
||||||
|
this.setCardViewProperties();
|
||||||
|
this.loadSecurityMarkOptions();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,11 +202,14 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
|
|||||||
this.onDestroy$.complete();
|
this.onDestroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
setCardViewProperties() {
|
setCardViewProperties(securityMarkOptions?: CardViewSelectItemOption<string>[]) {
|
||||||
const disabledTags = !this.tagService.areTagsEnabled();
|
const disabledTags = !this.tagService.areTagsEnabled();
|
||||||
const disabledCategories = !this.categoryService.areCategoriesEnabled();
|
const disabledCategories = !this.categoryService.areCategoriesEnabled();
|
||||||
this.cardViewItems = (this.selectedActionDefinition?.parameterDefinitions ?? []).map((paramDef) => {
|
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 = {
|
const cardViewPropertiesModel = {
|
||||||
label: paramDef.displayLabel + (paramDef.mandatory ? ' *' : ''),
|
label: paramDef.displayLabel + (paramDef.mandatory ? ' *' : ''),
|
||||||
key: paramDef.name,
|
key: paramDef.name,
|
||||||
@ -253,7 +272,10 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
|
|||||||
}
|
}
|
||||||
return new CardViewTextItemModel({
|
return new CardViewTextItemModel({
|
||||||
...cardViewPropertiesModel,
|
...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]);
|
Object.keys(params).forEach((key) => (params[key] === null || params[key] === undefined || params[key] === '') && delete params[key]);
|
||||||
return params;
|
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
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user