mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-6025] - Resolve linked dropdowns during runtime (#7289)
* Resolve linked dropdown during runtime, Draft commit * Remove app from appconfig * Make the link work for Saved and Completed tasks * Call the new API to fetch dropdown options in case of rest type * When widgetId is missing from restUrl * Update unit tests * Declare default option * Rebase, remove appName example * Maurizify the PR * Fix lint error Co-authored-by: Ardit Domi <arditdomi@apl-c02g64vpmd6t.home>
This commit is contained in:
28
lib/core/form/components/widgets/core/form-field-rule.ts
Normal file
28
lib/core/form/components/widgets/core/form-field-rule.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { FormFieldOption } from './form-field-option';
|
||||||
|
|
||||||
|
export interface FormFieldRule {
|
||||||
|
ruleOn: string;
|
||||||
|
entries: RuleEntry[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RuleEntry {
|
||||||
|
key: string;
|
||||||
|
options: FormFieldOption[];
|
||||||
|
}
|
@@ -26,6 +26,7 @@ import { FormFieldTypes } from './form-field-types';
|
|||||||
import { NumberFieldValidator } from './form-field-validator';
|
import { NumberFieldValidator } from './form-field-validator';
|
||||||
import { FormWidgetModel } from './form-widget.model';
|
import { FormWidgetModel } from './form-widget.model';
|
||||||
import { FormModel } from './form.model';
|
import { FormModel } from './form.model';
|
||||||
|
import { FormFieldRule } from './form-field-rule';
|
||||||
|
|
||||||
// Maps to FormFieldRepresentation
|
// Maps to FormFieldRepresentation
|
||||||
export class FormFieldModel extends FormWidgetModel {
|
export class FormFieldModel extends FormWidgetModel {
|
||||||
@@ -72,6 +73,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
currency: string = null;
|
currency: string = null;
|
||||||
dateDisplayFormat: string = this.defaultDateFormat;
|
dateDisplayFormat: string = this.defaultDateFormat;
|
||||||
selectionType: 'single' | 'multiple' = null;
|
selectionType: 'single' | 'multiple' = null;
|
||||||
|
rule?: FormFieldRule;
|
||||||
|
|
||||||
// container model members
|
// container model members
|
||||||
numberOfColumns: number = 1;
|
numberOfColumns: number = 1;
|
||||||
@@ -178,6 +180,7 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
this.validationSummary = new ErrorMessageModel();
|
this.validationSummary = new ErrorMessageModel();
|
||||||
this.tooltip = json.tooltip;
|
this.tooltip = json.tooltip;
|
||||||
this.selectionType = json.selectionType;
|
this.selectionType = json.selectionType;
|
||||||
|
this.rule = json.rule;
|
||||||
|
|
||||||
if (json.placeholder && json.placeholder !== '' && json.placeholder !== 'null') {
|
if (json.placeholder && json.placeholder !== '' && json.placeholder !== 'null') {
|
||||||
this.placeholder = json.placeholder;
|
this.placeholder = json.placeholder;
|
||||||
|
@@ -40,3 +40,4 @@ export * from './form-variable.model';
|
|||||||
export * from './process-variable.model';
|
export * from './process-variable.model';
|
||||||
export * from './upload-widget-content-link.model';
|
export * from './upload-widget-content-link.model';
|
||||||
export * from './form-field-file-source';
|
export * from './form-field-file-source';
|
||||||
|
export * from './form-field-rule';
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
"UPLOAD": "UPLOAD",
|
"UPLOAD": "UPLOAD",
|
||||||
"REQUIRED": "*Required",
|
"REQUIRED": "*Required",
|
||||||
"FILE_NAME": "File Name",
|
"FILE_NAME": "File Name",
|
||||||
|
"DEPENDS_ON": "Depends on: {{widgetId}}",
|
||||||
"NO_FILE_ATTACHED" : "No file attached",
|
"NO_FILE_ATTACHED" : "No file attached",
|
||||||
"VALIDATOR": {
|
"VALIDATOR": {
|
||||||
"INVALID_NUMBER": "Use a different number format",
|
"INVALID_NUMBER": "Use a different number format",
|
||||||
|
@@ -1,13 +1,21 @@
|
|||||||
<div class="adf-dropdown-widget {{field.className}}"
|
<div class="adf-dropdown-widget {{field.className}}"
|
||||||
[class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly">
|
[class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly">
|
||||||
<label class="adf-label" [attr.for]="field.id">{{field.name | translate }}<span *ngIf="isRequired()">*</span></label>
|
<div class="adf-dropdown-widget-top-labels">
|
||||||
|
<label class="adf-label" [attr.for]="field.id">{{field.name | translate }}<span
|
||||||
|
*ngIf="isRequired()">*</span></label>
|
||||||
|
<label class="adf-label adf-dropdown-widget-linked"
|
||||||
|
*ngIf="isLinkedWidget()"
|
||||||
|
[attr.for]="field.id">
|
||||||
|
{{ 'FORM.FIELD.DEPENDS_ON' | translate: { widgetId: getLinkedWidgetId() } }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-select class="adf-select"
|
<mat-select class="adf-select"
|
||||||
[id]="field.id"
|
[id]="field.id"
|
||||||
[(ngModel)]="field.value"
|
[(ngModel)]="field.value"
|
||||||
[disabled]="field.readOnly"
|
[disabled]="field.readOnly"
|
||||||
[compareWith]="compareDropdownValues"
|
[compareWith]="compareDropdownValues"
|
||||||
(ngModelChange)="onFieldChanged(field)"
|
(ngModelChange)="selectionChangedForField(field)"
|
||||||
[matTooltip]="field.tooltip"
|
[matTooltip]="field.tooltip"
|
||||||
matTooltipPosition="above"
|
matTooltipPosition="above"
|
||||||
matTooltipShowDelay="1000"
|
matTooltipShowDelay="1000"
|
||||||
|
@@ -12,6 +12,17 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-top-labels {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 16px;
|
||||||
|
|
||||||
|
.adf-dropdown-widget-linked {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&-select {
|
&-select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ import {
|
|||||||
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';
|
||||||
|
import { mockConditionalEntries, mockRestDropdownOptions } from '../../../mocks/linked-dropdown.mock';
|
||||||
|
|
||||||
describe('DropdownCloudWidgetComponent', () => {
|
describe('DropdownCloudWidgetComponent', () => {
|
||||||
|
|
||||||
@@ -253,44 +254,6 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should map properties if restResponsePath is set', (done) => {
|
|
||||||
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
|
||||||
id: 'dropdown-id',
|
|
||||||
name: 'date-name',
|
|
||||||
type: 'dropdown-cloud',
|
|
||||||
readOnly: 'false',
|
|
||||||
restUrl: 'fake-rest-url',
|
|
||||||
optionType: 'rest',
|
|
||||||
restResponsePath: 'path'
|
|
||||||
});
|
|
||||||
|
|
||||||
const dropdownSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of( [
|
|
||||||
{ id: 'opt_1', name: 'option_1' },
|
|
||||||
{ id: 'opt_2', name: 'option_2' },
|
|
||||||
{ id: 'opt_3', name: 'option_3' }]
|
|
||||||
));
|
|
||||||
|
|
||||||
widget.ngOnInit();
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
openSelect('#dropdown-id');
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
expect(dropdownSpy).toHaveBeenCalled();
|
|
||||||
|
|
||||||
const optOne: any = fixture.debugElement.queryAll(By.css('[id="opt_1"]'));
|
|
||||||
expect(optOne[0].context.value).toBe('opt_1');
|
|
||||||
expect(optOne[0].context.viewValue).toBe('option_1');
|
|
||||||
const optTwo: any = fixture.debugElement.queryAll(By.css('[id="opt_2"]'));
|
|
||||||
expect(optTwo[0].context.value).toBe('opt_2');
|
|
||||||
expect(optTwo[0].context.viewValue).toBe('option_2');
|
|
||||||
const optThree: any = fixture.debugElement.queryAll(By.css('[id="opt_3"]'));
|
|
||||||
expect(optThree[0].context.value).toBe('opt_3');
|
|
||||||
expect(optThree[0].context.viewValue).toBe('option_3');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -349,4 +312,174 @@ describe('DropdownCloudWidgetComponent', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Linked Dropdown', () => {
|
||||||
|
|
||||||
|
describe('Rest URL options', () => {
|
||||||
|
|
||||||
|
const parentDropdown = new FormFieldModel(new FormModel(), { id: 'parentDropdown', type: 'dropdown' });
|
||||||
|
beforeEach(() => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
|
id: 'child-dropdown-id',
|
||||||
|
name: 'child-dropdown',
|
||||||
|
type: 'dropdown-cloud',
|
||||||
|
readOnly: 'false',
|
||||||
|
optionType: 'rest',
|
||||||
|
restUrl: 'myFakeDomain.com/cities?country=${parentDropdown}',
|
||||||
|
rule: {
|
||||||
|
ruleOn: 'parentDropdown',
|
||||||
|
entries: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
widget.field.form.id = 'fake-form-id';
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fetch the options from a rest url for a linked dropdown', async () => {
|
||||||
|
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(mockRestDropdownOptions));
|
||||||
|
const mockParentDropdown = { id: 'parentDropdown', value: 'mock-value' };
|
||||||
|
spyOn(widget.field.form, 'getFormFields').and.returnValue([mockParentDropdown]);
|
||||||
|
parentDropdown.value = 'UK';
|
||||||
|
widget.selectionChangedForField(parentDropdown);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
openSelect('child-dropdown-id');
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const optOne: any = fixture.debugElement.query(By.css('[id="LO"]'));
|
||||||
|
const optTwo: any = fixture.debugElement.query(By.css('[id="MA"]'));
|
||||||
|
|
||||||
|
expect(jsonDataSpy).toHaveBeenCalledWith('fake-form-id', 'child-dropdown-id', { parentDropdown: 'mock-value' });
|
||||||
|
expect(optOne.context.value).toBe('LO');
|
||||||
|
expect(optOne.context.viewValue).toBe('LONDON');
|
||||||
|
expect(optTwo.context.value).toBe('MA');
|
||||||
|
expect(optTwo.context.viewValue).toBe('MANCHESTER');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset the options for a linked dropdown with restUrl when the parent dropdown selection changes to empty', async () => {
|
||||||
|
widget.field.options = mockConditionalEntries[1].options;
|
||||||
|
parentDropdown.value = 'empty';
|
||||||
|
widget.selectionChangedForField(parentDropdown);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
openSelect('child-dropdown-id');
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const defaultOption: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
||||||
|
|
||||||
|
expect(widget.field.options).toEqual([{ 'id': 'empty', 'name': 'Choose one...' }]);
|
||||||
|
expect(defaultOption.context.value).toBe('empty');
|
||||||
|
expect(defaultOption.context.viewValue).toBe('Choose one...');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Manual options', () => {
|
||||||
|
const parentDropdown = new FormFieldModel(new FormModel(), { id: 'parentDropdown', type: 'dropdown' });
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
|
id: 'child-dropdown-id',
|
||||||
|
name: 'child-dropdown',
|
||||||
|
type: 'dropdown-cloud',
|
||||||
|
readOnly: 'false',
|
||||||
|
optionType: 'manual',
|
||||||
|
rule: {
|
||||||
|
ruleOn: 'parentDropdown',
|
||||||
|
entries: mockConditionalEntries
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should display the options for a linked dropdown based on the parent dropdown selection', async () => {
|
||||||
|
parentDropdown.value = 'GR';
|
||||||
|
widget.selectionChangedForField(parentDropdown);
|
||||||
|
fixture.detectChanges();
|
||||||
|
openSelect('child-dropdown-id');
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const optOne: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
||||||
|
const optTwo: any = fixture.debugElement.query(By.css('[id="ATH"]'));
|
||||||
|
const optThree: any = fixture.debugElement.query(By.css('[id="SKG"]'));
|
||||||
|
|
||||||
|
expect(widget.field.options).toEqual(mockConditionalEntries[0].options);
|
||||||
|
expect(optOne.context.value).toBe('empty');
|
||||||
|
expect(optOne.context.viewValue).toBe('Choose one...');
|
||||||
|
expect(optTwo.context.value).toBe('ATH');
|
||||||
|
expect(optTwo.context.viewValue).toBe('Athens');
|
||||||
|
expect(optThree.context.value).toBe('SKG');
|
||||||
|
expect(optThree.context.viewValue).toBe('Thessaloniki');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset the options for a linked dropdown when the parent dropdown selection changes to empty', async () => {
|
||||||
|
widget.field.options = mockConditionalEntries[1].options;
|
||||||
|
parentDropdown.value = 'empty';
|
||||||
|
widget.selectionChangedForField(parentDropdown);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
openSelect('child-dropdown-id');
|
||||||
|
fixture.detectChanges();
|
||||||
|
await fixture.whenStable();
|
||||||
|
|
||||||
|
const defaultOption: any = fixture.debugElement.query(By.css('[id="empty"]'));
|
||||||
|
|
||||||
|
expect(widget.field.options).toEqual([{ 'id': 'empty', 'name': 'Choose one...' }]);
|
||||||
|
expect(defaultOption.context.value).toBe('empty');
|
||||||
|
expect(defaultOption.context.viewValue).toBe('Choose one...');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Load selection for linked dropdown (i.e. saved, completed forms)', () => {
|
||||||
|
|
||||||
|
it('should load the selection of a manual type linked dropdown', () => {
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
|
id: 'child-dropdown-id',
|
||||||
|
name: 'child-dropdown',
|
||||||
|
type: 'dropdown-cloud',
|
||||||
|
readOnly: 'false',
|
||||||
|
optionType: 'manual',
|
||||||
|
rule: {
|
||||||
|
ruleOn: 'parentDropdown',
|
||||||
|
entries: mockConditionalEntries
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const updateFormSpy = spyOn(widget.field, 'updateForm');
|
||||||
|
const mockParentDropdown = { id: 'parentDropdown', value: 'IT' };
|
||||||
|
spyOn(widget.field.form, 'getFormFields').and.returnValue([mockParentDropdown]);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(updateFormSpy).toHaveBeenCalled();
|
||||||
|
expect(widget.field.options).toEqual(mockConditionalEntries[1].options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should load the selection of a rest type linked dropdown', () => {
|
||||||
|
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(mockRestDropdownOptions));
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
|
id: 'child-dropdown-id',
|
||||||
|
name: 'child-dropdown',
|
||||||
|
type: 'dropdown-cloud',
|
||||||
|
readOnly: 'false',
|
||||||
|
restUrl: 'mock-url.com/country=${country}',
|
||||||
|
optionType: 'rest',
|
||||||
|
rule: {
|
||||||
|
ruleOn: 'country',
|
||||||
|
entries: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
widget.field.form.id = 'fake-form-id';
|
||||||
|
const updateFormSpy = spyOn(widget.field, 'updateForm');
|
||||||
|
const mockParentDropdown = { id: 'country', value: 'UK' };
|
||||||
|
spyOn(widget.field.form, 'getFormFields').and.returnValue([mockParentDropdown]);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(updateFormSpy).toHaveBeenCalled();
|
||||||
|
expect(jsonDataSpy).toHaveBeenCalledWith('fake-form-id', 'child-dropdown-id', { country: 'UK' });
|
||||||
|
expect(widget.field.options).toEqual(mockRestDropdownOptions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -16,10 +16,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core';
|
import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core';
|
||||||
import { WidgetComponent, FormService, LogService, FormFieldOption } from '@alfresco/adf-core';
|
import {
|
||||||
|
WidgetComponent,
|
||||||
|
FormService,
|
||||||
|
LogService,
|
||||||
|
FormFieldOption,
|
||||||
|
FormFieldEvent,
|
||||||
|
FormFieldModel,
|
||||||
|
FormFieldTypes,
|
||||||
|
RuleEntry
|
||||||
|
} from '@alfresco/adf-core';
|
||||||
import { FormCloudService } from '../../../services/form-cloud.service';
|
import { FormCloudService } from '../../../services/form-cloud.service';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { filter, takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
/* tslint:disable:component-selector */
|
/* tslint:disable:component-selector */
|
||||||
|
|
||||||
@@ -41,6 +50,10 @@ import { takeUntil } from 'rxjs/operators';
|
|||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class DropdownCloudWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
export class DropdownCloudWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
||||||
|
static DEFAULT_OPTION = {
|
||||||
|
id: 'empty',
|
||||||
|
name: 'Choose one...'
|
||||||
|
};
|
||||||
|
|
||||||
typeId = 'DropdownCloudWidgetComponent';
|
typeId = 'DropdownCloudWidgetComponent';
|
||||||
protected onDestroy$ = new Subject<boolean>();
|
protected onDestroy$ = new Subject<boolean>();
|
||||||
@@ -52,14 +65,28 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.field && this.field.restUrl) {
|
if (this.hasRestUrl() && !this.isLinkedWidget()) {
|
||||||
this.getValuesFromRestApi();
|
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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getValuesFromRestApi() {
|
private persistFieldOptionsFromRestApi() {
|
||||||
if (this.isValidRestType()) {
|
if (this.isValidRestType()) {
|
||||||
this.formCloudService.getRestWidgetData(this.field.form.id, this.field.id)
|
const bodyParam = this.buildBodyParam();
|
||||||
|
this.formCloudService.getRestWidgetData(this.field.form.id, this.field.id, bodyParam)
|
||||||
.pipe(takeUntil(this.onDestroy$))
|
.pipe(takeUntil(this.onDestroy$))
|
||||||
.subscribe((result: FormFieldOption[]) => {
|
.subscribe((result: FormFieldOption[]) => {
|
||||||
this.field.options = result;
|
this.field.options = result;
|
||||||
@@ -67,6 +94,97 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildBodyParam(): any {
|
||||||
|
const bodyParam = Object.assign({});
|
||||||
|
if (this.isLinkedWidget()) {
|
||||||
|
const parentWidgetValue = this.getParentWidgetValue();
|
||||||
|
const parentWidgetId = this.getLinkedWidgetId();
|
||||||
|
bodyParam[parentWidgetId] = parentWidgetValue;
|
||||||
|
}
|
||||||
|
return bodyParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadFieldOptionsForLinkedWidget() {
|
||||||
|
const parentWidgetValue = this.getParentWidgetValue();
|
||||||
|
this.parentValueChanged(parentWidgetValue);
|
||||||
|
this.field.updateForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
private getParentWidgetValue(): string {
|
||||||
|
const parentWidgetId = this.getLinkedWidgetId();
|
||||||
|
const parentWidget = this.getFormFieldById(parentWidgetId);
|
||||||
|
return parentWidget?.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private parentValueChanged(value: string) {
|
||||||
|
if (this.isValidValue(value)) {
|
||||||
|
this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value);
|
||||||
|
} else if (this.isDefaultValue(value)) {
|
||||||
|
this.addDefaultOption();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isValidValue(value: string): boolean {
|
||||||
|
return !!value && value !== DropdownCloudWidgetComponent.DEFAULT_OPTION.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isDefaultValue(value: string): boolean {
|
||||||
|
return value === DropdownCloudWidgetComponent.DEFAULT_OPTION.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getFormFieldById(fieldId): FormFieldModel {
|
||||||
|
return this.field.form.getFormFields().filter((field: FormFieldModel) => field.id === fieldId)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private persistFieldOptionsFromManualList(value: string) {
|
||||||
|
if (this.hasRuleEntries()) {
|
||||||
|
const rulesEntries = this.getRuleEntries();
|
||||||
|
rulesEntries.forEach((ruleEntry: RuleEntry) => {
|
||||||
|
if (ruleEntry.key === value) {
|
||||||
|
this.field.options = ruleEntry.options;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getRuleEntries(): RuleEntry[] {
|
||||||
|
return this.field.rule.entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private hasRuleEntries(): boolean {
|
||||||
|
return !!this.getRuleEntries().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private addDefaultOption() {
|
||||||
|
this.field.options = [DropdownCloudWidgetComponent.DEFAULT_OPTION];
|
||||||
|
}
|
||||||
|
|
||||||
|
selectionChangedForField(field: FormFieldModel) {
|
||||||
|
const formFieldValueChangedEvent = new FormFieldEvent(field.form, field);
|
||||||
|
this.formService.formFieldValueChanged.next(formFieldValueChangedEvent);
|
||||||
|
this.onFieldChanged(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
private isParentFormFieldEvent(event: FormFieldEvent): boolean {
|
||||||
|
return event.field.id === this.getLinkedWidgetId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private isFormFieldEventOfTypeDropdown(event: FormFieldEvent): boolean {
|
||||||
|
return event.field.type === FormFieldTypes.DROPDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private hasRestUrl(): boolean {
|
||||||
|
return !!this.field?.restUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
isLinkedWidget(): boolean {
|
||||||
|
return !!this.getLinkedWidgetId();
|
||||||
|
}
|
||||||
|
|
||||||
|
getLinkedWidgetId(): string {
|
||||||
|
return this.field?.rule?.ruleOn;
|
||||||
|
}
|
||||||
|
|
||||||
compareDropdownValues(opt1: FormFieldOption | string, opt2: FormFieldOption | string): boolean {
|
compareDropdownValues(opt1: FormFieldOption | string, opt2: FormFieldOption | string): boolean {
|
||||||
if (!opt1 || !opt2) {
|
if (!opt1 || !opt2) {
|
||||||
return false;
|
return false;
|
||||||
@@ -93,7 +211,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
}
|
}
|
||||||
|
|
||||||
let optionValue: string = '';
|
let optionValue: string = '';
|
||||||
if (option.id === 'empty' || option.name !== fieldValue) {
|
if (option.id === DropdownCloudWidgetComponent.DEFAULT_OPTION.id || option.name !== fieldValue) {
|
||||||
optionValue = option.id;
|
optionValue = option.id;
|
||||||
} else {
|
} else {
|
||||||
optionValue = option.name;
|
optionValue = option.name;
|
||||||
@@ -101,11 +219,11 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
|||||||
return optionValue;
|
return optionValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
isValidRestType(): boolean {
|
private isValidRestType(): boolean {
|
||||||
return this.field.optionType === 'rest' && !!this.field.restUrl;
|
return this.field.optionType === 'rest' && !!this.field.restUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleError(error: any) {
|
private handleError(error: any) {
|
||||||
this.logService.error(error);
|
this.logService.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,85 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { FormFieldOption } from '@alfresco/adf-core';
|
||||||
|
|
||||||
|
export const mockConditionalEntries = [
|
||||||
|
{
|
||||||
|
key: 'GR',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
id: 'empty',
|
||||||
|
name: 'Choose one...'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ATH',
|
||||||
|
name: 'Athens'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SKG',
|
||||||
|
name: 'Thessaloniki'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'IT',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
id: 'empty',
|
||||||
|
name: 'Choose one...'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'MI',
|
||||||
|
name: 'MILAN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'RM',
|
||||||
|
name: 'ROME'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'UK',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
id: 'empty',
|
||||||
|
name: 'Choose one...'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'LDN',
|
||||||
|
name: 'London'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'MAN',
|
||||||
|
name: 'Manchester'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'SHE',
|
||||||
|
name: 'Sheffield'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'LEE',
|
||||||
|
name: 'Leeds'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const mockRestDropdownOptions: FormFieldOption[] = [
|
||||||
|
{ id: 'LO', name: 'LONDON' },
|
||||||
|
{ id: 'MA', name: 'MANCHESTER' }
|
||||||
|
];
|
Reference in New Issue
Block a user