mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-15082][AAE-15081] Resolve the options coming from a json variabl… (#8673)
* [AAE-15082][AAE-15081] Resolve the options coming from a json variable for a dropdown * split method to smaller parts and remove duplications in units * fix unit tests * get variables from API call * [AAE-15082] Add handle form variable * replace variableId by variableName * improve code
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface VariableConfig {
|
||||||
|
variableName: string;
|
||||||
|
optionsPath?: string;
|
||||||
|
optionsId?: string;
|
||||||
|
optionsLabel?: string;
|
||||||
|
}
|
@@ -27,6 +27,7 @@ import { FormWidgetModel } from './form-widget.model';
|
|||||||
import { FormFieldRule } from './form-field-rule';
|
import { FormFieldRule } from './form-field-rule';
|
||||||
import { ProcessFormModel } from './process-form-model.interface';
|
import { ProcessFormModel } from './process-form-model.interface';
|
||||||
import { isNumberValue } from './form-field-utils';
|
import { isNumberValue } from './form-field-utils';
|
||||||
|
import { VariableConfig } from './form-field-variable-options';
|
||||||
|
|
||||||
// Maps to FormFieldRepresentation
|
// Maps to FormFieldRepresentation
|
||||||
export class FormFieldModel extends FormWidgetModel {
|
export class FormFieldModel extends FormWidgetModel {
|
||||||
@@ -66,7 +67,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
restLabelProperty: string;
|
restLabelProperty: string;
|
||||||
hasEmptyValue: boolean;
|
hasEmptyValue: boolean;
|
||||||
className: string;
|
className: string;
|
||||||
optionType: 'rest' | 'manual' ;
|
optionType: 'rest' | 'manual' | 'variable';
|
||||||
params: FormFieldMetadata = {};
|
params: FormFieldMetadata = {};
|
||||||
hyperlinkUrl: string;
|
hyperlinkUrl: string;
|
||||||
displayText: string;
|
displayText: string;
|
||||||
@@ -81,6 +82,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
selectLoggedUser: boolean;
|
selectLoggedUser: boolean;
|
||||||
groupsRestriction: string[];
|
groupsRestriction: string[];
|
||||||
leftLabels: boolean = false;
|
leftLabels: boolean = false;
|
||||||
|
variableConfig: VariableConfig;
|
||||||
|
|
||||||
// container model members
|
// container model members
|
||||||
numberOfColumns: number = 1;
|
numberOfColumns: number = 1;
|
||||||
@@ -194,6 +196,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
this.rule = json.rule;
|
this.rule = json.rule;
|
||||||
this.selectLoggedUser = json.selectLoggedUser;
|
this.selectLoggedUser = json.selectLoggedUser;
|
||||||
this.groupsRestriction = json.groupsRestriction?.groups;
|
this.groupsRestriction = json.groupsRestriction?.groups;
|
||||||
|
this.variableConfig = json.variableConfig;
|
||||||
|
|
||||||
if (json.placeholder && json.placeholder !== '' && json.placeholder !== 'null') {
|
if (json.placeholder && json.placeholder !== '' && json.placeholder !== 'null') {
|
||||||
this.placeholder = json.placeholder;
|
this.placeholder = json.placeholder;
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
"UPLOAD": "UPLOAD",
|
"UPLOAD": "UPLOAD",
|
||||||
"REQUIRED": "This is a required field",
|
"REQUIRED": "This is a required field",
|
||||||
"REST_API_FAILED": "The server `{{ hostname }}` is not reachable",
|
"REST_API_FAILED": "The server `{{ hostname }}` is not reachable",
|
||||||
|
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "There was a problem loading dropdown elements. Please contact administrator.",
|
||||||
"FILE_NAME": "File Name",
|
"FILE_NAME": "File Name",
|
||||||
"NO_FILE_ATTACHED": "No file attached",
|
"NO_FILE_ATTACHED": "No file attached",
|
||||||
"VALIDATOR": {
|
"VALIDATOR": {
|
||||||
|
@@ -37,5 +37,7 @@
|
|||||||
required="{{ 'FORM.FIELD.REQUIRED' | translate }}"></error-widget>
|
required="{{ 'FORM.FIELD.REQUIRED' | translate }}"></error-widget>
|
||||||
<error-widget class="adf-dropdown-failed-message" *ngIf="isRestApiFailed"
|
<error-widget class="adf-dropdown-failed-message" *ngIf="isRestApiFailed"
|
||||||
required="{{ 'FORM.FIELD.REST_API_FAILED' | translate: { hostname: restApiHostName } }}"></error-widget>
|
required="{{ 'FORM.FIELD.REST_API_FAILED' | translate: { hostname: restApiHostName } }}"></error-widget>
|
||||||
|
<error-widget class="adf-dropdown-failed-message" *ngIf="variableOptionsFailed"
|
||||||
|
required="{{ 'FORM.FIELD.VARIABLE_DROPDOWN_OPTIONS_FAILED' | translate }}"></error-widget>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -19,7 +19,15 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget';
|
import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget';
|
||||||
import { FormFieldModel, FormModel, FormService, setupTestBed, FormFieldEvent, FormFieldTypes } from '@alfresco/adf-core';
|
import {
|
||||||
|
FormFieldModel,
|
||||||
|
FormModel,
|
||||||
|
FormService,
|
||||||
|
setupTestBed,
|
||||||
|
FormFieldEvent,
|
||||||
|
FormFieldTypes,
|
||||||
|
LogService
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
import { FormCloudService } from '../../../services/form-cloud.service';
|
import { FormCloudService } from '../../../services/form-cloud.service';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
@@ -27,16 +35,22 @@ import {
|
|||||||
fakeOptionList,
|
fakeOptionList,
|
||||||
filterOptionList,
|
filterOptionList,
|
||||||
mockConditionalEntries,
|
mockConditionalEntries,
|
||||||
|
mockFormVariableWithJson,
|
||||||
|
mockPlayersResponse,
|
||||||
mockRestDropdownOptions,
|
mockRestDropdownOptions,
|
||||||
mockSecondRestDropdownOptions
|
mockSecondRestDropdownOptions,
|
||||||
|
mockVariablesWithDefaultJson,
|
||||||
|
mockProcessVariablesWithJson
|
||||||
} from '../../../mocks/dropdown.mock';
|
} from '../../../mocks/dropdown.mock';
|
||||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||||
|
import { TaskVariableCloud } from '../../../models/task-variable-cloud.model';
|
||||||
|
|
||||||
describe('DropdownCloudWidgetComponent', () => {
|
describe('DropdownCloudWidgetComponent', () => {
|
||||||
|
|
||||||
let formService: FormService;
|
let formService: FormService;
|
||||||
let widget: DropdownCloudWidgetComponent;
|
let widget: DropdownCloudWidgetComponent;
|
||||||
let formCloudService: FormCloudService;
|
let formCloudService: FormCloudService;
|
||||||
|
let logService: LogService;
|
||||||
let overlayContainer: OverlayContainer;
|
let overlayContainer: OverlayContainer;
|
||||||
let fixture: ComponentFixture<DropdownCloudWidgetComponent>;
|
let fixture: ComponentFixture<DropdownCloudWidgetComponent>;
|
||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
@@ -64,6 +78,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
formService = TestBed.inject(FormService);
|
formService = TestBed.inject(FormService);
|
||||||
formCloudService = TestBed.inject(FormCloudService);
|
formCloudService = TestBed.inject(FormCloudService);
|
||||||
overlayContainer = TestBed.inject(OverlayContainer);
|
overlayContainer = TestBed.inject(OverlayContainer);
|
||||||
|
logService = TestBed.inject(LogService);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => fixture.destroy());
|
afterEach(() => fixture.destroy());
|
||||||
@@ -876,4 +891,136 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('variable options', () => {
|
||||||
|
let logServiceSpy: jasmine.Spy;
|
||||||
|
const errorIcon: string = 'error_outline';
|
||||||
|
|
||||||
|
const getVariableDropdownWidget = (
|
||||||
|
variableName: string,
|
||||||
|
optionsPath: string,
|
||||||
|
optionsId: string,
|
||||||
|
optionsLabel: string,
|
||||||
|
processVariables?: TaskVariableCloud[],
|
||||||
|
variables?: TaskVariableCloud[]
|
||||||
|
) => new FormFieldModel(
|
||||||
|
new FormModel({ taskId: 'fake-task-id', processVariables, variables }), {
|
||||||
|
id: 'variable-dropdown-id',
|
||||||
|
name: 'variable-options-dropdown',
|
||||||
|
type: 'dropdown',
|
||||||
|
readOnly: 'false',
|
||||||
|
optionType: 'variable',
|
||||||
|
variableConfig: {
|
||||||
|
variableName,
|
||||||
|
optionsPath,
|
||||||
|
optionsId,
|
||||||
|
optionsLabel
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const checkDropdownVariableOptionsFailed = () => {
|
||||||
|
const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
|
||||||
|
expect(failedErrorMsgElement.nativeElement.textContent.trim()).toBe(errorIcon.concat('FORM.FIELD.VARIABLE_DROPDOWN_OPTIONS_FAILED'));
|
||||||
|
|
||||||
|
expect(widget.field.options.length).toEqual(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
logServiceSpy = spyOn(logService, 'error');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display options persisted from process variable', async () => {
|
||||||
|
widget.field = getVariableDropdownWidget('variables.json-variable', 'response.people.players', 'playerId', 'playerFullName', mockProcessVariablesWithJson);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await openSelect('variable-dropdown-id');
|
||||||
|
|
||||||
|
const optOne: any = fixture.debugElement.query(By.css('[id="player-1"]'));
|
||||||
|
const optTwo: any = fixture.debugElement.query(By.css('[id="player-2"]'));
|
||||||
|
const optThree: any = fixture.debugElement.query(By.css('[id="player-3"]'));
|
||||||
|
|
||||||
|
expect(widget.field.options.length).toEqual(3);
|
||||||
|
expect(optOne.context.value).toBe('player-1');
|
||||||
|
expect(optOne.context.viewValue).toBe('Lionel Messi');
|
||||||
|
expect(optTwo.context.value).toBe('player-2');
|
||||||
|
expect(optTwo.context.viewValue).toBe('Cristiano Ronaldo');
|
||||||
|
expect(optThree.context.value).toBe('player-3');
|
||||||
|
expect(optThree.context.viewValue).toBe('Robert Lewandowski');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display options persisted from form variable if there are NO process variables', async () => {
|
||||||
|
widget.field = getVariableDropdownWidget('json-form-variable', 'countries', 'id', 'name', [], mockFormVariableWithJson);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await openSelect('variable-dropdown-id');
|
||||||
|
|
||||||
|
const optOne: any = fixture.debugElement.query(By.css('[id="PL"]'));
|
||||||
|
const optTwo: any = fixture.debugElement.query(By.css('[id="UK"]'));
|
||||||
|
const optThree: any = fixture.debugElement.query(By.css('[id="GR"]'));
|
||||||
|
|
||||||
|
expect(widget.field.options.length).toEqual(3);
|
||||||
|
expect(optOne.context.value).toBe('PL');
|
||||||
|
expect(optOne.context.viewValue).toBe('Poland');
|
||||||
|
expect(optTwo.context.value).toBe('UK');
|
||||||
|
expect(optTwo.context.viewValue).toBe('United Kingdom');
|
||||||
|
expect(optThree.context.value).toBe('GR');
|
||||||
|
expect(optThree.context.viewValue).toBe('Greece');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display default options if config options are NOT provided', async () => {
|
||||||
|
widget.field = getVariableDropdownWidget('variables.json-default-variable', null, null, null, mockVariablesWithDefaultJson);
|
||||||
|
fixture.detectChanges();
|
||||||
|
await openSelect('variable-dropdown-id');
|
||||||
|
|
||||||
|
const optOne: any = fixture.debugElement.query(By.css('[id="default-pet-1"]'));
|
||||||
|
const optTwo: any = fixture.debugElement.query(By.css('[id="default-pet-2"]'));
|
||||||
|
const optThree: any = fixture.debugElement.query(By.css('[id="default-pet-3"]'));
|
||||||
|
|
||||||
|
expect(widget.field.options.length).toEqual(3);
|
||||||
|
expect(optOne.context.value).toBe('default-pet-1');
|
||||||
|
expect(optOne.context.viewValue).toBe('Dog');
|
||||||
|
expect(optTwo.context.value).toBe('default-pet-2');
|
||||||
|
expect(optTwo.context.viewValue).toBe('Cat');
|
||||||
|
expect(optThree.context.value).toBe('default-pet-3');
|
||||||
|
expect(optThree.context.viewValue).toBe('Parrot');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty array and display error when path is incorrect', () => {
|
||||||
|
widget.field = getVariableDropdownWidget('variables.json-variable', 'response.wrongPath.players', 'playerId', 'playerFullName', mockProcessVariablesWithJson);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
checkDropdownVariableOptionsFailed();
|
||||||
|
expect(logServiceSpy).toHaveBeenCalledWith(`wrongPath not found in ${JSON.stringify(mockPlayersResponse.response)}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty array and display error when id is incorrect', () => {
|
||||||
|
widget.field = getVariableDropdownWidget('variables.json-variable', 'response.people.players', 'wrongId', 'playerFullName', mockProcessVariablesWithJson);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
checkDropdownVariableOptionsFailed();
|
||||||
|
expect(logServiceSpy).toHaveBeenCalledWith(`'id' or 'label' is not properly defined`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty array and display error when label is incorrect', () => {
|
||||||
|
widget.field = getVariableDropdownWidget('variables.json-variable', 'response.people.players', 'playerId', 'wrongFullName', mockProcessVariablesWithJson);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
checkDropdownVariableOptionsFailed();
|
||||||
|
expect(logServiceSpy).toHaveBeenCalledWith(`'id' or 'label' is not properly defined`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty array and display error when variable is NOT found', () => {
|
||||||
|
widget.field = getVariableDropdownWidget('variables.wrong-variable-id', 'response.people.players', 'playerId', 'playerFullName', mockProcessVariablesWithJson);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
checkDropdownVariableOptionsFailed();
|
||||||
|
expect(logServiceSpy).toHaveBeenCalledWith(`variables.wrong-variable-id not found`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty array and display error if there are NO process and form variables', () => {
|
||||||
|
widget.field = getVariableDropdownWidget('variables.json-variable', 'response.people.players', 'playerId', 'playerFullName', [], []);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
checkDropdownVariableOptionsFailed();
|
||||||
|
expect(logServiceSpy).toHaveBeenCalledWith('variables.json-variable not found');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -30,6 +30,7 @@ import {
|
|||||||
import { FormCloudService } from '../../../services/form-cloud.service';
|
import { FormCloudService } from '../../../services/form-cloud.service';
|
||||||
import { BehaviorSubject, combineLatest, Observable, of, Subject } from 'rxjs';
|
import { BehaviorSubject, combineLatest, Observable, of, Subject } from 'rxjs';
|
||||||
import { filter, map, takeUntil } from 'rxjs/operators';
|
import { filter, map, takeUntil } from 'rxjs/operators';
|
||||||
|
import { TaskVariableCloud } from '../../../models/task-variable-cloud.model';
|
||||||
|
|
||||||
export const DEFAULT_OPTION = {
|
export const DEFAULT_OPTION = {
|
||||||
id: 'empty',
|
id: 'empty',
|
||||||
@@ -60,10 +61,15 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
typeId = 'DropdownCloudWidgetComponent';
|
typeId = 'DropdownCloudWidgetComponent';
|
||||||
showInputFilter = false;
|
showInputFilter = false;
|
||||||
isRestApiFailed = false;
|
isRestApiFailed = false;
|
||||||
|
variableOptionsFailed = false;
|
||||||
restApiHostName: string;
|
restApiHostName: string;
|
||||||
list$: Observable<FormFieldOption[]>;
|
list$: Observable<FormFieldOption[]>;
|
||||||
filter$ = new BehaviorSubject<string>('');
|
filter$ = new BehaviorSubject<string>('');
|
||||||
|
|
||||||
|
private readonly defaultVariableOptionId = 'id';
|
||||||
|
private readonly defaultVariableOptionLabel = 'name';
|
||||||
|
private readonly defaultVariableOptionPath = 'data';
|
||||||
|
|
||||||
protected onDestroy$ = new Subject<boolean>();
|
protected onDestroy$ = new Subject<boolean>();
|
||||||
|
|
||||||
constructor(public formService: FormService,
|
constructor(public formService: FormService,
|
||||||
@@ -74,25 +80,113 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.field.restUrl && !this.isLinkedWidget()) {
|
this.checkFieldOptionsSource();
|
||||||
this.persistFieldOptionsFromRestApi();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isLinkedWidget()) {
|
|
||||||
this.loadFieldOptionsForLinkedWidget();
|
|
||||||
|
|
||||||
this.formService.formFieldValueChanged
|
|
||||||
.pipe(
|
|
||||||
filter((event: FormFieldEvent) => this.isFormFieldEventOfTypeDropdown(event) && this.isParentFormFieldEvent(event)),
|
|
||||||
takeUntil(this.onDestroy$))
|
|
||||||
.subscribe((event: FormFieldEvent) => {
|
|
||||||
const valueOfParentWidget = event.field.value;
|
|
||||||
this.parentValueChanged(valueOfParentWidget);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.updateOptions();
|
this.updateOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private checkFieldOptionsSource(): void {
|
||||||
|
switch (true) {
|
||||||
|
case this.field.restUrl && !this.isLinkedWidget():
|
||||||
|
this.persistFieldOptionsFromRestApi();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case this.isLinkedWidget():
|
||||||
|
this.loadFieldOptionsForLinkedWidget();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case this.isVariableOptionType():
|
||||||
|
this.persistFieldOptionsFromVariable();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private persistFieldOptionsFromVariable(): void {
|
||||||
|
const optionsPath = this.field?.variableConfig?.optionsPath ?? this.defaultVariableOptionPath;
|
||||||
|
const variableName = this.field?.variableConfig?.variableName;
|
||||||
|
const processVariables = this.field?.form?.processVariables;
|
||||||
|
const formVariables = this.field?.form?.variables;
|
||||||
|
|
||||||
|
const dropdownOptions = this.getOptionsFromVariable(processVariables, formVariables, variableName);
|
||||||
|
|
||||||
|
if (dropdownOptions) {
|
||||||
|
const formVariableOptions: FormFieldOption[] = this.getOptionsFromPath(dropdownOptions, optionsPath);
|
||||||
|
this.field.options = formVariableOptions;
|
||||||
|
this.resetInvalidValue();
|
||||||
|
this.field.updateForm();
|
||||||
|
} else {
|
||||||
|
this.handleError(`${variableName} not found`);
|
||||||
|
this.resetOptions();
|
||||||
|
this.variableOptionsFailed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getOptionsFromPath(data: any, path: string): FormFieldOption[] {
|
||||||
|
const optionsId = this.field?.variableConfig?.optionsId ?? this.defaultVariableOptionId;
|
||||||
|
const optionsLabel = this.field?.variableConfig?.optionsLabel ?? this.defaultVariableOptionLabel;
|
||||||
|
|
||||||
|
const properties = path.split('.');
|
||||||
|
const currentProperty = properties.shift();
|
||||||
|
|
||||||
|
if (!data.hasOwnProperty(currentProperty)) {
|
||||||
|
this.handleError(`${currentProperty} not found in ${JSON.stringify(data)}`);
|
||||||
|
this.variableOptionsFailed = true;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const nestedData = data[currentProperty];
|
||||||
|
|
||||||
|
if (Array.isArray(nestedData)) {
|
||||||
|
return this.getOptionsFromArray(nestedData, optionsId, optionsLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getOptionsFromPath(nestedData, properties.join('.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private getOptionsFromArray(nestedData: any[], id: string, label: string): FormFieldOption[] {
|
||||||
|
const options = nestedData.map(item => this.createOption(item, id, label));
|
||||||
|
const hasInvalidOption = options.some(option => !option);
|
||||||
|
|
||||||
|
if (hasInvalidOption) {
|
||||||
|
this.variableOptionsFailed = true;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.variableOptionsFailed = false;
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
private createOption(item: any, id: string, label: string): FormFieldOption {
|
||||||
|
const option: FormFieldOption = {
|
||||||
|
id: item[id],
|
||||||
|
name: item[label]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!option.id || !option.name) {
|
||||||
|
this.handleError(`'id' or 'label' is not properly defined`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getOptionsFromVariable(processVariables: TaskVariableCloud[], formVariables: TaskVariableCloud[], variableName: string): TaskVariableCloud {
|
||||||
|
const processVariableDropdownOptions: TaskVariableCloud = this.getVariableValueByName(processVariables, variableName);
|
||||||
|
const formVariableDropdownOptions: TaskVariableCloud = this.getVariableValueByName(formVariables, variableName);
|
||||||
|
|
||||||
|
return processVariableDropdownOptions ?? formVariableDropdownOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getVariableValueByName(variables: TaskVariableCloud[], variableName: string): any {
|
||||||
|
return variables?.find((variable: TaskVariableCloud) => variable?.name === `variables.${variableName}` || variable?.name === variableName)?.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isVariableOptionType(): boolean {
|
||||||
|
return this.field?.optionType === 'variable';
|
||||||
|
}
|
||||||
|
|
||||||
private persistFieldOptionsFromRestApi() {
|
private persistFieldOptionsFromRestApi() {
|
||||||
if (this.isValidRestType()) {
|
if (this.isValidRestType()) {
|
||||||
this.resetRestApiErrorMessage();
|
this.resetRestApiErrorMessage();
|
||||||
@@ -125,6 +219,15 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
private loadFieldOptionsForLinkedWidget() {
|
private loadFieldOptionsForLinkedWidget() {
|
||||||
const parentWidgetValue = this.getParentWidgetValue();
|
const parentWidgetValue = this.getParentWidgetValue();
|
||||||
this.parentValueChanged(parentWidgetValue);
|
this.parentValueChanged(parentWidgetValue);
|
||||||
|
|
||||||
|
this.formService.formFieldValueChanged
|
||||||
|
.pipe(
|
||||||
|
filter((event: FormFieldEvent) => this.isFormFieldEventOfTypeDropdown(event) && this.isParentFormFieldEvent(event)),
|
||||||
|
takeUntil(this.onDestroy$))
|
||||||
|
.subscribe((event: FormFieldEvent) => {
|
||||||
|
const valueOfParentWidget = event.field.value;
|
||||||
|
this.parentValueChanged(valueOfParentWidget);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getParentWidgetValue(): string {
|
private getParentWidgetValue(): string {
|
||||||
@@ -317,7 +420,10 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
}
|
}
|
||||||
|
|
||||||
showRequiredMessage(): boolean {
|
showRequiredMessage(): boolean {
|
||||||
return (this.isInvalidFieldRequired() || (this.isNoneValueSelected(this.field.value) && this.isRequired())) && this.isTouched() && !this.isRestApiFailed;
|
return (this.isInvalidFieldRequired() || (this.isNoneValueSelected(this.field.value) && this.isRequired())) &&
|
||||||
|
this.isTouched() &&
|
||||||
|
!this.isRestApiFailed &&
|
||||||
|
!this.variableOptionsFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultOption(options: FormFieldOption[]): FormFieldOption {
|
getDefaultOption(options: FormFieldOption[]): FormFieldOption {
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { FormFieldOption } from '@alfresco/adf-core';
|
import { FormFieldOption } from '@alfresco/adf-core';
|
||||||
|
import { TaskVariableCloud } from '../models/task-variable-cloud.model';
|
||||||
|
|
||||||
export const mockConditionalEntries = [
|
export const mockConditionalEntries = [
|
||||||
{
|
{
|
||||||
@@ -103,3 +104,79 @@ export const filterOptionList = [
|
|||||||
{ id: 'opt_5', name: 'option_5' },
|
{ id: 'opt_5', name: 'option_5' },
|
||||||
{ id: 'opt_6', name: 'option_6' }
|
{ id: 'opt_6', name: 'option_6' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const mockPlayersResponse = {
|
||||||
|
response: {
|
||||||
|
people: {
|
||||||
|
players:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
playerId: 'player-1',
|
||||||
|
playerFullName: 'Lionel Messi',
|
||||||
|
totalGoals: 999,
|
||||||
|
shirtNumber: 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
playerId: 'player-2',
|
||||||
|
playerFullName: 'Cristiano Ronaldo',
|
||||||
|
totalGoals: 15,
|
||||||
|
shirtNumber: 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
playerId: 'player-3',
|
||||||
|
playerFullName: 'Robert Lewandowski',
|
||||||
|
totalGoals: 500,
|
||||||
|
shirtNumber: 9
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockDefaultResponse = {
|
||||||
|
data:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
id: 'default-pet-1',
|
||||||
|
name: 'Dog'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'default-pet-2',
|
||||||
|
name: 'Cat'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'default-pet-3',
|
||||||
|
name: 'Parrot'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockCountriesResponse = {
|
||||||
|
countries: [
|
||||||
|
{
|
||||||
|
id: 'PL',
|
||||||
|
name: 'Poland'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'UK',
|
||||||
|
name: 'United Kingdom'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'GR',
|
||||||
|
name: 'Greece'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mockFormVariableWithJson = [
|
||||||
|
new TaskVariableCloud({ name: 'json-form-variable', value: mockCountriesResponse, type: 'json', id: 'fake-id-1' })
|
||||||
|
];
|
||||||
|
|
||||||
|
export const mockProcessVariablesWithJson = [
|
||||||
|
new TaskVariableCloud({ name: 'variables.json-variable', value: mockPlayersResponse, type: 'json', id: 'fake-id-1' }),
|
||||||
|
new TaskVariableCloud({ name: 'variables.different-variable', value: 'fake-value', type: 'json', id: 'fake-id-2' })
|
||||||
|
];
|
||||||
|
|
||||||
|
export const mockVariablesWithDefaultJson = [
|
||||||
|
new TaskVariableCloud({ name: 'variables.json-default-variable', value: mockDefaultResponse, type: 'json', id: 'fake-id-1' })
|
||||||
|
];
|
||||||
|
Reference in New Issue
Block a user