diff --git a/lib/core/src/lib/form/components/form-base.component.ts b/lib/core/src/lib/form/components/form-base.component.ts index e7aa215461..84205a0328 100644 --- a/lib/core/src/lib/form/components/form-base.component.ts +++ b/lib/core/src/lib/form/components/form-base.component.ts @@ -18,6 +18,7 @@ import { Directive, EventEmitter, Input, Output } from '@angular/core'; import { ThemePalette } from '@angular/material/core'; import { FormFieldModel, FormFieldValidator, FormModel, FormOutcomeEvent, FormOutcomeModel } from './widgets'; +import { isOutcomeButtonVisible } from './helpers/buttons-visibility'; @Directive({ standalone: true @@ -103,10 +104,6 @@ export abstract class FormBaseComponent { */ formStyle: string = ''; - get hasVisibleOutcomes(): boolean { - return this.form?.outcomes?.some((outcome) => this.isOutcomeButtonVisible(outcome, this.form.readOnly)); - } - get form(): FormModel { return this._form; } @@ -169,22 +166,7 @@ export abstract class FormBaseComponent { } isOutcomeButtonVisible(outcome: FormOutcomeModel, isFormReadOnly: boolean): boolean { - if (outcome?.name) { - if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) { - return this.showCompleteButton; - } - if (isFormReadOnly) { - return outcome.isSelected; - } - if (outcome.name === FormOutcomeModel.SAVE_ACTION) { - return this.showSaveButton; - } - if (outcome.name === FormOutcomeModel.START_PROCESS_ACTION) { - return false; - } - return true; - } - return false; + return isOutcomeButtonVisible(outcome, { isFormReadOnly, showCompleteButton: this.showCompleteButton, showSaveButton: this.showSaveButton }); } /** diff --git a/lib/core/src/lib/form/components/form-field/form-field.component.ts b/lib/core/src/lib/form/components/form-field/form-field.component.ts index 7f07be441e..484447aa6c 100644 --- a/lib/core/src/lib/form/components/form-field/form-field.component.ts +++ b/lib/core/src/lib/form/components/form-field/form-field.component.ts @@ -73,6 +73,7 @@ export class FormFieldComponent implements OnInit, OnDestroy { if (w.adf === undefined) { w.adf = {}; } + const originalField = this.getField(); if (originalField) { const customTemplate = this.field.form.customFieldTemplates[originalField.type]; diff --git a/lib/core/src/lib/form/components/form-renderer.component.html b/lib/core/src/lib/form/components/form-renderer.component.html index ae79dce060..8cd4a59ac1 100644 --- a/lib/core/src/lib/form/components/form-renderer.component.html +++ b/lib/core/src/lib/form/components/form-renderer.component.html @@ -40,7 +40,8 @@
+ [style.width.%]="getColumnWidth(currentRootElement)" + > @@ -61,9 +62,11 @@
+
+
diff --git a/lib/core/src/lib/form/components/helpers/buttons-visibility.ts b/lib/core/src/lib/form/components/helpers/buttons-visibility.ts new file mode 100644 index 0000000000..cb2c431b7b --- /dev/null +++ b/lib/core/src/lib/form/components/helpers/buttons-visibility.ts @@ -0,0 +1,45 @@ +/*! + * @license + * Copyright © 2005-2025 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. + */ + +import { FormOutcomeModel } from '../widgets'; + +interface IsOutcomeButtonVisibleProps { + isFormReadOnly: boolean; + showCompleteButton: boolean; + showSaveButton: boolean; +} + +export const isOutcomeButtonVisible = (outcome: FormOutcomeModel, props: IsOutcomeButtonVisibleProps): boolean => { + const { isFormReadOnly, showCompleteButton, showSaveButton } = props; + + if (outcome?.name) { + if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) { + return showCompleteButton; + } + if (isFormReadOnly) { + return outcome.isSelected; + } + if (outcome.name === FormOutcomeModel.SAVE_ACTION) { + return showSaveButton; + } + if (outcome.name === FormOutcomeModel.START_PROCESS_ACTION) { + return false; + } + return true; + } + return false; +}; diff --git a/lib/core/src/lib/form/public-api.ts b/lib/core/src/lib/form/public-api.ts index 83a9ec195b..2098c2726f 100644 --- a/lib/core/src/lib/form/public-api.ts +++ b/lib/core/src/lib/form/public-api.ts @@ -23,6 +23,7 @@ export * from './components/form-renderer.component'; export * from './components/widgets'; export * from './components/middlewares/middleware'; export * from './components/middlewares/decimal-middleware.service'; +export * from './components/helpers/buttons-visibility'; export * from './services/form-rendering.service'; export * from './services/form.service'; diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts index 2e7490cc79..df24e70306 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts @@ -670,12 +670,36 @@ describe('FormCloudComponent', () => { done(); }); - const formValues: any[] = []; + const formValues: TaskVariableCloud[] = [ + { + name: 'var1', + value: 'value1', + id: 'var1', + type: 'string', + hasValue: () => true + } + ]; + const change = new SimpleChange(null, formValues, false); formComponent.data = formValues; formComponent.ngOnChanges({ data: change }); }); + it('should not change form if custom form values is empty array', () => { + const formModel = new FormModel({ + id: 'id', + taskId: 'task-id', + fields: [{ id: 'field1' }, { id: 'field2' }] + }); + formComponent.form = formModel; + + const formValues: TaskVariableCloud[] = []; + const change = new SimpleChange(null, formValues, false); + formComponent.ngOnChanges({ data: change }); + + expect(formComponent.form).toEqual(formModel); + }); + it('should save task form and raise corresponding event', () => { spyOn(formCloudService, 'saveTaskForm').and.callFake( () => diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts index 52f9b03a0b..be42b21ab2 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.ts @@ -242,13 +242,14 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, return; } - const data = changes['data']; - if (data?.currentValue) { + const data = changes['data']?.currentValue; + if (data?.length > 0) { this.refreshFormData(); return; } const formRepresentation = changes['form']; + if (formRepresentation?.currentValue) { this.form = formRepresentation.currentValue; this.onFormLoaded(this.form); diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html index 3224bfb896..9367cb6284 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.html @@ -17,13 +17,16 @@ class="adf-process-input-container" floatLabel="always" *ngIf="showSelectProcessDropdown" - data-automation-id="adf-select-cloud-process-dropdown"> + data-automation-id="adf-select-cloud-process-dropdown" + > {{ 'ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.FORM.LABEL.TYPE' | translate }} + id="processDefinitionName" + > +
+ +
(false); private readonly dialog = inject(MatDialog); + showSaveButton = false; + showCompleteButton = false; + get isProcessFormValid(): boolean { if (this.hasForm && this.isFormCloudLoaded) { return (this.formCloud ? !Object.keys(this.formCloud.values).length : false) || this.formCloud?.isValid || this.isProcessStarting; @@ -256,6 +258,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { .subscribe((processDefinitionName) => { this.selectProcessDefinitionByProcessDefinitionName(processDefinitionName); }); + this.showStartProcessButton$ = combineLatest([this.displayStartSubject, this.hasVisibleOutcomesSubject]).pipe( map(([displayStart, hasVisibleOutcomes]) => (displayStart !== null ? displayStart === 'true' : !hasVisibleOutcomes)) ); @@ -284,9 +287,14 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { this.isFormCloudLoaded = true; this.formCloud = form; - if (this.startForm) { - this.hasVisibleOutcomesSubject.next(this.startForm.hasVisibleOutcomes); - } + const anyOutcomeVisible = form?.outcomes?.some((outcome) => + isOutcomeButtonVisible(outcome, { + isFormReadOnly: form.readOnly, + showCompleteButton: this.showCompleteButton, + showSaveButton: this.showSaveButton + }) + ); + this.hasVisibleOutcomesSubject.next(anyOutcomeVisible); } private getMaxNameLength(): number {