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",
|
||||
"versionable",
|
||||
"erroredSpy",
|
||||
"errored"
|
||||
"errored",
|
||||
"noderef"
|
||||
],
|
||||
"dictionaries": ["html", "en-gb", "en_US"]
|
||||
}
|
||||
|
@ -22,7 +22,8 @@
|
||||
"NAME": "Enter rule name",
|
||||
"DESCRIPTION": "Enter rule description",
|
||||
"NO_DESCRIPTION": "No description",
|
||||
"VALUE": "Value"
|
||||
"VALUE": "Value",
|
||||
"CHOOSE_FOLDER": "Choose destination folder"
|
||||
},
|
||||
"ERROR": {
|
||||
"REQUIRED": "This field is required",
|
||||
|
@ -86,7 +86,8 @@
|
||||
[actionDefinitions]="actionDefinitions$ | async"
|
||||
[readOnly]="true"
|
||||
[preview]="true"
|
||||
[value]="selectedRule">
|
||||
[value]="selectedRule"
|
||||
[nodeId]="nodeId">
|
||||
</aca-rule-details>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -48,7 +48,7 @@ import { RuleSet } from '../model/rule-set.model';
|
||||
host: { class: 'aca-manage-rules' }
|
||||
})
|
||||
export class ManageRulesSmartComponent implements OnInit, OnDestroy {
|
||||
nodeId: string = null;
|
||||
nodeId = '';
|
||||
|
||||
mainRuleSet$: Observable<RuleSet>;
|
||||
inheritedRuleSets$: Observable<RuleSet[]>;
|
||||
@ -115,7 +115,8 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
|
||||
width: '90%',
|
||||
panelClass: 'aca-edit-rule-dialog-container',
|
||||
data: {
|
||||
model
|
||||
model,
|
||||
nodeId: this.nodeId
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -57,6 +57,18 @@ export const actionDefListMock = {
|
||||
multiValued: false,
|
||||
mandatory: false,
|
||||
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',
|
||||
@ -102,6 +114,24 @@ const actionParam3TransformedMock: ActionParameterDefinitionTransformed = {
|
||||
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 = {
|
||||
id: 'mock-action-1-definition',
|
||||
name: 'mock-action-1-definition',
|
||||
@ -109,7 +139,13 @@ const action1TransformedMock: ActionDefinitionTransformed = {
|
||||
title: 'Action 1 title',
|
||||
applicableTypes: [],
|
||||
trackStatus: false,
|
||||
parameterDefinitions: [actionParam1TransformedMock, actionParam2TransformedMock, actionParam3TransformedMock]
|
||||
parameterDefinitions: [
|
||||
actionParam1TransformedMock,
|
||||
actionParam2TransformedMock,
|
||||
actionParam3TransformedMock,
|
||||
actionParam4TransformedMock,
|
||||
actionParam5TransformedMock
|
||||
]
|
||||
};
|
||||
|
||||
const action2TransformedMock: ActionDefinitionTransformed = {
|
||||
|
@ -3,7 +3,8 @@
|
||||
[actionDefinitions]="actionDefinitions"
|
||||
[parameterConstraints]="parameterConstraints"
|
||||
[readOnly]="readOnly"
|
||||
[formControl]="control">
|
||||
[formControl]="control"
|
||||
[nodeId]="nodeId">
|
||||
</aca-rule-action>
|
||||
|
||||
<button
|
||||
|
@ -51,6 +51,8 @@ export class RuleActionListUiComponent implements ControlValueAccessor, OnDestro
|
||||
readOnly = false;
|
||||
@Input()
|
||||
parameterConstraints: ActionParameterConstraint[] = [];
|
||||
@Input()
|
||||
nodeId = '';
|
||||
|
||||
formArray = new FormArray([]);
|
||||
private formArraySubscription: Subscription;
|
||||
|
@ -79,10 +79,13 @@ describe('RuleActionUiComponent', () => {
|
||||
expect(cardView.properties.length).toBe(0);
|
||||
|
||||
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[1]).toBeInstanceOf(CardViewBoolItemModel);
|
||||
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');
|
||||
expect(cardView.properties.length).toBe(0);
|
||||
|
@ -35,10 +35,13 @@ import {
|
||||
CardViewUpdateService,
|
||||
UpdateNotification
|
||||
} from '@alfresco/adf-core';
|
||||
import { ActionParameterDefinition } from '@alfresco/js-api';
|
||||
import { ActionParameterDefinition, Node } from '@alfresco/js-api';
|
||||
import { of, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
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({
|
||||
selector: 'aca-rule-action',
|
||||
@ -56,6 +59,9 @@ import { ActionParameterConstraint, ConstraintValue } from '../../model/action-p
|
||||
]
|
||||
})
|
||||
export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDestroy {
|
||||
@Input()
|
||||
nodeId = '';
|
||||
|
||||
private _actionDefinitions: ActionDefinitionTransformed[];
|
||||
@Input()
|
||||
get actionDefinitions(): ActionDefinitionTransformed[] {
|
||||
@ -108,7 +114,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
||||
onChange: (action: RuleAction) => void = () => undefined;
|
||||
onTouch: () => void = () => undefined;
|
||||
|
||||
constructor(private cardViewUpdateService: CardViewUpdateService) {}
|
||||
constructor(private cardViewUpdateService: CardViewUpdateService, private dialog: MatDialog, private translate: TranslateService) {}
|
||||
|
||||
writeValue(action: RuleAction) {
|
||||
this.form.setValue({
|
||||
@ -161,6 +167,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
||||
setCardViewProperties() {
|
||||
this.cardViewItems = (this.selectedActionDefinition?.parameterDefinitions ?? []).map((paramDef) => {
|
||||
this.isFullWidth = false;
|
||||
const constraintsForDropdownBox = this._parameterConstraints.find((obj) => obj.name === paramDef.name);
|
||||
const cardViewPropertiesModel = {
|
||||
label: paramDef.displayLabel + (paramDef.mandatory ? ' *' : ''),
|
||||
key: paramDef.name,
|
||||
@ -182,8 +189,19 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
||||
...cardViewPropertiesModel,
|
||||
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:
|
||||
const constraintsForDropdownBox = this._parameterConstraints.find((obj) => obj.name === paramDef.name);
|
||||
if (constraintsForDropdownBox && !this.readOnly) {
|
||||
this.isFullWidth = true;
|
||||
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() {
|
||||
this.parameters = {};
|
||||
(this.selectedActionDefinition?.parameterDefinitions ?? []).forEach((paramDef: ActionParameterDefinition) => {
|
||||
|
@ -20,6 +20,7 @@
|
||||
[actionDefinitions]="actionDefinitions$ | async"
|
||||
[parameterConstraints]="parameterConstraints$ | async"
|
||||
[value]="model"
|
||||
[nodeId]="nodeId"
|
||||
(formValueChanged)="formValue = $event"
|
||||
(formValidationChanged)="onFormValidChange($event)">
|
||||
</aca-rule-details>
|
||||
|
@ -30,6 +30,7 @@ import { ActionsService } from '../services/actions.service';
|
||||
|
||||
export interface EditRuleDialogOptions {
|
||||
model?: Partial<Rule>;
|
||||
nodeId?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@ -42,6 +43,7 @@ export interface EditRuleDialogOptions {
|
||||
export class EditRuleDialogSmartComponent implements OnInit, OnDestroy {
|
||||
formValid = false;
|
||||
model: Partial<Rule>;
|
||||
nodeId = '';
|
||||
formValue: Partial<Rule>;
|
||||
@Output() submitted = new EventEmitter<Partial<Rule>>();
|
||||
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) {
|
||||
this.model = this.data?.model || {};
|
||||
this.nodeId = this.data?.nodeId;
|
||||
}
|
||||
|
||||
get isUpdateMode(): boolean {
|
||||
|
@ -47,7 +47,8 @@
|
||||
formControlName="actions"
|
||||
[actionDefinitions]="actionDefinitions"
|
||||
[parameterConstraints]="parameterConstraints"
|
||||
[readOnly]="readOnly">
|
||||
[readOnly]="readOnly"
|
||||
[nodeId]="nodeId">
|
||||
</aca-rule-action-list>
|
||||
</div>
|
||||
|
||||
|
@ -97,6 +97,8 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
||||
actionDefinitions: ActionDefinitionTransformed[] = [];
|
||||
@Input()
|
||||
parameterConstraints: ActionParameterConstraint[] = [];
|
||||
@Input()
|
||||
nodeId = '';
|
||||
|
||||
@Output()
|
||||
formValidationChanged = new EventEmitter<boolean>();
|
||||
|
Loading…
x
Reference in New Issue
Block a user