mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-06-30 18:15:11 +00:00
[AAE-3084] Add retrieve metadata option in upload widget (#5903)
* AAE-3084 Add retrieve metadata option to upload widget file menu * AAE-3084 Fix rebasing issues * AAE-3084 Fix behaviour on empty dropdown * Update en.json * AAE-3084 Fix en.json Co-authored-by: Eugenio Romano <eromano@users.noreply.github.com>
This commit is contained in:
parent
83786bf271
commit
aeff60a1b5
@ -29,4 +29,10 @@ export interface FormFieldMetadata {
|
||||
type: string;
|
||||
};
|
||||
responseVariable?: boolean;
|
||||
menuOptions?: {
|
||||
show?: boolean,
|
||||
download?: boolean,
|
||||
retrieveMetadata?: boolean,
|
||||
remove?: boolean
|
||||
};
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ export class FormService {
|
||||
|
||||
executeOutcome = new Subject<FormOutcomeEvent>();
|
||||
|
||||
updateFormValuesRequested = new Subject<FormValues>();
|
||||
|
||||
constructor(private ecmModelService: EcmModelService,
|
||||
private apiService: AlfrescoApiService,
|
||||
protected logService: LogService) {
|
||||
|
@ -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<any>(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');
|
||||
|
@ -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) {
|
||||
|
@ -25,17 +25,24 @@
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #fileActionMenu="matMenu" xPosition="before">
|
||||
<button id="{{'file-'+file?.id+'-show-file'}}" mat-menu-item (click)="onAttachFileClicked(file)">
|
||||
<button *ngIf="displayMenuOption('show')" id="{{'file-'+file?.id+'-show-file'}}"
|
||||
mat-menu-item (click)="onAttachFileClicked(file)">
|
||||
<mat-icon>image</mat-icon>
|
||||
<span>{{ 'FORM.FIELD.VIEW_FILE' | translate }}</span>
|
||||
</button>
|
||||
<button id="{{'file-'+file?.id+'-download-file'}}" mat-menu-item (click)="downloadContent(file)">
|
||||
<button *ngIf="displayMenuOption('download')" id="{{'file-'+file?.id+'-download-file'}}"
|
||||
mat-menu-item (click)="downloadContent(file)">
|
||||
<mat-icon>file_download</mat-icon>
|
||||
<span>{{ 'FORM.FIELD.DOWNLOAD_FILE' | translate }}</span>
|
||||
</button>
|
||||
<button *ngIf="!field.readOnly" id="{{'file-'+file?.id+'-remove-file'}}" mat-menu-item
|
||||
[id]="'file-'+file?.id+'-remove'" (click)="onRemoveAttachFile(file);"
|
||||
(keyup.enter)="onRemoveAttachFile(file);">
|
||||
<button *ngIf="displayMenuOption('retrieveMetadata')" id="{{'file-'+file?.id+'-retrieve-file-metadata'}}"
|
||||
mat-menu-item (click)="onRetrieveFileMetadata(file);">
|
||||
<mat-icon class="mat-24">low_priority</mat-icon>
|
||||
<span>{{ 'ADF_CLOUD_FORM_COMPONENT.RETRIEVE_METADATA' | translate }}</span>
|
||||
</button>
|
||||
<button *ngIf="!field.readOnly && displayMenuOption('remove')" id="{{'file-'+file?.id+'-remove-file'}}"
|
||||
mat-menu-item [id]="'file-'+file?.id+'-remove'"
|
||||
(click)="onRemoveAttachFile(file);" (keyup.enter)="onRemoveAttachFile(file);">
|
||||
<mat-icon class="mat-24">highlight_off</mat-icon>
|
||||
<span>{{ 'FORM.FIELD.REMOVE_FILE' | translate }}</span>
|
||||
</button>
|
||||
|
@ -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 = <HTMLButtonElement> (
|
||||
fixture.debugElement.query(By.css('#file-fake-option-menu'))
|
||||
.nativeElement
|
||||
);
|
||||
|
||||
menuButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
const retrieveMetadataOption: HTMLButtonElement = <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 = <FormFieldMetadata> 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 = <HTMLButtonElement> (
|
||||
fixture.debugElement.query(
|
||||
By.css('#file-1155-option-menu')
|
||||
).nativeElement
|
||||
);
|
||||
menuButton.click();
|
||||
fixture.detectChanges();
|
||||
const showOption: HTMLButtonElement = <HTMLButtonElement> (
|
||||
fixture.debugElement.query(
|
||||
By.css('#file-1155-show-file')
|
||||
).nativeElement
|
||||
);
|
||||
const downloadOption: HTMLButtonElement = <HTMLButtonElement> (
|
||||
fixture.debugElement.query(By.css('#file-1155-download-file'))
|
||||
.nativeElement
|
||||
);
|
||||
const retrieveMetadataOption: HTMLButtonElement = <HTMLButtonElement> (
|
||||
fixture.debugElement.query(By.css('#file-1155-retrieve-file-metadata'))
|
||||
.nativeElement
|
||||
);
|
||||
const removeOption: HTMLButtonElement = <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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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': []
|
||||
}
|
||||
};
|
||||
|
@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user