mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACS-3859] Action parameter constraints into dropdown box (#2773)
* [ACS-3859] - functionality implementation * [ACS-3859] - unit tests * [ACS-3859] - small fix
This commit is contained in:
parent
5ce4835e4c
commit
854fb28374
@ -35,7 +35,6 @@ import { By } from '@angular/platform-browser';
|
|||||||
import { dummyNodeInfo } from '../mock/node.mock';
|
import { dummyNodeInfo } from '../mock/node.mock';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ActionsService } from '../services/actions.service';
|
import { ActionsService } from '../services/actions.service';
|
||||||
import { dummyAspects } from '../mock/aspects.mock';
|
|
||||||
|
|
||||||
describe('ManageRulesSmartComponent', () => {
|
describe('ManageRulesSmartComponent', () => {
|
||||||
let fixture: ComponentFixture<ManageRulesSmartComponent>;
|
let fixture: ComponentFixture<ManageRulesSmartComponent>;
|
||||||
@ -61,7 +60,6 @@ describe('ManageRulesSmartComponent', () => {
|
|||||||
debugElement = fixture.debugElement;
|
debugElement = fixture.debugElement;
|
||||||
folderRulesService = TestBed.inject<FolderRulesService>(FolderRulesService);
|
folderRulesService = TestBed.inject<FolderRulesService>(FolderRulesService);
|
||||||
actionsService = TestBed.inject<ActionsService>(ActionsService);
|
actionsService = TestBed.inject<ActionsService>(ActionsService);
|
||||||
actionsService.aspects$ = of(dummyAspects);
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -23,9 +23,12 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Aspect } from '../model/aspect.model';
|
import { ActionParameterConstraint } from '../model/action-parameter-constraint.model';
|
||||||
|
|
||||||
export const dummyAspects: Aspect[] = [
|
export const dummyConstraints: ActionParameterConstraint[] = [
|
||||||
|
{
|
||||||
|
name: 'aspect-name',
|
||||||
|
constraints: [
|
||||||
{
|
{
|
||||||
value: 'cm:aspect1',
|
value: 'cm:aspect1',
|
||||||
label: 'Label 1'
|
label: 'Label 1'
|
||||||
@ -36,6 +39,27 @@ export const dummyAspects: Aspect[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'cm:aspect3',
|
value: 'cm:aspect3',
|
||||||
label: 'Label 3'
|
label: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const rawConstraints = {
|
||||||
|
entry: {
|
||||||
|
constraintValues: [
|
||||||
|
{
|
||||||
|
value: 'cm:aspect1',
|
||||||
|
label: 'Label 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'cm:aspect2',
|
||||||
|
label: 'Label 2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'cm:aspect3'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
constraintName: 'ac-aspects'
|
||||||
|
}
|
||||||
|
};
|
@ -23,10 +23,9 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ActionDefinitionList } from '@alfresco/js-api';
|
|
||||||
import { ActionDefinitionTransformed, ActionParameterDefinitionTransformed, RuleAction } from '../model/rule-action.model';
|
import { ActionDefinitionTransformed, ActionParameterDefinitionTransformed, RuleAction } from '../model/rule-action.model';
|
||||||
|
|
||||||
export const actionDefListMock: ActionDefinitionList = {
|
export const actionDefListMock = {
|
||||||
list: {
|
list: {
|
||||||
pagination: {
|
pagination: {
|
||||||
count: 2,
|
count: 2,
|
||||||
@ -56,7 +55,8 @@ export const actionDefListMock: ActionDefinitionList = {
|
|||||||
name: 'aspect-name',
|
name: 'aspect-name',
|
||||||
type: 'd:qname',
|
type: 'd:qname',
|
||||||
multiValued: false,
|
multiValued: false,
|
||||||
mandatory: false
|
mandatory: false,
|
||||||
|
parameterConstraintName: 'ac-aspects'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'mock-action-1-definition',
|
name: 'mock-action-1-definition',
|
||||||
@ -80,7 +80,8 @@ const actionParam1TransformedMock: ActionParameterDefinitionTransformed = {
|
|||||||
type: 'd:text',
|
type: 'd:text',
|
||||||
multiValued: false,
|
multiValued: false,
|
||||||
mandatory: true,
|
mandatory: true,
|
||||||
displayLabel: 'Mock action parameter text'
|
displayLabel: 'Mock action parameter text',
|
||||||
|
parameterConstraintName: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionParam2TransformedMock: ActionParameterDefinitionTransformed = {
|
const actionParam2TransformedMock: ActionParameterDefinitionTransformed = {
|
||||||
@ -88,7 +89,8 @@ const actionParam2TransformedMock: ActionParameterDefinitionTransformed = {
|
|||||||
type: 'd:boolean',
|
type: 'd:boolean',
|
||||||
multiValued: false,
|
multiValued: false,
|
||||||
mandatory: false,
|
mandatory: false,
|
||||||
displayLabel: 'mock-action-parameter-boolean'
|
displayLabel: 'mock-action-parameter-boolean',
|
||||||
|
parameterConstraintName: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionParam3TransformedMock: ActionParameterDefinitionTransformed = {
|
const actionParam3TransformedMock: ActionParameterDefinitionTransformed = {
|
||||||
@ -96,7 +98,8 @@ const actionParam3TransformedMock: ActionParameterDefinitionTransformed = {
|
|||||||
type: 'd:qname',
|
type: 'd:qname',
|
||||||
multiValued: false,
|
multiValued: false,
|
||||||
mandatory: false,
|
mandatory: false,
|
||||||
displayLabel: 'aspect-name'
|
displayLabel: 'aspect-name',
|
||||||
|
parameterConstraintName: 'ac-aspects'
|
||||||
};
|
};
|
||||||
|
|
||||||
const action1TransformedMock: ActionDefinitionTransformed = {
|
const action1TransformedMock: ActionDefinitionTransformed = {
|
||||||
|
@ -23,7 +23,12 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface Aspect {
|
export interface ActionParameterConstraint {
|
||||||
|
name: string;
|
||||||
|
constraints: ConstraintValue[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConstraintValue {
|
||||||
value: string;
|
value: string;
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
@ -49,4 +49,5 @@ export interface ActionParameterDefinitionTransformed {
|
|||||||
multiValued: boolean;
|
multiValued: boolean;
|
||||||
mandatory: boolean;
|
mandatory: boolean;
|
||||||
displayLabel: string;
|
displayLabel: string;
|
||||||
|
parameterConstraintName?: string;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div class="aca-rule-action-list__item " *ngFor="let control of formControls">
|
<div class="aca-rule-action-list__item " *ngFor="let control of formControls">
|
||||||
<aca-rule-action
|
<aca-rule-action
|
||||||
[actionDefinitions]="actionDefinitions"
|
[actionDefinitions]="actionDefinitions"
|
||||||
[aspects]="aspects"
|
[parameterConstraints]="parameterConstraints"
|
||||||
[readOnly]="readOnly"
|
[readOnly]="readOnly"
|
||||||
[formControl]="control">
|
[formControl]="control">
|
||||||
</aca-rule-action>
|
</aca-rule-action>
|
||||||
|
@ -28,7 +28,7 @@ import { ControlValueAccessor, FormArray, FormControl, NG_VALUE_ACCESSOR, Valida
|
|||||||
import { ActionDefinitionTransformed, RuleAction } from '../../model/rule-action.model';
|
import { ActionDefinitionTransformed, RuleAction } from '../../model/rule-action.model';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { ruleActionValidator } from '../validators/rule-actions.validator';
|
import { ruleActionValidator } from '../validators/rule-actions.validator';
|
||||||
import { Aspect } from '../../model/aspect.model';
|
import { ActionParameterConstraint } from '../../model/action-parameter-constraint.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'aca-rule-action-list',
|
selector: 'aca-rule-action-list',
|
||||||
@ -50,7 +50,7 @@ export class RuleActionListUiComponent implements ControlValueAccessor, OnDestro
|
|||||||
@Input()
|
@Input()
|
||||||
readOnly = false;
|
readOnly = false;
|
||||||
@Input()
|
@Input()
|
||||||
aspects: Aspect[] = [];
|
parameterConstraints: ActionParameterConstraint[] = [];
|
||||||
|
|
||||||
formArray = new FormArray([]);
|
formArray = new FormArray([]);
|
||||||
private formArraySubscription: Subscription;
|
private formArraySubscription: Subscription;
|
||||||
|
@ -29,6 +29,7 @@ import { RuleActionUiComponent } from './rule-action.ui-component';
|
|||||||
import { actionsTransformedListMock } from '../../mock/actions.mock';
|
import { actionsTransformedListMock } from '../../mock/actions.mock';
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { dummyConstraints } from '../../mock/action-parameter-constraints.mock';
|
||||||
|
|
||||||
describe('RuleActionUiComponent', () => {
|
describe('RuleActionUiComponent', () => {
|
||||||
let fixture: ComponentFixture<RuleActionUiComponent>;
|
let fixture: ComponentFixture<RuleActionUiComponent>;
|
||||||
@ -71,6 +72,7 @@ describe('RuleActionUiComponent', () => {
|
|||||||
|
|
||||||
it('should populate the card view with parameters when an action is selected', () => {
|
it('should populate the card view with parameters when an action is selected', () => {
|
||||||
component.actionDefinitions = actionsTransformedListMock;
|
component.actionDefinitions = actionsTransformedListMock;
|
||||||
|
component.parameterConstraints = dummyConstraints;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const cardView = getByDataAutomationId('rule-action-card-view').componentInstance as CardViewComponent;
|
const cardView = getByDataAutomationId('rule-action-card-view').componentInstance as CardViewComponent;
|
||||||
|
@ -38,7 +38,7 @@ import {
|
|||||||
import { ActionParameterDefinition } from '@alfresco/js-api';
|
import { ActionParameterDefinition } 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 { Aspect } from '../../model/aspect.model';
|
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'aca-rule-action',
|
selector: 'aca-rule-action',
|
||||||
@ -74,13 +74,13 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
this.setDisabledState(isReadOnly);
|
this.setDisabledState(isReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _aspects;
|
private _parameterConstraints = [];
|
||||||
@Input()
|
@Input()
|
||||||
get aspects(): Aspect[] {
|
get parameterConstraints(): ActionParameterConstraint[] {
|
||||||
return this._aspects;
|
return this._parameterConstraints;
|
||||||
}
|
}
|
||||||
set aspects(value) {
|
set parameterConstraints(value) {
|
||||||
this._aspects = this.parseAspectsToSelectOptions(value);
|
this._parameterConstraints = value.map((obj) => ({ ...obj, constraints: this.parseConstraintsToSelectOptions(obj.constraints) }));
|
||||||
}
|
}
|
||||||
|
|
||||||
isFullWidth = false;
|
isFullWidth = false;
|
||||||
@ -182,17 +182,16 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
...cardViewPropertiesModel,
|
...cardViewPropertiesModel,
|
||||||
value: this.parameters[paramDef.name] ?? false
|
value: this.parameters[paramDef.name] ?? false
|
||||||
});
|
});
|
||||||
case 'd:qname':
|
default:
|
||||||
if (paramDef.name === 'aspect-name' && !this.readOnly) {
|
const constraintsForDropdownBox = this._parameterConstraints.find((obj) => obj.name === paramDef.name);
|
||||||
|
if (constraintsForDropdownBox && !this.readOnly) {
|
||||||
this.isFullWidth = true;
|
this.isFullWidth = true;
|
||||||
return new CardViewSelectItemModel({
|
return new CardViewSelectItemModel({
|
||||||
...cardViewPropertiesModel,
|
...cardViewPropertiesModel,
|
||||||
value: (this.parameters[paramDef.name] as string) ?? '',
|
value: (this.parameters[paramDef.name] as string) ?? '',
|
||||||
options$: of(this._aspects)
|
options$: of(constraintsForDropdownBox.constraints)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/* falls through */
|
|
||||||
default:
|
|
||||||
return new CardViewTextItemModel({
|
return new CardViewTextItemModel({
|
||||||
...cardViewPropertiesModel,
|
...cardViewPropertiesModel,
|
||||||
value: this.parameters[paramDef.name] ?? ''
|
value: this.parameters[paramDef.name] ?? ''
|
||||||
@ -224,8 +223,8 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseAspectsToSelectOptions(aspects: Aspect[]): CardViewSelectItemOption<unknown>[] {
|
private parseConstraintsToSelectOptions(constraints: ConstraintValue[]): CardViewSelectItemOption<unknown>[] {
|
||||||
return aspects
|
return constraints
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (!a.label && b.label) {
|
if (!a.label && b.label) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -235,9 +234,9 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnDe
|
|||||||
}
|
}
|
||||||
return a.label?.localeCompare(b.label) ?? -1;
|
return a.label?.localeCompare(b.label) ?? -1;
|
||||||
})
|
})
|
||||||
.map((aspect) => ({
|
.map((constraint) => ({
|
||||||
key: aspect.value,
|
key: constraint.value,
|
||||||
label: aspect.label ? `${aspect.label} [${aspect.value}]` : aspect.value
|
label: constraint.label ? `${constraint.label} [${constraint.value}]` : constraint.value
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<ng-template #ruleDetails>
|
<ng-template #ruleDetails>
|
||||||
<aca-rule-details
|
<aca-rule-details
|
||||||
[actionDefinitions]="actionDefinitions$ | async"
|
[actionDefinitions]="actionDefinitions$ | async"
|
||||||
[aspects]="aspects$ | async"
|
[parameterConstraints]="parameterConstraints$ | async"
|
||||||
[value]="model"
|
[value]="model"
|
||||||
(formValueChanged)="formValue = $event"
|
(formValueChanged)="formValue = $event"
|
||||||
(formValidationChanged)="onFormValidChange($event)">
|
(formValidationChanged)="onFormValidChange($event)">
|
||||||
|
@ -66,7 +66,7 @@ describe('EditRuleDialogSmartComponent', () => {
|
|||||||
|
|
||||||
actionsService = TestBed.inject(ActionsService);
|
actionsService = TestBed.inject(ActionsService);
|
||||||
spyOn(actionsService, 'loadActionDefinitions').and.stub();
|
spyOn(actionsService, 'loadActionDefinitions').and.stub();
|
||||||
spyOn(actionsService, 'loadAspects').and.stub();
|
spyOn(actionsService, 'getParameterConstraints').and.stub();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(EditRuleDialogSmartComponent);
|
fixture = TestBed.createComponent(EditRuleDialogSmartComponent);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, EventEmitter, Inject, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
import { Component, EventEmitter, Inject, OnInit, OnDestroy, Output, ViewEncapsulation } from '@angular/core';
|
||||||
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
import { Rule } from '../model/rule.model';
|
import { Rule } from '../model/rule.model';
|
||||||
import { ActionsService } from '../services/actions.service';
|
import { ActionsService } from '../services/actions.service';
|
||||||
@ -39,14 +39,15 @@ export interface EditRuleDialogOptions {
|
|||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
host: { class: 'aca-edit-rule-dialog' }
|
host: { class: 'aca-edit-rule-dialog' }
|
||||||
})
|
})
|
||||||
export class EditRuleDialogSmartComponent implements OnInit {
|
export class EditRuleDialogSmartComponent implements OnInit, OnDestroy {
|
||||||
formValid = false;
|
formValid = false;
|
||||||
model: Partial<Rule>;
|
model: Partial<Rule>;
|
||||||
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$;
|
||||||
loading$ = this.actionsService.loading$;
|
loading$ = this.actionsService.loading$;
|
||||||
aspects$ = this.actionsService.aspects$;
|
parameterConstraints$ = this.actionsService.parameterConstraints$;
|
||||||
|
private _actionDefinitionsSub;
|
||||||
|
|
||||||
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 || {};
|
||||||
@ -69,8 +70,14 @@ export class EditRuleDialogSmartComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.actionsService.loadAspects();
|
|
||||||
this.actionsService.loadActionDefinitions();
|
this.actionsService.loadActionDefinitions();
|
||||||
|
this._actionDefinitionsSub = this.actionDefinitions$.subscribe((actionDefinitions) =>
|
||||||
|
this.actionsService.loadActionParameterConstraints(actionDefinitions)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this._actionDefinitionsSub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
onFormValidChange(isValid: boolean) {
|
onFormValidChange(isValid: boolean) {
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
<aca-rule-action-list
|
<aca-rule-action-list
|
||||||
formControlName="actions"
|
formControlName="actions"
|
||||||
[actionDefinitions]="actionDefinitions"
|
[actionDefinitions]="actionDefinitions"
|
||||||
[aspects]="aspects"
|
[parameterConstraints]="parameterConstraints"
|
||||||
[readOnly]="readOnly">
|
[readOnly]="readOnly">
|
||||||
</aca-rule-action-list>
|
</aca-rule-action-list>
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,7 +32,7 @@ import { ruleCompositeConditionValidator } from './validators/rule-composite-con
|
|||||||
import { FolderRulesService } from '../services/folder-rules.service';
|
import { FolderRulesService } from '../services/folder-rules.service';
|
||||||
import { ActionDefinitionTransformed } from '../model/rule-action.model';
|
import { ActionDefinitionTransformed } from '../model/rule-action.model';
|
||||||
import { ruleActionsValidator } from './validators/rule-actions.validator';
|
import { ruleActionsValidator } from './validators/rule-actions.validator';
|
||||||
import { Aspect } from '../model/aspect.model';
|
import { ActionParameterConstraint } from '../model/action-parameter-constraint.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'aca-rule-details',
|
selector: 'aca-rule-details',
|
||||||
@ -96,7 +96,7 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
|
|||||||
@Input()
|
@Input()
|
||||||
actionDefinitions: ActionDefinitionTransformed[] = [];
|
actionDefinitions: ActionDefinitionTransformed[] = [];
|
||||||
@Input()
|
@Input()
|
||||||
aspects: Aspect[] = [];
|
parameterConstraints: ActionParameterConstraint[] = [];
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
formValidationChanged = new EventEmitter<boolean>();
|
formValidationChanged = new EventEmitter<boolean>();
|
||||||
|
@ -29,6 +29,8 @@ import { CoreTestingModule } from '@alfresco/adf-core';
|
|||||||
import { ActionsApi } from '@alfresco/js-api';
|
import { ActionsApi } from '@alfresco/js-api';
|
||||||
import { actionDefListMock, actionsTransformedListMock } from '../mock/actions.mock';
|
import { actionDefListMock, actionsTransformedListMock } from '../mock/actions.mock';
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
|
import { dummyConstraints, rawConstraints } from '../mock/action-parameter-constraints.mock';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
describe('ActionsService', () => {
|
describe('ActionsService', () => {
|
||||||
let actionsService: ActionsService;
|
let actionsService: ActionsService;
|
||||||
@ -65,12 +67,29 @@ describe('ActionsService', () => {
|
|||||||
expect(await loadingFalsePromise).toBeFalse();
|
expect(await loadingFalsePromise).toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loadAspects should send correct GET request', async () => {
|
it('loadParameterConstraints should send GET request and return formatted observable', async () => {
|
||||||
apiCallSpy = spyOn<any>(actionsService, 'publicApiCall').withArgs(`/action-parameter-constraints/ac-aspects`, 'GET', params).and.returnValue([]);
|
const constraintName = dummyConstraints[0].name;
|
||||||
|
const formattedConstraints = dummyConstraints[0].constraints;
|
||||||
|
|
||||||
actionsService.loadAspects();
|
apiCallSpy = spyOn<any>(actionsService, 'publicApiCall')
|
||||||
|
.withArgs(`/action-parameter-constraints/${constraintName}`, 'GET', params)
|
||||||
|
.and.returnValue(of(rawConstraints));
|
||||||
|
|
||||||
|
actionsService.getParameterConstraints(constraintName).subscribe((result) => expect(result).toEqual(formattedConstraints));
|
||||||
|
|
||||||
expect(apiCallSpy).toHaveBeenCalled();
|
expect(apiCallSpy).toHaveBeenCalled();
|
||||||
expect(apiCallSpy).toHaveBeenCalledWith(`/action-parameter-constraints/ac-aspects`, 'GET', params);
|
expect(apiCallSpy).toHaveBeenCalledWith(`/action-parameter-constraints/${constraintName}`, 'GET', params);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('loadActionParameterConstraints should load the data into the observable', async () => {
|
||||||
|
spyOn<any>(actionsService, 'getParameterConstraints').and.returnValue(of(dummyConstraints[0].constraints));
|
||||||
|
|
||||||
|
const constraintsPromise = actionsService.parameterConstraints$.pipe(take(2)).toPromise();
|
||||||
|
|
||||||
|
actionsService.loadActionParameterConstraints(actionsTransformedListMock);
|
||||||
|
|
||||||
|
const parameterConstraints = await constraintsPromise;
|
||||||
|
|
||||||
|
expect(parameterConstraints).toEqual(dummyConstraints);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -24,12 +24,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { ActionDefinition, ActionDefinitionEntry, ActionDefinitionList, ActionParameterDefinition, ActionsApi } from '@alfresco/js-api';
|
import { ActionDefinition, ActionDefinitionEntry, ActionDefinitionList, ActionsApi } from '@alfresco/js-api';
|
||||||
import { AlfrescoApiService } from '@alfresco/adf-core';
|
import { AlfrescoApiService } from '@alfresco/adf-core';
|
||||||
import { BehaviorSubject, from, Observable } from 'rxjs';
|
import { BehaviorSubject, forkJoin, from, Observable, of } from 'rxjs';
|
||||||
|
import { finalize, map, switchMap } from 'rxjs/operators';
|
||||||
import { ActionDefinitionTransformed, ActionParameterDefinitionTransformed } from '../model/rule-action.model';
|
import { ActionDefinitionTransformed, ActionParameterDefinitionTransformed } from '../model/rule-action.model';
|
||||||
import { finalize, map } from 'rxjs/operators';
|
import { ActionParameterConstraint, ConstraintValue } from '../model/action-parameter-constraint.model';
|
||||||
import { Aspect } from '../model/aspect.model';
|
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class ActionsService {
|
export class ActionsService {
|
||||||
@ -37,8 +37,8 @@ export class ActionsService {
|
|||||||
actionDefinitionsListing$ = this.actionDefinitionsListingSource.asObservable();
|
actionDefinitionsListing$ = this.actionDefinitionsListingSource.asObservable();
|
||||||
private loadingSource = new BehaviorSubject<boolean>(false);
|
private loadingSource = new BehaviorSubject<boolean>(false);
|
||||||
loading$ = this.loadingSource.asObservable();
|
loading$ = this.loadingSource.asObservable();
|
||||||
private aspectsSource = new BehaviorSubject<Aspect[]>([]);
|
private parameterConstraintsSource = new BehaviorSubject<ActionParameterConstraint[]>([]);
|
||||||
aspects$: Observable<Aspect[]> = this.aspectsSource.asObservable();
|
parameterConstraints$: Observable<ActionParameterConstraint[]> = this.parameterConstraintsSource.asObservable();
|
||||||
|
|
||||||
private _actionsApi: ActionsApi;
|
private _actionsApi: ActionsApi;
|
||||||
get actionsApi(): ActionsApi {
|
get actionsApi(): ActionsApi {
|
||||||
@ -62,12 +62,10 @@ export class ActionsService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAspects(): void {
|
getParameterConstraints(constraintName): Observable<ConstraintValue[]> {
|
||||||
from(this.publicApiCall('/action-parameter-constraints/ac-aspects', 'GET', [{}, {}, {}, {}, {}, ['application/json'], ['application/json']]))
|
return from(
|
||||||
.pipe(map((res) => res.entry.constraintValues.map((entry) => this.formatAspect(entry))))
|
this.publicApiCall(`/action-parameter-constraints/${constraintName}`, 'GET', [{}, {}, {}, {}, {}, ['application/json'], ['application/json']])
|
||||||
.subscribe((res) => {
|
).pipe(map((res) => res.entry.constraintValues.map((entry) => this.formatConstraint(entry))));
|
||||||
this.aspectsSource.next(res);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private transformActionDefinition(obj: ActionDefinition | ActionDefinitionEntry): ActionDefinitionTransformed {
|
private transformActionDefinition(obj: ActionDefinition | ActionDefinitionEntry): ActionDefinitionTransformed {
|
||||||
@ -81,19 +79,20 @@ export class ActionsService {
|
|||||||
title: obj.title ?? obj.name ?? '',
|
title: obj.title ?? obj.name ?? '',
|
||||||
applicableTypes: obj.applicableTypes ?? [],
|
applicableTypes: obj.applicableTypes ?? [],
|
||||||
trackStatus: obj.trackStatus ?? false,
|
trackStatus: obj.trackStatus ?? false,
|
||||||
parameterDefinitions: (obj.parameterDefinitions ?? []).map((paramDef: ActionParameterDefinition) =>
|
parameterDefinitions: (obj.parameterDefinitions ?? []).map((paramDef: ActionParameterDefinitionTransformed) =>
|
||||||
this.transformActionParameterDefinition(paramDef)
|
this.transformActionParameterDefinition(paramDef)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private transformActionParameterDefinition(obj: ActionParameterDefinition): ActionParameterDefinitionTransformed {
|
private transformActionParameterDefinition(obj: ActionParameterDefinitionTransformed): ActionParameterDefinitionTransformed {
|
||||||
return {
|
return {
|
||||||
name: obj.name ?? '',
|
name: obj.name ?? '',
|
||||||
type: obj.type ?? '',
|
type: obj.type ?? '',
|
||||||
multiValued: obj.multiValued ?? false,
|
multiValued: obj.multiValued ?? false,
|
||||||
mandatory: obj.mandatory ?? false,
|
mandatory: obj.mandatory ?? false,
|
||||||
displayLabel: obj.displayLabel ?? obj.name ?? ''
|
displayLabel: obj.displayLabel ?? obj.name ?? '',
|
||||||
|
parameterConstraintName: obj.parameterConstraintName ?? ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,10 +104,37 @@ export class ActionsService {
|
|||||||
return this.apiService.getInstance().contentClient.callApi(path, httpMethod, ...params);
|
return this.apiService.getInstance().contentClient.callApi(path, httpMethod, ...params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private formatAspect(aspect): Aspect {
|
private formatConstraint(constraint): ConstraintValue {
|
||||||
return {
|
return {
|
||||||
value: aspect.value ?? '',
|
value: constraint.value ?? '',
|
||||||
label: aspect.label ?? ''
|
label: constraint.label ?? ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadActionParameterConstraints(actionDefinitions: ActionDefinitionTransformed[]): void {
|
||||||
|
of(actionDefinitions)
|
||||||
|
.pipe(
|
||||||
|
map((actionDefinition) =>
|
||||||
|
actionDefinition
|
||||||
|
.map((obj) => obj.parameterDefinitions)
|
||||||
|
.flat()
|
||||||
|
.filter((parameterDefinition) => parameterDefinition.parameterConstraintName.length > 0)
|
||||||
|
.map((parameterDefinition) => ({
|
||||||
|
name: parameterDefinition.name,
|
||||||
|
parameterConstraintName: parameterDefinition.parameterConstraintName,
|
||||||
|
constraints: null
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
switchMap((parameterDefinitions) =>
|
||||||
|
forkJoin(
|
||||||
|
...parameterDefinitions.map((parameterDefinition) =>
|
||||||
|
this.getParameterConstraints(parameterDefinition.parameterConstraintName).pipe(
|
||||||
|
map((constraints) => ({ name: parameterDefinition.name, constraints }))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.subscribe((res) => this.parameterConstraintsSource.next(res));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"types": [],
|
"types": [],
|
||||||
"lib": [
|
"lib": [
|
||||||
"dom",
|
"dom",
|
||||||
"es2018"
|
"es2020"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"angularCompilerOptions": {
|
"angularCompilerOptions": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user