diff --git a/lib/core/form/components/widgets/core/form-field-metadata.ts b/lib/core/form/components/widgets/core/form-field-metadata.ts index 295d1a1199..77156f4bf9 100644 --- a/lib/core/form/components/widgets/core/form-field-metadata.ts +++ b/lib/core/form/components/widgets/core/form-field-metadata.ts @@ -29,4 +29,10 @@ export interface FormFieldMetadata { type: string; }; responseVariable?: boolean; + menuOptions?: { + show?: boolean, + download?: boolean, + retrieveMetadata?: boolean, + remove?: boolean + }; } diff --git a/lib/core/form/services/form.service.ts b/lib/core/form/services/form.service.ts index 85bc4c117c..7135abb373 100644 --- a/lib/core/form/services/form.service.ts +++ b/lib/core/form/services/form.service.ts @@ -60,6 +60,8 @@ export class FormService { executeOutcome = new Subject(); + updateFormValuesRequested = new Subject(); + constructor(private ecmModelService: EcmModelService, private apiService: AlfrescoApiService, protected logService: LogService) { 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 0a18ea37d1..c71014465d 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 @@ -30,7 +30,8 @@ import { setupTestBed, TRANSLATION_PROVIDER, WidgetVisibilityService, - VersionCompatibilityService + VersionCompatibilityService, + FormService } from '@alfresco/adf-core'; import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; import { FormCloudService } from '../services/form-cloud.service'; @@ -40,7 +41,8 @@ import { conditionalUploadWidgetsMock, emptyFormRepresentationJSON, fakeCloudForm, - multilingualForm + multilingualForm, + fakeMetadataForm } from '../mocks/cloud-form.mock'; import { FormCloudRepresentation } from '../models/form-cloud-representation.model'; import { FormCloudModule } from '../form-cloud.module'; @@ -55,6 +57,7 @@ describe('FormCloudComponent', () => { let visibilityService: WidgetVisibilityService; let formRenderingService: CloudFormRenderingService; let translateService: TranslateService; + let formService: FormService; @Component({ selector: 'adf-cloud-custom-widget', @@ -117,11 +120,24 @@ describe('FormCloudComponent', () => { const appConfigService = TestBed.inject(AppConfigService); spyOn(appConfigService, 'get').and.returnValue([]); + formService = TestBed.inject(FormService); + fixture = TestBed.createComponent(FormCloudComponent); formComponent = fixture.componentInstance; fixture.detectChanges(); })); + it('should set values when updateFormValuesRequested is updated', async () => { + const fakeForm = new FormModel(JSON.parse(JSON.stringify(fakeMetadataForm))); + formComponent.form = fakeForm; + formComponent.formCloudRepresentationJSON = new FormCloudRepresentation(fakeForm); + + const refreshFormSpy = spyOn(formComponent, 'refreshFormData'); + formService.updateFormValuesRequested.next({ pfx_property_one: 'testValue', pfx_property_two: true }); + expect(refreshFormSpy).toHaveBeenCalled(); + expect(formComponent.data).toContain({ name: 'pfx_property_one', value: 'testValue' }, { name: 'pfx_property_two', value: true }); + }); + it('should register custom [upload] widget', () => { const widget = buildWidget('upload', fixture.componentRef.injector); expect(widget['typeId']).toBe('AttachFileCloudWidgetComponent'); 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 e2c79a33f4..4fb39ad6c2 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 @@ -112,6 +112,21 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges, .subscribe((content) => { this.formContentClicked.emit(content); }); + + this.formService.updateFormValuesRequested + .pipe(takeUntil(this.onDestroy$)) + .subscribe((valuesToSetIfNotPresent) => { + const keys = Object.keys(valuesToSetIfNotPresent); + keys.forEach(key => { + if (!this.form.values[key]) { + this.form.values[key] = valuesToSetIfNotPresent[key]; + } + }); + this.data = []; + const fields = Object.keys(this.form.values); + fields.forEach(field => this.data.push({ name: field, value: this.form.values[field] })); + this.refreshFormData(); + }); } ngOnChanges(changes: SimpleChanges) { diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html index 41f47bd959..32239dab62 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html +++ b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.html @@ -25,17 +25,24 @@ more_vert - - - + diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.spec.ts index 23ea888db6..9fa79da64b 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.spec.ts @@ -79,6 +79,12 @@ describe('AttachFileCloudWidgetComponent', () => { fileSource: { name: 'mock-alf-content', serviceId: 'alfresco-content' + }, + menuOptions: { + show: true, + download: true, + retrieveMetadata: true, + remove: true } }; @@ -103,6 +109,10 @@ describe('AttachFileCloudWidgetComponent', () => { name: 'fake-name', content: { mimeType: 'application/pdf' + }, + properties: { + 'pfx:property_one': 'testValue', + 'pfx:property_two': true } }; @@ -110,6 +120,26 @@ describe('AttachFileCloudWidgetComponent', () => { resolve('mock-node-id'); }); + const fakeLocalPngAnswer = { + id: 1155, + nodeId: 1155, + name: 'a_png_file.png', + created: '2017-07-25T17:17:37.099Z', + createdBy: { + id: 1001, + firstName: 'Admin', + lastName: 'admin', + email: 'admin' + }, + relatedContent: false, + contentAvailable: true, + link: false, + mimeType: 'image/png', + simpleType: 'image', + previewStatus: 'queued', + thumbnailStatus: 'queued' + }; + setupTestBed({ imports: [ TranslateModule.forRoot(), @@ -455,5 +485,74 @@ describe('AttachFileCloudWidgetComponent', () => { ); showOption.click(); }); + + it('should request form to be updated with metadata when retrieve is clicked', (done) => { + const updateFormSpy = spyOn(formService.updateFormValuesRequested, 'next'); + const expectedValues = { pfx_property_one: 'testValue', pfx_property_two: true}; + + const menuButton: HTMLButtonElement = ( + fixture.debugElement.query(By.css('#file-fake-option-menu')) + .nativeElement + ); + + menuButton.click(); + fixture.detectChanges(); + + const retrieveMetadataOption: HTMLButtonElement = ( + fixture.debugElement.query(By.css('#file-fake-retrieve-file-metadata')) + .nativeElement + ); + + retrieveMetadataOption.click(); + + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(updateFormSpy).toHaveBeenCalledWith(expectedValues); + done(); + }); + }); + + it('should display the default menu options if no options are provided', () => { + widget.field.params = onlyLocalParams; + fixture.detectChanges(); + fixture.whenStable().then(() => { + const inputDebugElement = fixture.debugElement.query( + By.css('#attach-file-attach') + ); + inputDebugElement.triggerEventHandler('change', { + target: { files: [fakeLocalPngAnswer] } + }); + fixture.detectChanges(); + const menuButton: HTMLButtonElement = ( + fixture.debugElement.query( + By.css('#file-1155-option-menu') + ).nativeElement + ); + menuButton.click(); + fixture.detectChanges(); + const showOption: HTMLButtonElement = ( + fixture.debugElement.query( + By.css('#file-1155-show-file') + ).nativeElement + ); + const downloadOption: HTMLButtonElement = ( + fixture.debugElement.query(By.css('#file-1155-download-file')) + .nativeElement + ); + const retrieveMetadataOption: HTMLButtonElement = ( + fixture.debugElement.query(By.css('#file-1155-retrieve-file-metadata')) + .nativeElement + ); + const removeOption: HTMLButtonElement = ( + fixture.debugElement.query(By.css('#file-1155-remove')) + .nativeElement + ); + + expect(showOption).not.toBeNull(); + expect(downloadOption).not.toBeNull(); + expect(retrieveMetadataOption).toBeNull(); + expect(removeOption).not.toBeNull(); + }); + }); }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.ts b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.ts index ab88fd09f1..77662a2033 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/attach-file/attach-file-cloud-widget.component.ts @@ -24,7 +24,8 @@ import { ThumbnailService, NotificationService, ContentLinkModel, - TranslationService + TranslationService, + FormValues } from '@alfresco/adf-core'; import { Node, RelatedContentRepresentation } from '@alfresco/js-api'; import { ContentCloudNodeSelectorService } from '../../../services/content-cloud-node-selector.service'; @@ -122,7 +123,7 @@ export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent removeExistingSelection(selections: Node[]) { const existingNode: Node[] = [...this.field.value || []]; - return selections.filter(opt => !existingNode.some( (node) => node.id === opt.id)); + return selections.filter(opt => !existingNode.some((node) => node.id === opt.id)); } downloadContent(file: Node): void { @@ -137,4 +138,21 @@ export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent getWidgetIcon(): string { return this.isAlfrescoAndLocal() ? 'file_upload' : 'attach_file'; } + + displayMenuOption(option: string): boolean { + return this.field.params.menuOptions ? this.field.params.menuOptions[option] : option !== 'retrieveMetadata'; + } + + onRetrieveFileMetadata(file: Node) { + const values: FormValues = {}; + const metadata = file?.properties; + if (metadata) { + const keys = Object.keys(metadata); + keys.forEach(key => { + const sanitizedKey = key.replace(':', '_'); + values[sanitizedKey] = metadata[key]; + }); + this.formService.updateFormValuesRequested.next(values); + } + } } diff --git a/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts b/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts index bbe762b9a7..c57fb80eb7 100644 --- a/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts +++ b/lib/process-services-cloud/src/lib/form/mocks/cloud-form.mock.ts @@ -965,3 +965,94 @@ export const multilingualForm = { } } }; + +export let fakeMetadataForm = { + 'id': 'form-de8895be-d0d7-4434-beef-559b15305d72', + 'name': 'StartEventForm', + 'description': '', + 'version': 0, + 'formDefinition': { + 'tabs': [], + 'fields': [ + { + 'type': 'container', + 'id': '5a6b24c1-db2b-45e9-9aff-142395433d23', + 'name': 'Label', + 'tab': null, + 'fields': { + '1': [ + { + 'type': 'text', + 'id': 'pfx_property_one', + 'name': 'pfx_property_one', + 'colspan': 1, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'visibilityCondition': null, + 'placeholder': null, + 'value': null, + 'required': false, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null + } + ], + '2': [ + { + 'type': 'boolean', + 'id': 'pfx_property_two', + 'name': 'pfx_property_two', + 'colspan': 1, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'visibilityCondition': null, + 'placeholder': null, + 'value': null, + 'required': false, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null + } + ], + '3': [ + { + 'id': 'content_form_nodes', + 'name': 'Nodes', + 'type': 'upload', + 'readOnly': false, + 'required': true, + 'colspan': 1, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2, + 'fileSource': { + 'serviceId': 'alfresco-content', + 'name': 'Alfresco Content', + 'metadataAllowed': true + }, + 'multiple': true, + 'menuOptions': { + 'show': true, + 'download': true, + 'retrieveMetadata': true, + 'remove': true + }, + 'link': false + } + } + ] + + }, + 'numberOfColumns': 2 + } + ], + 'outcomes': [], + 'metadata': {}, + 'variables': [] + } +}; diff --git a/lib/process-services-cloud/src/lib/i18n/en.json b/lib/process-services-cloud/src/lib/i18n/en.json index 8b1e888289..86d879c77c 100644 --- a/lib/process-services-cloud/src/lib/i18n/en.json +++ b/lib/process-services-cloud/src/lib/i18n/en.json @@ -188,7 +188,6 @@ "NOT_FOUND": "No group found with the name {{groupName}}" } }, - "ADF_CLOUD_USERS": { "ERROR": { "NOT_FOUND": "No user found with the username {{userName}}" @@ -270,6 +269,8 @@ "ERROR": { "INVALID_DESTINATION_FOLDER_PATH": "Invalid destination folder path" } + }, + "ADF_CLOUD_FORM_COMPONENT": { + "RETRIEVE_METADATA": "Fill form fields with this file's metadata" } - }