From 7481001461918f7d76c1949a9593feb83863401a Mon Sep 17 00:00:00 2001 From: Vito Date: Fri, 29 Oct 2021 14:55:51 +0100 Subject: [PATCH] [AAE-6093] - fixed rest option for cloud widget (#7304) * [AAE-6093] - fixed rest option for cloud widget * [AAE-6093] - reverted app config change * [AAE-6093] - fixed naming * [AAE-6093] - fixed radio button complete task and added support for rest url with the new feature * [AAE-6093] - removed test value * [AAE-6093] - fixed lint * [AAE-6093] - fixed lint * [AAE-6093] - merged fix for dropdown --- .../widgets/core/form-field.model.spec.ts | 92 +++++++++ .../widgets/core/form-field.model.ts | 23 ++- .../cloud-form-rendering.service.ts | 4 +- .../dropdown/dropdown-cloud.widget.spec.ts | 105 +---------- .../widgets/dropdown/dropdown-cloud.widget.ts | 17 +- .../radio-buttons-cloud.widget.html | 23 +++ .../radio-buttons-cloud.widget.scss | 20 ++ .../radio-buttons-cloud.widget.spec.ts | 177 ++++++++++++++++++ .../radio-buttons-cloud.widget.ts | 78 ++++++++ .../src/lib/form/form-cloud.module.ts | 3 + .../services/form-cloud.service.interface.ts | 4 +- .../lib/form/services/form-cloud.service.ts | 14 +- 12 files changed, 431 insertions(+), 129 deletions(-) create mode 100644 lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html create mode 100644 lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss create mode 100644 lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts create mode 100644 lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts diff --git a/lib/core/form/components/widgets/core/form-field.model.spec.ts b/lib/core/form/components/widgets/core/form-field.model.spec.ts index 3a3c9da89c9..8b28bb8b7fd 100644 --- a/lib/core/form/components/widgets/core/form-field.model.spec.ts +++ b/lib/core/form/components/widgets/core/form-field.model.spec.ts @@ -691,6 +691,98 @@ describe('FormFieldModel', () => { expect(form.values['dropdown_field'].name).toEqual('Option 1'); }); + it('dropdown field type should be formatted on rest properties', () => { + const form = new FormModel(); + const field = new FormFieldModel(form, { + fieldType: 'HeaderFieldtype', + id: 'dropdown_field', + name: 'header', + type: FormFieldTypes.DROPDOWN, + value: 'opt1', + required: false, + readOnly: true, + restUrl: 'fake-url-just-to-show', + optionType: 'rest', + restIdProperty: 'fake-id-property', + restLabelProperty: 'fake-label-property', + options: [ + {id: 'opt1', name: 'Option 1'}, + {id: 'opt2', name: 'Option 2'} + ] + }); + field.updateForm(); + expect(form.values['dropdown_field']['fake-id-property']).toEqual('opt1'); + expect(form.values['dropdown_field']['fake-label-property']).toEqual('Option 1'); + }); + + it('dropdown field type should be formatted on id and name properties if rest properties are not set', () => { + const form = new FormModel(); + const field = new FormFieldModel(form, { + fieldType: 'HeaderFieldtype', + id: 'dropdown_field', + name: 'header', + type: FormFieldTypes.DROPDOWN, + value: 'opt1', + required: false, + readOnly: true, + restUrl: 'fake-url-just-to-show', + optionType: 'rest', + options: [ + {id: 'opt1', name: 'Option 1'}, + {id: 'opt2', name: 'Option 2'} + ] + }); + field.updateForm(); + expect(form.values['dropdown_field']['id']).toEqual('opt1'); + expect(form.values['dropdown_field']['name']).toEqual('Option 1'); + }); + + it('radio button field rest type should appear with its configured label and id into the rest values', () => { + const form = new FormModel(); + const field = new FormFieldModel(form, { + fieldType: 'HeaderFieldtype', + id: 'radio_bananan_field', + name: 'banana', + type: FormFieldTypes.RADIO_BUTTONS, + value: 'opt1', + required: false, + readOnly: true, + restUrl: '', + restIdProperty: 'banana', + restLabelProperty: 'banLabel', + optionType: 'rest', + options: [ + {id: 'opt1', name: 'Option 1'}, + {id: 'opt2', name: 'Option 2'} + ] + }); + field.updateForm(); + expect(form.values['radio_bananan_field']['banana']).toEqual('opt1'); + expect(form.values['radio_bananan_field']['banLabel']).toEqual('Option 1'); + }); + + it('radio button field rest type should appear with id / name properties when rest properties are not configured', () => { + const form = new FormModel(); + const field = new FormFieldModel(form, { + fieldType: 'HeaderFieldtype', + id: 'radio_bananan_field', + name: 'banana', + type: FormFieldTypes.RADIO_BUTTONS, + value: 'opt1', + required: false, + readOnly: true, + restUrl: '', + optionType: 'rest', + options: [ + {id: 'opt1', name: 'Option 1'}, + {id: 'opt2', name: 'Option 2'} + ] + }); + field.updateForm(); + expect(form.values['radio_bananan_field']['id']).toEqual('opt1'); + expect(form.values['radio_bananan_field']['name']).toEqual('Option 1'); + }); + it('should parse and resolve people null value as null', () => { const field = new FormFieldModel(new FormModel(), { type: FormFieldTypes.PEOPLE, diff --git a/lib/core/form/components/widgets/core/form-field.model.ts b/lib/core/form/components/widgets/core/form-field.model.ts index f15c6113fe6..2a5dea5caed 100644 --- a/lib/core/form/components/widgets/core/form-field.model.ts +++ b/lib/core/form/components/widgets/core/form-field.model.ts @@ -62,7 +62,7 @@ export class FormFieldModel extends FormWidgetModel { restLabelProperty: string; hasEmptyValue: boolean; className: string; - optionType: string; + optionType: 'rest' | 'manual' ; params: FormFieldMetadata = {}; hyperlinkUrl: string; displayText: string; @@ -372,18 +372,14 @@ export class FormFieldModel extends FormWidgetModel { const entry: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value); if (entry.length > 0) { - this.form.values[this.id] = entry[0]; + this.setFormFieldValueOption(entry[0]); } } break; case FormFieldTypes.RADIO_BUTTONS: - /* - This is needed due to Activiti issue related to reading radio button values as value string - but saving back as object: { id: , name: } - */ const radioButton: FormFieldOption[] = this.options.filter((opt) => opt.id === this.value); if (radioButton.length > 0) { - this.form.values[this.id] = radioButton[0]; + this.setFormFieldValueOption(radioButton[0]); } break; case FormFieldTypes.UPLOAD: @@ -491,4 +487,17 @@ export class FormFieldModel extends FormWidgetModel { json.type === FormFieldTypes.BOOLEAN; } + private setFormFieldValueOption(option: FormFieldOption ) { + if (this.optionType === 'rest' && !!this.restUrl) { + const restEntry = {}; + const restIdProperty = this.restIdProperty || 'id'; + const restLabelProperty = this.restLabelProperty || 'name'; + restEntry[restIdProperty] = option.id; + restEntry[restLabelProperty] = option.name; + this.form.values[this.id] = restEntry; + } else { + this.form.values[this.id] = option; + } + } + } diff --git a/lib/process-services-cloud/src/lib/form/components/cloud-form-rendering.service.ts b/lib/process-services-cloud/src/lib/form/components/cloud-form-rendering.service.ts index 4002c80c263..d282fa79050 100644 --- a/lib/process-services-cloud/src/lib/form/components/cloud-form-rendering.service.ts +++ b/lib/process-services-cloud/src/lib/form/components/cloud-form-rendering.service.ts @@ -23,6 +23,7 @@ import { DateCloudWidgetComponent } from './widgets/date/date-cloud.widget'; import { PeopleCloudWidgetComponent } from './widgets/people/people-cloud.widget'; import { GroupCloudWidgetComponent } from './widgets/group/group-cloud.widget'; import { PropertiesViewerWidgetComponent } from './widgets/properties-viewer/properties-viewer.widget'; +import { RadioButtonsCloudWidgetComponent } from './widgets/radio-buttons/radio-buttons-cloud.widget'; @Injectable({ providedIn: 'root' @@ -37,7 +38,8 @@ export class CloudFormRenderingService extends FormRenderingService { 'date': () => DateCloudWidgetComponent, 'people': () => PeopleCloudWidgetComponent, 'functional-group': () => GroupCloudWidgetComponent, - 'properties-viewer': () => PropertiesViewerWidgetComponent + 'properties-viewer': () => PropertiesViewerWidgetComponent, + 'radio-buttons': () => RadioButtonsCloudWidgetComponent }, true); } } diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts index dc9ec45330f..dc8aaeb7d40 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.spec.ts @@ -146,7 +146,7 @@ describe('DropdownCloudWidgetComponent', () => { }); it('should load data from restUrl and populate options', async () => { - const jsonDataSpy = spyOn(formCloudService, 'getDropDownJsonData').and.returnValue(of(fakeOptionList)); + const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(fakeOptionList)); widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { id: 'dropdown-id', name: 'date-name', @@ -166,9 +166,9 @@ describe('DropdownCloudWidgetComponent', () => { fixture.detectChanges(); await fixture.whenStable(); - const optOne = fixture.debugElement.queryAll(By.css('[id="option_1"]')); - const optTwo = fixture.debugElement.queryAll(By.css('[id="option_2"]')); - const optThree = fixture.debugElement.queryAll(By.css('[id="option_3"]')); + const optOne = fixture.debugElement.queryAll(By.css('[id="opt_1"]')); + const optTwo = fixture.debugElement.queryAll(By.css('[id="opt_2"]')); + const optThree = fixture.debugElement.queryAll(By.css('[id="opt_3"]')); const allOptions = fixture.debugElement.queryAll(By.css('mat-option')); expect(jsonDataSpy).toHaveBeenCalled(); @@ -195,7 +195,7 @@ describe('DropdownCloudWidgetComponent', () => { } }); - spyOn(formCloudService, 'getDropDownJsonData').and.returnValue(of([ + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([ { id: 'opt1', name: 'default1_value' @@ -230,7 +230,7 @@ describe('DropdownCloudWidgetComponent', () => { value: 'opt1' }); - spyOn(formCloudService, 'getDropDownJsonData').and.returnValue(of([ + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of([ { id: 'opt1', name: 'default1_value' @@ -265,98 +265,11 @@ describe('DropdownCloudWidgetComponent', () => { restResponsePath: 'path' }); - const dropdownSpy = spyOn(formCloudService, 'getDropDownJsonData').and.returnValue(of({ - id: 1, - 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' }], - name: '' - })); - - 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(); - }); - }); - - it('should map correct label if restLabelProperty 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', - restLabelProperty: 'first_name' - }); - - const dropdownSpy = spyOn(formCloudService, 'getDropDownJsonData').and.returnValue(of({ - id: 1, - path: [ - { id: 'opt_1', first_name: 'option_1' }, - { id: 'opt_2', first_name: 'option_2' }, - { id: 'opt_3', first_name: 'option_3' }], - name: '' - })); - - 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(); - }); - }); - - it('should map correct id if restIdProperty 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', - restIdProperty: 'my_id' - }); - - const dropdownSpy = spyOn(formCloudService, 'getDropDownJsonData').and.returnValue(of({ - id: 1, - path: [ - { my_id: 'opt_1', name: 'option_1' }, - { my_id: 'opt_2', name: 'option_2' }, - { my_id: 'opt_3', name: 'option_3' }], - name: '' - })); + { id: 'opt_3', name: 'option_3' }] + )); widget.ngOnInit(); fixture.detectChanges(); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts index 3cfaf5e7461..853e2c02b0e 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/dropdown/dropdown-cloud.widget.ts @@ -59,27 +59,14 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI getValuesFromRestApi() { if (this.isValidRestType()) { - this.formCloudService.getDropDownJsonData(this.field.restUrl) + this.formCloudService.getRestWidgetData(this.field.form.id, this.field.id) .pipe(takeUntil(this.onDestroy$)) .subscribe((result: FormFieldOption[]) => { - this.field.options = this.mapJsonData(result); + this.field.options = result; }, (err) => this.handleError(err)); } } - mapJsonData(data: any[]): FormFieldOption[] { - const dataToMap: any[] = this.field.restResponsePath ? data[this.field.restResponsePath] : data; - const idProperty = this.field.restIdProperty || 'id'; - const restLabelProperty = this.field.restLabelProperty || 'name'; - - return dataToMap.map((value: any) => { - return { - name: value[restLabelProperty], - id: value[idProperty] - }; - }); - } - compareDropdownValues(opt1: FormFieldOption | string, opt2: FormFieldOption | string): boolean { if (!opt1 || !opt2) { return false; diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html new file mode 100644 index 00000000000..5f4f3aaafb6 --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.html @@ -0,0 +1,23 @@ +
+
+ + + + {{opt.name}} + + +
+ + +
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss new file mode 100644 index 00000000000..4b2b48c05cf --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.scss @@ -0,0 +1,20 @@ +.adf { + + &-radio-button-container { + margin-bottom: 15px; + display: flex; + flex-direction: column; + } + + &-radio-group { + margin-top: 15px; + margin-left: 5px; + display: inline-flex; + flex-direction: column; + } + + &-radio-button { + margin: 5px; + } + + } diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts new file mode 100644 index 00000000000..98e5c63c719 --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts @@ -0,0 +1,177 @@ +/*! + * @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 { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; +import { MatIconModule } from '@angular/material/icon'; +import { MatRadioModule } from '@angular/material/radio'; +import { TranslateModule } from '@ngx-translate/core'; +import { AlfrescoApiService, CoreTestingModule, FormFieldModel, FormFieldOption, FormFieldTypes, FormModel, FormService, setupTestBed } from 'core'; +import { FormCloudService } from 'process-services-cloud'; +import { Observable } from 'rxjs'; +import { RadioButtonsCloudWidgetComponent } from './radio-buttons-cloud.widget'; + +describe('RadioButtonsCloudWidgetComponent', () => { + + let formService: FormService; + let formCloudService: FormCloudService; + let widget: RadioButtonsCloudWidgetComponent; + let alfrescoApiService: AlfrescoApiService; + + setupTestBed({ + imports: [ + TranslateModule.forRoot(), + CoreTestingModule, + MatRadioModule, + FormsModule, + MatIconModule + ] + }); + + beforeEach(() => { + alfrescoApiService = TestBed.inject(AlfrescoApiService); + + formService = new FormService(null, alfrescoApiService, null); + formCloudService = new FormCloudService(alfrescoApiService, null); + widget = new RadioButtonsCloudWidgetComponent(formService, formCloudService, null); + widget.field = new FormFieldModel(new FormModel(), { restUrl: '' }); + }); + + it('should update form on values fetched', () => { + const taskId = ''; + const fieldId = ''; + + const form = new FormModel({ + taskId: taskId + }); + + widget.field = new FormFieldModel(form, { + id: fieldId, + restUrl: '' + }); + const field = widget.field; + spyOn(field, 'updateForm').and.stub(); + + spyOn(formCloudService, 'getRestWidgetData').and.returnValue(new Observable((observer) => { + observer.next(null); + observer.complete(); + })); + widget.ngOnInit(); + expect(field.updateForm).toHaveBeenCalled(); + }); + + it('should update the field value when an option is selected', () => { + spyOn(widget, 'onFieldChanged').and.stub(); + widget.onOptionClick('fake-opt'); + + expect(widget.field.value).toEqual('fake-opt'); + }); + + describe('when template is ready', () => { + let radioButtonWidget: RadioButtonsCloudWidgetComponent; + let fixture: ComponentFixture; + let element: HTMLElement; + const restOption: FormFieldOption[] = [ + { + id: 'opt-1', + name: 'opt-name-1' + }, + { + id: 'opt-2', + name: 'opt-name-2' + }]; + + beforeEach(() => { + fixture = TestBed.createComponent(RadioButtonsCloudWidgetComponent); + radioButtonWidget = fixture.componentInstance; + element = fixture.nativeElement; + }); + + it('should show radio buttons as text when is readonly', async () => { + radioButtonWidget.field = new FormFieldModel(new FormModel({}), { + id: 'radio-id', + name: 'radio-name', + type: FormFieldTypes.RADIO_BUTTONS, + readOnly: true + }); + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); + expect(element.querySelector('display-text-widget')).toBeDefined(); + }); + + it('should be able to set label property for Radio Button widget', () => { + radioButtonWidget.field = new FormFieldModel(new FormModel({}), { + id: 'radio-id', + name: 'radio-name-label', + type: FormFieldTypes.RADIO_BUTTONS, + readOnly: true + }); + fixture.detectChanges(); + expect(element.querySelector('label').innerText).toBe('radio-name-label'); + }); + + it('should be able to set a Radio Button widget as required', async () => { + radioButtonWidget.field = new FormFieldModel(new FormModel({}), { + id: 'radio-id', + name: 'radio-name-label', + type: FormFieldTypes.RADIO_BUTTONS, + readOnly: false, + required: true, + optionType: 'manual', + options: restOption, + restUrl: null + }); + + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); + const widgetLabel = element.querySelector('label'); + expect(widgetLabel.innerText).toBe('radio-name-label*'); + expect(radioButtonWidget.field.isValid).toBe(false); + + const option: HTMLElement = element.querySelector('#radio-id-opt-1 label'); + option.click(); + + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); + const selectedOption: HTMLElement = element.querySelector('[class*="mat-radio-checked"]'); + expect(selectedOption.innerText).toBe('opt-name-1'); + expect(radioButtonWidget.field.isValid).toBe(true); + }); + + it('should be able to set a Radio Button widget as required', () => { + radioButtonWidget.field = new FormFieldModel(new FormModel({}), { + id: 'radio-id', + name: 'radio-name-label', + type: FormFieldTypes.RADIO_BUTTONS, + readOnly: false, + required: true, + optionType: 'manual', + options: restOption, + restUrl: null, + value: 'opt-name-2' + }); + + fixture.detectChanges(); + const selectedOption: HTMLElement = element.querySelector('[class*="mat-radio-checked"]'); + expect(selectedOption.innerText).toBe('opt-name-2'); + expect(radioButtonWidget.field.isValid).toBe(true); + }); + }); +}); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts new file mode 100644 index 00000000000..12f7048ef0b --- /dev/null +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts @@ -0,0 +1,78 @@ +/*! + * @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. + */ + +/* tslint:disable:component-selector */ + +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { WidgetComponent, FormService, LogService, FormFieldOption } from '@alfresco/adf-core'; +import { FormCloudService } from '../../../services/form-cloud.service'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'radio-buttons-cloud-widget', + templateUrl: './radio-buttons-cloud.widget.html', + styleUrls: ['./radio-buttons-cloud.widget.scss'], + host: { + '(click)': 'event($event)', + '(blur)': 'event($event)', + '(change)': 'event($event)', + '(focus)': 'event($event)', + '(focusin)': 'event($event)', + '(focusout)': 'event($event)', + '(input)': 'event($event)', + '(invalid)': 'event($event)', + '(select)': 'event($event)' + }, + encapsulation: ViewEncapsulation.None +}) +export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements OnInit { + + typeId = 'RadioButtonsCloudWidgetComponent'; + protected onDestroy$ = new Subject(); + + constructor(public formService: FormService, + private formCloudService: FormCloudService, + private logService: LogService) { + super(formService); + } + + ngOnInit() { + if (this.field && this.field.restUrl) { + this.getValuesFromRestApi(); + } + } + + getValuesFromRestApi() { + this.formCloudService.getRestWidgetData(this.field.form.id, this.field.id) + .pipe(takeUntil(this.onDestroy$)) + .subscribe((result: FormFieldOption[]) => { + this.field.options = result; + this.field.updateForm(); + }, (err) => this.handleError(err)); + } + + onOptionClick(optionSelected: any) { + this.field.value = optionSelected; + this.fieldChanged.emit(this.field); + } + + handleError(error: any) { + this.logService.error(error); + } + +} diff --git a/lib/process-services-cloud/src/lib/form/form-cloud.module.ts b/lib/process-services-cloud/src/lib/form/form-cloud.module.ts index 2b6a5089776..6cd2ee55439 100644 --- a/lib/process-services-cloud/src/lib/form/form-cloud.module.ts +++ b/lib/process-services-cloud/src/lib/form/form-cloud.module.ts @@ -37,6 +37,7 @@ import { PeopleCloudModule } from '../people/people-cloud.module'; import { GroupCloudModule } from '../group/group-cloud.module'; import { PropertiesViewerWidgetComponent } from './components/widgets/properties-viewer/properties-viewer.widget'; import { PropertiesViewerWrapperComponent } from './components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer-wrapper.component'; +import { RadioButtonsCloudWidgetComponent } from './components/widgets/radio-buttons/radio-buttons-cloud.widget'; @NgModule({ imports: [ @@ -57,6 +58,7 @@ import { PropertiesViewerWrapperComponent } from './components/widgets/propertie FormDefinitionSelectorCloudComponent, FormCustomOutcomesComponent, DropdownCloudWidgetComponent, + RadioButtonsCloudWidgetComponent, AttachFileCloudWidgetComponent, DateCloudWidgetComponent, PeopleCloudWidgetComponent, @@ -70,6 +72,7 @@ import { PropertiesViewerWrapperComponent } from './components/widgets/propertie FormDefinitionSelectorCloudComponent, FormCustomOutcomesComponent, DropdownCloudWidgetComponent, + RadioButtonsCloudWidgetComponent, AttachFileCloudWidgetComponent, DateCloudWidgetComponent, PeopleCloudWidgetComponent, diff --git a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.interface.ts b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.interface.ts index 74979ca902d..2e50df85fcf 100644 --- a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.interface.ts +++ b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.interface.ts @@ -16,7 +16,7 @@ */ import { UploadApi } from '@alfresco/js-api'; -import { FormModel, FormValues } from '@alfresco/adf-core'; +import { FormFieldOption, FormModel, FormValues } from '@alfresco/adf-core'; import { TaskDetailsCloudModel } from '../../task/start-task/models/task-details-cloud.model'; import { TaskVariableCloud } from '../models/task-variable-cloud.model'; import { FormContent } from '../../services/form-fields.interfaces'; @@ -33,6 +33,6 @@ export interface FormCloudServiceInterface { getTask(appName: string, taskId: string): Observable; getTaskVariables(appName: string, taskId: string): Observable; getForm(appName: string, formKey: string, version?: number): Observable; - getDropDownJsonData(url: string): Observable; parseForm(json: any, data?: TaskVariableCloud[], readOnly?: boolean): FormModel; + getRestWidgetData(formName: string, widgetId: string, body: Map): Observable; } diff --git a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts index 85cca961e24..6134ac46f10 100644 --- a/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/form/services/form-cloud.service.ts @@ -21,7 +21,8 @@ import { FormValues, AppConfigService, FormOutcomeModel, - FormModel + FormModel, + FormFieldOption } from '@alfresco/adf-core'; import { Observable, from } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; @@ -191,13 +192,10 @@ export class FormCloudService extends BaseCloudService implements FormCloudServi return this.get(url); } - /** - * Parses JSON data to create a corresponding form. - * @param url String data to make the request - * @returns Array of FormFieldOption object - */ - getDropDownJsonData(url: string): Observable { - return this.get(url); + getRestWidgetData(formName: string, widgetId: string, body: any = {}): Observable { + const appName = this.appConfigService.get('alfresco-deployed-apps')[0]?.name; + const apiUrl = `${this.getBasePath(appName)}/form/v1/forms/${formName}/values/${widgetId}`; + return this.post(apiUrl, body); } /**