diff --git a/e2e/pages/adf/demo-shell/process-services/people-group-cloud-component.page.ts b/e2e/pages/adf/demo-shell/process-services/people-group-cloud-component.page.ts index d8a9551dbb..ad279f197e 100644 --- a/e2e/pages/adf/demo-shell/process-services/people-group-cloud-component.page.ts +++ b/e2e/pages/adf/demo-shell/process-services/people-group-cloud-component.page.ts @@ -36,7 +36,7 @@ export class PeopleGroupCloudComponentPage { peopleCloudComponentTitle: ElementFinder = element(by.cssContainingText('mat-card-title', 'People Cloud Component')); groupCloudComponentTitle: ElementFinder = element(by.cssContainingText('mat-card-title', 'Groups Cloud Component')); preselectValidation: ElementFinder = element.all(by.css('mat-checkbox.app-preselect-value')).first(); - preselectValidationStatus: ElementFinder = element(by.css('mat-checkbox.app-preselect-value label input')); + preselectValidationStatus: ElementFinder = element.all(by.css('mat-checkbox.app-preselect-value label input')).first(); peopleFilterByAppName: ElementFinder = element(by.css('.app-people-control-options mat-radio-button[value="appName"]')); groupFilterByAppName: ElementFinder = element(by.css('.app-groups-control-options mat-radio-button[value="appName"]')); diff --git a/lib/process-services-cloud/src/lib/form/components/form-definition-selector-cloud.component.ts b/lib/process-services-cloud/src/lib/form/components/form-definition-selector-cloud.component.ts index 2f4cdeae63..20a4543dac 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-definition-selector-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-definition-selector-cloud.component.ts @@ -18,8 +18,8 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Observable } from 'rxjs'; import { FormDefinitionSelectorCloudService } from '../services/form-definition-selector-cloud.service'; -import { FormDefinitionSelectorCloudModel } from '../models/form-definition-selector-cloud.model'; import { MatSelectChange } from '@angular/material'; +import { FormRepresentation } from '../../services/form-fields.interfaces'; @Component({ selector: 'adf-cloud-form-definition-selector', @@ -37,7 +37,7 @@ export class FormDefinitionSelectorCloudComponent implements OnInit { @Output() selectForm: EventEmitter = new EventEmitter(); - forms$: Observable; + forms$: Observable; constructor(private formDefinitionCloudService: FormDefinitionSelectorCloudService) { } diff --git a/lib/process-services-cloud/src/lib/form/models/form-definition-selector-cloud.model.ts b/lib/process-services-cloud/src/lib/form/models/form-definition-selector-cloud.model.ts deleted file mode 100644 index bad242bdd3..0000000000 --- a/lib/process-services-cloud/src/lib/form/models/form-definition-selector-cloud.model.ts +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * @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. - */ - -export interface FormDefinitionSelectorCloudModel { - id?: number; - name?: string; - description?: string; - version?: string; - standalone?: string; -} diff --git a/lib/process-services-cloud/src/lib/form/public-api.ts b/lib/process-services-cloud/src/lib/form/public-api.ts index 9b1cb8ad89..f983738e31 100644 --- a/lib/process-services-cloud/src/lib/form/public-api.ts +++ b/lib/process-services-cloud/src/lib/form/public-api.ts @@ -16,7 +16,6 @@ */ export * from './models/task-variable-cloud.model'; -export * from './models/form-definition-selector-cloud.model'; export * from './components/form-cloud.component'; export * from './components/form-definition-selector-cloud.component'; 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 2722c30fb7..25190f26f8 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 @@ -16,13 +16,21 @@ */ import { Injectable } from '@angular/core'; -import { AlfrescoApiService, FormValues, AppConfigService, FormOutcomeModel, FormFieldOption, FormModel } from '@alfresco/adf-core'; +import { + AlfrescoApiService, + FormValues, + AppConfigService, + FormOutcomeModel, + FormFieldOption, + FormModel +} from '@alfresco/adf-core'; import { Observable, from } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { TaskDetailsCloudModel } from '../../task/start-task/models/task-details-cloud.model'; import { CompleteFormRepresentation } from '@alfresco/js-api'; import { TaskVariableCloud, ProcessStorageCloudModel } from '../models/task-variable-cloud.model'; import { BaseCloudService } from '../../services/base-cloud.service'; +import { FormContent } from '../../services/form-fields.interfaces'; @Injectable({ providedIn: 'root' @@ -48,7 +56,7 @@ export class FormCloudService extends BaseCloudService { return this.getTask(appName, taskId).pipe( switchMap(task => { return this.getForm(appName, task.formKey, version).pipe( - map(form => { + map((form: FormContent) => { const flattenForm = { ...form.formRepresentation, ...form.formRepresentation.formDefinition, @@ -69,6 +77,7 @@ export class FormCloudService extends BaseCloudService { * Saves a task form. * @param appName Name of the app * @param taskId ID of the target task + * @param processInstanceId ID of processInstance * @param formId ID of the form to save * @param values Form values object * @returns Updated task details @@ -97,7 +106,7 @@ export class FormCloudService extends BaseCloudService { '', nodeId, '', - {overwrite: true} + { overwrite: true } )).pipe( map((res: any) => res.entry) ); @@ -107,14 +116,20 @@ export class FormCloudService extends BaseCloudService { * Completes a task form. * @param appName Name of the app * @param taskId ID of the target task + * @param processInstanceId ID of processInstance * @param formId ID of the form to complete * @param formValues Form values object * @param outcome Form outcome + * @param version of the form * @returns Updated task details */ completeTaskForm(appName: string, taskId: string, processInstanceId: string, formId: string, formValues: FormValues, outcome: string, version: number): Observable { const apiUrl = `${this.getBasePath(appName)}/form/v1/forms/${formId}/submit/versions/${version}`; - const completeFormRepresentation = {values: formValues, taskId: taskId, processInstanceId: processInstanceId}; + const completeFormRepresentation = { + values: formValues, + taskId: taskId, + processInstanceId: processInstanceId + }; if (outcome) { completeFormRepresentation.outcome = outcome; } @@ -171,7 +186,7 @@ export class FormCloudService extends BaseCloudService { * @param version Version of the form * @returns Form definition */ - getForm(appName: string, formKey: string, version?: number): Observable { + getForm(appName: string, formKey: string, version?: number): Observable { let url = `${this.getBasePath(appName)}/form/v1/forms/${formKey}`; if (version) { diff --git a/lib/process-services-cloud/src/lib/form/services/form-definition-selector-cloud.service.ts b/lib/process-services-cloud/src/lib/form/services/form-definition-selector-cloud.service.ts index d6bb569e16..4bb6335c1f 100644 --- a/lib/process-services-cloud/src/lib/form/services/form-definition-selector-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/form/services/form-definition-selector-cloud.service.ts @@ -18,9 +18,9 @@ import { Injectable } from '@angular/core'; import { AlfrescoApiService, AppConfigService } from '@alfresco/adf-core'; import { map } from 'rxjs/operators'; -import { FormDefinitionSelectorCloudModel } from '../models/form-definition-selector-cloud.model'; import { from, Observable } from 'rxjs'; import { BaseCloudService } from '../../services/base-cloud.service'; +import { FormRepresentation } from '../../services/form-fields.interfaces'; @Injectable({ providedIn: 'root' @@ -38,13 +38,13 @@ export class FormDefinitionSelectorCloudService extends BaseCloudService { * @param appName Name of the application * @returns Details of the forms */ - getForms(appName: string): Observable { + getForms(appName: string): Observable { const url = `${this.getBasePath(appName)}/form/v1/forms`; return this.get(url).pipe( map((data: any) => { return data.map((formData: any) => { - return formData.formRepresentation; + return formData.formRepresentation; }); }) ); @@ -55,7 +55,7 @@ export class FormDefinitionSelectorCloudService extends BaseCloudService { * @param appName Name of the application * @returns Details of the forms */ - getStandAloneTaskForms(appName: string): Observable { + getStandAloneTaskForms(appName: string): Observable { return from(this.getForms(appName)).pipe( map((data: any) => { return data.filter((formData: any) => formData.standalone || formData.standalone === undefined); diff --git a/lib/process-services-cloud/src/lib/services/form-fields.interfaces.ts b/lib/process-services-cloud/src/lib/services/form-fields.interfaces.ts new file mode 100644 index 0000000000..0e0675903d --- /dev/null +++ b/lib/process-services-cloud/src/lib/services/form-fields.interfaces.ts @@ -0,0 +1,233 @@ +/*! + * @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 { Moment } from 'moment'; + +export interface FormContent { + formRepresentation: FormRepresentation; +} + +export interface FormRepresentation { + id: string; + name: string; + description: string; + version?: number; + formDefinition?: FormDefinition; + standAlone?: boolean; +} + +export interface FormTab { + id: string; + title: string; + visibilityCondition: VisibilityCondition | null; +} + +export interface FormOutcome { + id: string; + name: string; +} + +export interface FormDefinition { + tabs: FormTab[]; + fields: Container[] | HeaderRepresentation[]; + outcomes: FormOutcome[]; + metadata: {}; + variables: any[]; +} + +export interface Container { + id: string; + type: string; + tab: string; + name: string; + numberOfColumns: number; + fields: { + [key: string]: FormFieldRepresentation[] + }; +} + +export type FormFieldRepresentation = (DateField | DateTimeField | TextField | AttachFileField | DropDownField | + RadioField | TypeaheadField | PeopleField | AmountField | NumberField | CheckboxField | HyperlinkField | NumberField); + +export interface AttachFileField extends FormField { + required: boolean; +} + +export interface TypeaheadField extends RestField { + required: boolean; +} + +export interface RestField extends FormField { + required: boolean; + restUrl: string; + restResponsePath: string; + restIdProperty: string; + restLabelProperty: string; +} + +export interface HeaderRepresentation extends Container { + numberOfColumns: number; + params: { + [key: string]: any + }; + visibilityCondition: VisibilityCondition; +} + +export interface ColumnDefinitionRepresentation extends Container { + id: string; + name: string; + type: string; + value: any; + required: boolean; + editable: boolean; + sortable: boolean; + visible: boolean; +} + +export interface DynamicTableRepresentation extends FormField { + required: boolean; + tab: string; + placeholder: string; + columnDefinitions: ColumnDefinitionRepresentation[]; +} + +export interface VisibilityCondition { + leftType: string; + leftValue: string; + operator: string; + rightValue: string | number | Date | Moment; + rightType: string; + nextConditionOperator?: string; + nextCondition?: VisibilityCondition; +} + +export interface FormField { + id: string; + name: string; + value: any; + type: FormFieldType | string; + readOnly?: boolean; + colspan: number; + params: { + [anyKey: string]: any + }; + visibilityCondition: null | VisibilityCondition; +} + +export interface FormOption { + id: string; + name: string; +} + +export interface OptionsField { + value: any; + restUrl: string | null; + restResponsePath: string | null; + restIdProperty: string | null; + restLabelProperty: string | null; + optionType: 'manual' | 'rest'; + options: FormOption[]; +} + +export interface AmountField extends FormField { + required: boolean; + placeholder: string | null; + minValue: number | null; + maxValue: number | null; + enableFractions: boolean; + currency: string; +} + +export interface CheckboxField extends FormField { + required: boolean; +} + +export interface DateField extends FormField { + required: boolean; + placeholder: string | null; + minValue: string | null; + maxValue: string | null; + dateDisplayFormat: string; +} + +export interface DateTimeField extends FormField { + required: boolean; + placeholder: string | null; + minValue: string | null; + maxValue: string | null; + dateDisplayFormat: string; +} + +export interface DropDownField extends OptionsField, FormField { + required: boolean; +} + +export interface HyperlinkField extends FormField { + hyperlinkUrl: string | null; + displayText: string | null; +} + +export interface NumberField extends FormField { + placeholder: string | null; + minValue: number | null; + maxValue: number | null; + required: boolean; +} + +export interface RadioField extends OptionsField, FormField { + required: boolean; +} + +export interface TextField extends FormField { + regexPattern: string | null; + required: boolean; + minLength: number; + maxLength: number; + placeholder: string | null; +} + +export enum PeopleModeOptions { + single = 'single', + multiple = 'multiple' +} + +export interface PeopleField extends FormField { + required: boolean; + optionType: PeopleModeOptions; +} + +export enum FormFieldType { + text = 'text', + multiline = 'multi-line-text', + number = 'integer', + checkbox = 'boolean', + date = 'date', + datetime = 'datetime', + dropdown = 'dropdown', + typeahead = 'typeahead', + amount = 'amount', + radio = 'radio-buttons', + people = 'people', + groupOfPeople = 'functional-group', + dynamicTable = 'dynamicTable', + hyperlink = 'hyperlink', + header = 'group', + uploadFile = 'upload', + uploadFolder = 'uploadFolder', + displayValue = 'readonly', + displayText = 'readonly-text' +} diff --git a/lib/process-services-cloud/src/lib/services/public-api.ts b/lib/process-services-cloud/src/lib/services/public-api.ts index 4cdb2c0031..8655ff1335 100644 --- a/lib/process-services-cloud/src/lib/services/public-api.ts +++ b/lib/process-services-cloud/src/lib/services/public-api.ts @@ -19,3 +19,4 @@ export * from './user-preference-cloud.service'; export * from './local-preference-cloud.service'; export * from './cloud-token.service'; export * from './preference-cloud.interface'; +export * from './form-fields.interfaces';