mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACS-3860] Folder rules - Node picker for action parameters of type "d:noderef" (#2800)
* [ACS-3860] - added callback with node selector dialog * ACS-3860 - implemented node picker for actions * ACS-3860 - unit tests * ACS-3860 - linting * ACS-3860 - i18n * ACS-3860 - small fix * ACS-3860 - changed to private method, added typization * ACS-3860 - removed useless getter and setter * ACS-3860 - added 'noderef' to cspell.json
This commit is contained in:
parent
03ed8e071a
commit
81033450d8
@ -65,7 +65,8 @@
|
|||||||
"dateitem",
|
"dateitem",
|
||||||
"versionable",
|
"versionable",
|
||||||
"erroredSpy",
|
"erroredSpy",
|
||||||
"errored"
|
"errored",
|
||||||
|
"noderef"
|
||||||
],
|
],
|
||||||
"dictionaries": ["html", "en-gb", "en_US"]
|
"dictionaries": ["html", "en-gb", "en_US"]
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
"NAME": "Enter rule name",
|
"NAME": "Enter rule name",
|
||||||
"DESCRIPTION": "Enter rule description",
|
"DESCRIPTION": "Enter rule description",
|
||||||
"NO_DESCRIPTION": "No description",
|
"NO_DESCRIPTION": "No description",
|
||||||
"VALUE": "Value"
|
"VALUE": "Value",
|
||||||
|
"CHOOSE_FOLDER": "Choose destination folder"
|
||||||
},
|
},
|
||||||
"ERROR": {
|
"ERROR": {
|
||||||
"REQUIRED": "This field is required",
|
"REQUIRED": "This field is required",
|
||||||
|
@ -86,7 +86,8 @@
|
|||||||
[actionDefinitions]="actionDefinitions$ | async"
|
[actionDefinitions]="actionDefinitions$ | async"
|
||||||
[readOnly]="true"
|
[readOnly]="true"
|
||||||
[preview]="true"
|
[preview]="true"
|
||||||
[value]="selectedRule">
|
[value]="selectedRule"
|
||||||
|
[nodeId]="nodeId">
|
||||||
</aca-rule-details>
|
</aca-rule-details>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,7 +48,7 @@ import { RuleSet } from '../model/rule-set.model';
|
|||||||
host: { class: 'aca-manage-rules' }
|
host: { class: 'aca-manage-rules' }
|
||||||
})
|
})
|
||||||
export class ManageRulesSmartComponent implements OnInit, OnDestroy {
|
export class ManageRulesSmartComponent implements OnInit, OnDestroy {
|
||||||
nodeId: string = null;
|
nodeId = '';
|
||||||
|
|
||||||
mainRuleSet$: Observable<RuleSet>;
|
mainRuleSet$: Observable<RuleSet>;
|
||||||
inheritedRuleSets$: Observable<RuleSet[]>;
|
inheritedRuleSets$: Observable<RuleSet[]>;
|
||||||
@ -115,7 +115,8 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
|
|||||||
width: '90%',
|
width: '90%',
|
||||||
panelClass: 'aca-edit-rule-dialog-container',
|
panelClass: 'aca-edit-rule-dialog-container',
|
||||||
data: {
|
data: {
|
||||||
model
|
model,
|
||||||
|
nodeId: this.nodeId
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -57,6 +57,18 @@ export const actionDefListMock = {
|
|||||||
multiValued: false,
|
multiValued: false,
|
||||||
mandatory: false,
|
mandatory: false,
|
||||||
parameterConstraintName: 'ac-aspects'
|
parameterConstraintName: 'ac-aspects'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mock-action-parameter-noderef',
|
||||||
|
type: 'd:noderef',
|
||||||
|
multiValued: false,
|
||||||
|
mandatory: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aspect-name',
|
||||||
|
type: 'd:noderef',
|
||||||
|
multiValued: false,
|
||||||
|
mandatory: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'mock-action-1-definition',
|
name: 'mock-action-1-definition',
|
||||||
@ -102,6 +114,24 @@ const actionParam3TransformedMock: ActionParameterDefinitionTransformed = {
|
|||||||
parameterConstraintName: 'ac-aspects'
|
parameterConstraintName: 'ac-aspects'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const actionParam4TransformedMock: ActionParameterDefinitionTransformed = {
|
||||||
|
name: 'mock-action-parameter-noderef',
|
||||||
|
type: 'd:noderef',
|
||||||
|
multiValued: false,
|
||||||
|
mandatory: false,
|
||||||
|
displayLabel: 'mock-action-parameter-noderef',
|
||||||
|
parameterConstraintName: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionParam5TransformedMock: ActionParameterDefinitionTransformed = {
|
||||||
|
name: 'aspect-name',
|
||||||
|
type: 'd:noderef',
|
||||||
|
multiValued: false,
|
||||||
|
mandatory: false,
|
||||||
|
displayLabel: 'aspect-name',
|
||||||
|
parameterConstraintName: ''
|
||||||
|
};
|
||||||
|
|
||||||
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',
|
||||||
@ -109,7 +139,13 @@ const action1TransformedMock: ActionDefinitionTransformed = {
|
|||||||
title: 'Action 1 title',
|
title: 'Action 1 title',
|
||||||
applicableTypes: [],
|
applicableTypes: [],
|
||||||
trackStatus: false,
|
trackStatus: false,
|
||||||
parameterDefinitions: [actionParam1TransformedMock, actionParam2TransformedMock, actionParam3TransformedMock]
|
parameterDefinitions: [
|
||||||
|
actionParam1TransformedMock,
|
||||||
|
actionParam2TransformedMock,
|
||||||
|
actionParam3TransformedMock,
|
||||||
|
actionParam4TransformedMock,
|
||||||
|
actionParam5TransformedMock
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const action2TransformedMock: ActionDefinitionTransformed = {
|
const action2TransformedMock: ActionDefinitionTransformed = {
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
[actionDefinitions]="actionDefinitions"
|
[actionDefinitions]="actionDefinitions"
|
||||||
[parameterConstraints]="parameterConstraints"
|
[parameterConstraints]="parameterConstraints"
|
||||||
[readOnly]="readOnly"
|
[readOnly]="readOnly"
|
||||||
[formControl]="control">
|
[formControl]="control"
|
||||||
|
[nodeId]="nodeId">
|
||||||
</aca-rule-action>
|
</aca-rule-action>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -51,6 +51,8 @@ export class RuleActionListUiComponent implements ControlValueAccessor, OnDestro
|
|||||||
readOnly = false;
|
readOnly = false;
|
||||||
@Input()
|
@Input()
|
||||||
parameterConstraints: ActionParameterConstraint[] = [];
|
parameterConstraints: ActionParameterConstraint[] = [];
|
||||||
|
@Input()
|
||||||
|
nodeId = '';
|
||||||
|
|
||||||
formArray = new FormArray([]);
|
formArray = new FormArray([]);
|
||||||
private formArraySubscription: Subscription;
|
private formArraySubscription: Subscription;
|
||||||
|
@ -79,10 +79,13 @@ describe('RuleActionUiComponent', () => {
|
|||||||
expect(cardView.properties.length).toBe(0);
|
expect(cardView.properties.length).toBe(0);
|
||||||
|
|
||||||
changeMatSelectValue('rule-action-select', 'mock-action-1-definition');
|
changeMatSelectValue('rule-action-select', 'mock-action-1-definition');
|
||||||
expect(cardView.properties.length).toBe(3);
|
|
||||||
|
expect(cardView.properties.length).toBe(5);
|
||||||
expect(cardView.properties[0]).toBeInstanceOf(CardViewTextItemModel);
|
expect(cardView.properties[0]).toBeInstanceOf(CardViewTextItemModel);
|
||||||
expect(cardView.properties[1]).toBeInstanceOf(CardViewBoolItemModel);
|
expect(cardView.properties[1]).toBeInstanceOf(CardViewBoolItemModel);
|
||||||
expect(cardView.properties[2]).toBeInstanceOf(CardViewSelectItemModel);
|
expect(cardView.properties[2]).toBeInstanceOf(CardViewSelectItemModel);
|
||||||
|
expect(cardView.properties[3]).toBeInstanceOf(CardViewTextItemModel);
|
||||||
|
expect(cardView.properties[4]).toBeInstanceOf(CardViewSelectItemModel);
|
||||||
|
|
||||||
changeMatSelectValue('rule-action-select', 'mock-action-2-definition');
|
changeMatSelectValue('rule-action-select', 'mock-action-2-definition');
|
||||||
expect(cardView.properties.length).toBe(0);
|
expect(cardView.properties.length).toBe(0);
|
||||||
|
@ -35,10 +35,13 @@ import {
|
|||||||
CardViewUpdateService,
|
CardViewUpdateService,
|
||||||
UpdateNotification
|
UpdateNotification
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
import { ActionParameterDefinition } from '@alfresco/js-api';
|
import { ActionParameterDefinition, Node } from '@alfresco/js-api';
|
||||||
import { of, Subject } from 'rxjs';
|
import { of, Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
|
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
|
||||||
|
import { ContentNodeSelectorComponent, ContentNodeSelectorComponentData, NodeAction } from '@alfresco/adf-content-services';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'aca-rule-action',
|
selector: 'aca-rule-action',
|
||||||
@ -56,6 +59,9 @@ import { ActionParameterConstraint, ConstraintValue } from '../../model/action-p
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDestroy {
|
export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDestroy {
|
||||||
|
@Input()
|
||||||
|
nodeId = '';
|
||||||
|
|
||||||
private _actionDefinitions: ActionDefinitionTransformed[];
|
private _actionDefinitions: ActionDefinitionTransformed[];
|
||||||
@Input()
|
@Input()
|
||||||
get actionDefinitions(): ActionDefinitionTransformed[] {
|
get actionDefinitions(): ActionDefinitionTransformed[] {
|
||||||
@ -108,7 +114,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
onChange: (action: RuleAction) => void = () => undefined;
|
onChange: (action: RuleAction) => void = () => undefined;
|
||||||
onTouch: () => void = () => undefined;
|
onTouch: () => void = () => undefined;
|
||||||
|
|
||||||
constructor(private cardViewUpdateService: CardViewUpdateService) {}
|
constructor(private cardViewUpdateService: CardViewUpdateService, private dialog: MatDialog, private translate: TranslateService) {}
|
||||||
|
|
||||||
writeValue(action: RuleAction) {
|
writeValue(action: RuleAction) {
|
||||||
this.form.setValue({
|
this.form.setValue({
|
||||||
@ -161,6 +167,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
setCardViewProperties() {
|
setCardViewProperties() {
|
||||||
this.cardViewItems = (this.selectedActionDefinition?.parameterDefinitions ?? []).map((paramDef) => {
|
this.cardViewItems = (this.selectedActionDefinition?.parameterDefinitions ?? []).map((paramDef) => {
|
||||||
this.isFullWidth = false;
|
this.isFullWidth = false;
|
||||||
|
const constraintsForDropdownBox = 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,
|
||||||
@ -182,8 +189,19 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
...cardViewPropertiesModel,
|
...cardViewPropertiesModel,
|
||||||
value: this.parameters[paramDef.name] ?? false
|
value: this.parameters[paramDef.name] ?? false
|
||||||
});
|
});
|
||||||
|
case 'd:noderef':
|
||||||
|
if (!constraintsForDropdownBox && !this.readOnly) {
|
||||||
|
return new CardViewTextItemModel({
|
||||||
|
...cardViewPropertiesModel,
|
||||||
|
icon: 'folder',
|
||||||
|
default: this.translate.instant('ACA_FOLDER_RULES.RULE_DETAILS.PLACEHOLDER.CHOOSE_FOLDER'),
|
||||||
|
clickable: true,
|
||||||
|
clickCallBack: this.openSelectorDialog.bind(this),
|
||||||
|
value: this.parameters[paramDef.name]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// falls through
|
||||||
default:
|
default:
|
||||||
const constraintsForDropdownBox = this._parameterConstraints.find((obj) => obj.name === paramDef.name);
|
|
||||||
if (constraintsForDropdownBox && !this.readOnly) {
|
if (constraintsForDropdownBox && !this.readOnly) {
|
||||||
this.isFullWidth = true;
|
this.isFullWidth = true;
|
||||||
return new CardViewSelectItemModel({
|
return new CardViewSelectItemModel({
|
||||||
@ -200,6 +218,45 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private openSelectorDialog() {
|
||||||
|
const data: ContentNodeSelectorComponentData = {
|
||||||
|
title: this.translate.instant('ACA_FOLDER_RULES.RULE_DETAILS.PLACEHOLDER.CHOOSE_FOLDER'),
|
||||||
|
actionName: NodeAction.CHOOSE,
|
||||||
|
currentFolderId: this.nodeId,
|
||||||
|
select: new Subject<Node[]>()
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dialog.open(ContentNodeSelectorComponent, {
|
||||||
|
data,
|
||||||
|
panelClass: 'adf-content-node-selector-dialog',
|
||||||
|
width: '630px'
|
||||||
|
});
|
||||||
|
|
||||||
|
data.select.subscribe(
|
||||||
|
(selections: Node[]) => {
|
||||||
|
if (selections[0].id) {
|
||||||
|
this.writeValue({
|
||||||
|
actionDefinitionId: this.selectedActionDefinitionId,
|
||||||
|
params: {
|
||||||
|
'destination-folder': selections[0].id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.onChange({
|
||||||
|
actionDefinitionId: this.selectedActionDefinitionId,
|
||||||
|
params: this.parameters
|
||||||
|
});
|
||||||
|
this.onTouch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error(error);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.dialog.closeAll();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
setDefaultParameters() {
|
setDefaultParameters() {
|
||||||
this.parameters = {};
|
this.parameters = {};
|
||||||
(this.selectedActionDefinition?.parameterDefinitions ?? []).forEach((paramDef: ActionParameterDefinition) => {
|
(this.selectedActionDefinition?.parameterDefinitions ?? []).forEach((paramDef: ActionParameterDefinition) => {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
[actionDefinitions]="actionDefinitions$ | async"
|
[actionDefinitions]="actionDefinitions$ | async"
|
||||||
[parameterConstraints]="parameterConstraints$ | async"
|
[parameterConstraints]="parameterConstraints$ | async"
|
||||||
[value]="model"
|
[value]="model"
|
||||||
|
[nodeId]="nodeId"
|
||||||
(formValueChanged)="formValue = $event"
|
(formValueChanged)="formValue = $event"
|
||||||
(formValidationChanged)="onFormValidChange($event)">
|
(formValidationChanged)="onFormValidChange($event)">
|
||||||
</aca-rule-details>
|
</aca-rule-details>
|
||||||
|
@ -30,6 +30,7 @@ import { ActionsService } from '../services/actions.service';
|
|||||||
|
|
||||||
export interface EditRuleDialogOptions {
|
export interface EditRuleDialogOptions {
|
||||||
model?: Partial<Rule>;
|
model?: Partial<Rule>;
|
||||||
|
nodeId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -42,6 +43,7 @@ export interface EditRuleDialogOptions {
|
|||||||
export class EditRuleDialogSmartComponent implements OnInit, OnDestroy {
|
export class EditRuleDialogSmartComponent implements OnInit, OnDestroy {
|
||||||
formValid = false;
|
formValid = false;
|
||||||
model: Partial<Rule>;
|
model: Partial<Rule>;
|
||||||
|
nodeId = '';
|
||||||
formValue: Partial<Rule>;
|
formValue: Partial<Rule>;
|
||||||
@Output() submitted = new EventEmitter<Partial<Rule>>();
|
@Output() submitted = new EventEmitter<Partial<Rule>>();
|
||||||
actionDefinitions$ = this.actionsService.actionDefinitionsListing$;
|
actionDefinitions$ = this.actionsService.actionDefinitionsListing$;
|
||||||
@ -51,6 +53,7 @@ export class EditRuleDialogSmartComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
constructor(@Inject(MAT_DIALOG_DATA) public data: EditRuleDialogOptions, private actionsService: ActionsService) {
|
constructor(@Inject(MAT_DIALOG_DATA) public data: EditRuleDialogOptions, private actionsService: ActionsService) {
|
||||||
this.model = this.data?.model || {};
|
this.model = this.data?.model || {};
|
||||||
|
this.nodeId = this.data?.nodeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isUpdateMode(): boolean {
|
get isUpdateMode(): boolean {
|
||||||
|
@ -47,7 +47,8 @@
|
|||||||
formControlName="actions"
|
formControlName="actions"
|
||||||
[actionDefinitions]="actionDefinitions"
|
[actionDefinitions]="actionDefinitions"
|
||||||
[parameterConstraints]="parameterConstraints"
|
[parameterConstraints]="parameterConstraints"
|
||||||
[readOnly]="readOnly">
|
[readOnly]="readOnly"
|
||||||
|
[nodeId]="nodeId">
|
||||||
</aca-rule-action-list>
|
</aca-rule-action-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -97,6 +97,8 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
|||||||
actionDefinitions: ActionDefinitionTransformed[] = [];
|
actionDefinitions: ActionDefinitionTransformed[] = [];
|
||||||
@Input()
|
@Input()
|
||||||
parameterConstraints: ActionParameterConstraint[] = [];
|
parameterConstraints: ActionParameterConstraint[] = [];
|
||||||
|
@Input()
|
||||||
|
nodeId = '';
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
formValidationChanged = new EventEmitter<boolean>();
|
formValidationChanged = new EventEmitter<boolean>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user