mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-6242] upload a new version of a file attached in a form (#7651)
* [AAE-6242] Create upload new version dialog to handle the upload of the new file version * [AAE-6242] Create version manager service to open version manager dialog * [AAE-6242] Export service and dialog * [AAE-6242] add adf-upload button to the show the upload new file button * [AAE-6242] open upload new version dialog * [AAE-6242] Removed console log * [AAE-8798] display update option name to newVersion * [AAE-8799] Emit version manager data when new file version is uploaded * [AAE-8799] When a new file version is uploaded open new version dialog and update current file version with the new file version * [AAE-8799] Rename UploadNewVersionDialogComponent to VersionManagerDialogComponent and UploadNewVersionDialogData to VersionManagerDialogData * [AAE-8799] Use default root folder id * [AAE-8799] Add #uploadSingleFile ViewChild in order get the input reference * [AAE-8799] Trigger adf-upload-button by clicking on the button in order to open the file chooser and upload a new file version * [AAE-8799] Version manager dialog emits file upload error * [AAE-8799] Format version manager dialog code * [AAE-8799] Reject upload and permission errors * [AAE-8799] Catch upload new version errors * [AAE-8799] Update allowable operation type * [AAE-8799] Rename VersionManagerDialogComponent into NewVersionUploaderDialogComponent and VersionManagerService into NewVersionUploaderService, create specific folder for new version uploader component and service * Restore previous UploadButtonComponent version * [AAE-8799] Use [adf-upload] directive to upload new file version * [AAE-8799] Add mock file for new version uploader unit tests * [AAE-8799] Override mat dialog configuration * [AAE-8799] Add unit test related to event emitted from Dialog * [AAE-8799] Create model to handle New Version Uploader data * [AAE-8799] Return data on dialog close * [AAE-8799] Add showVersionsOnly property to dialog to show only file version list * [AAE-8799] Add dialogAction to emit dialog actions * [AAE-8799] Return observable instead of promise * [AAE-8799] Update new file version type * [AAE-8799] Subscribe dialog because return an Observable * [AAE-8799] Add license header * [AAE-8799] Add i18n new version uploader translations * [AAE-8799] If data.title is not provided, add a default title * [AAE-8799] Change panelClass for manage versions visualizations, add dialog styles * [AAE-8799] Add upload new version dialog unit test * [AAE-8799] Add upload new version dialog unit test related to manage versions section * [AAE-8799] Add onUploadNewFileVersion unit tests * [AAE-8799] Test new dialog panelClass * [AAE-8799] Create a method to set dialog title, if title isn't provided from parent component, a default title is set * [AAE-8799] Add doc to new-version-uploader-dilog component and service * [AAE-8799] Add new-version-uploader.dialog.service documentation
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
(rowClick)="onRowClicked($event)"
|
||||
(attachFileClick)="onAttachFileClicked($event)"
|
||||
(downloadFile)="downloadContent($event)"
|
||||
(uploadNewFileVersion)="onUploadNewFileVersion($event)"
|
||||
(contentModelFileHandler)="contentModelFormFileHandler($event)"
|
||||
(removeAttachFile)="onRemoveAttachFile($event)"
|
||||
></adf-cloud-file-properties-table>
|
||||
|
@@ -29,7 +29,8 @@ import {
|
||||
DownloadService,
|
||||
AppConfigService,
|
||||
UploadWidgetContentLinkModel,
|
||||
LocalizedDatePipe
|
||||
LocalizedDatePipe,
|
||||
NotificationService
|
||||
} from '@alfresco/adf-core';
|
||||
import {
|
||||
allSourceParams,
|
||||
@@ -60,11 +61,12 @@ import {
|
||||
} from '../../../mocks/attach-file-cloud-widget.mock';
|
||||
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ContentModule, ContentNodeSelectorPanelService } from '@alfresco/adf-content-services';
|
||||
import { ContentModule, ContentNodeSelectorPanelService, NewVersionUploaderDataAction, NewVersionUploaderService } from '@alfresco/adf-content-services';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { of } from 'rxjs';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { FormCloudModule } from '../../../form-cloud.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { mockNode } from 'content-services/src/lib/mock';
|
||||
|
||||
describe('AttachFileCloudWidgetComponent', () => {
|
||||
let widget: AttachFileCloudWidgetComponent;
|
||||
@@ -82,6 +84,8 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
let contentClickedSpy: jasmine.Spy;
|
||||
let openUploadFileDialogSpy: jasmine.Spy;
|
||||
let localizedDataPipe: LocalizedDatePipe;
|
||||
let newVersionUploaderService: NewVersionUploaderService;
|
||||
let notificationService: NotificationService;
|
||||
|
||||
const createUploadWidgetField = (form: FormModel, fieldId: string, value?: any, params?: any, multiple?: boolean, name?: string, readOnly?: boolean) => {
|
||||
widget.field = new FormFieldModel(form, {
|
||||
@@ -204,7 +208,7 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
describe('when is required', () => {
|
||||
|
||||
it('should be able to display label with asterisk', async () => {
|
||||
widget.field = new FormFieldModel( new FormModel({ taskId: '<id>' }), {
|
||||
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
|
||||
type: FormFieldTypes.UPLOAD,
|
||||
required: true
|
||||
});
|
||||
@@ -298,7 +302,7 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
it('should be able to use mapped string variable value if the destinationFolderPath set to string type variable', async () => {
|
||||
const getNodeIdFromPathSpy = spyOn(contentCloudNodeSelectorService, 'getNodeIdFromPath').and.returnValue(mockNodeIdBasedOnStringVariableValue);
|
||||
|
||||
const form = new FormModel({ formVariables, processVariables});
|
||||
const form = new FormModel({ formVariables, processVariables });
|
||||
createUploadWidgetField(form, 'attach-file-alfresco', [], mockAllFileSourceWithStringVariablePathType);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -383,9 +387,9 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
appConfigService.config = Object.assign(appConfigService.config, {
|
||||
'alfresco-deployed-apps': [
|
||||
{
|
||||
name: 'fakeapp'
|
||||
name: 'fakeapp'
|
||||
}
|
||||
]
|
||||
]
|
||||
});
|
||||
|
||||
expect(widget.replaceAppNameAliasWithValue('/myfiles/-appname-/folder')).toBe('/myfiles/fakeapp/folder');
|
||||
@@ -504,7 +508,7 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
|
||||
describe('when a file is uploaded', () => {
|
||||
beforeEach(async () => {
|
||||
apiServiceSpy = spyOn(widget['nodesApi'], 'getNode').and.returnValue(new Promise(resolve => resolve({entry: fakeNodeWithProperties})));
|
||||
apiServiceSpy = spyOn(widget['nodesApi'], 'getNode').and.returnValue(new Promise(resolve => resolve({ entry: fakeNodeWithProperties })));
|
||||
spyOn(contentCloudNodeSelectorService, 'getNodeIdFromPath').and.returnValue(new Promise(resolve => resolve('fake-properties')));
|
||||
openUploadFileDialogSpy.and.returnValue(of([fakeNodeWithProperties]));
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
@@ -846,4 +850,48 @@ describe('AttachFileCloudWidgetComponent', () => {
|
||||
expect(getProcessVariableValueSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onUploadNewFileVersion', () => {
|
||||
let spyOnOpenUploadNewVersionDialog: jasmine.Spy;
|
||||
let spyOnReplaceOldFileVersionWithNew: jasmine.Spy;
|
||||
let spyOnShowError: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
newVersionUploaderService = TestBed.inject(NewVersionUploaderService);
|
||||
spyOnOpenUploadNewVersionDialog = spyOn(newVersionUploaderService, 'openUploadNewVersionDialog')
|
||||
.and.returnValue(of({ action: NewVersionUploaderDataAction.refresh }));
|
||||
spyOnReplaceOldFileVersionWithNew = spyOn(widget, 'replaceOldFileVersionWithNew');
|
||||
spyOnShowError = spyOn(notificationService, 'showError');
|
||||
});
|
||||
|
||||
it('Should open new version uploader dialog', async () => {
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnOpenUploadNewVersionDialog).toHaveBeenCalledWith(mockNode);
|
||||
});
|
||||
|
||||
it('Should not replace old file version with the new one if dialog returned action is not upload', async () => {
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnReplaceOldFileVersionWithNew).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should replace old file version with the new one if dialog returned action is upload', async () => {
|
||||
spyOnOpenUploadNewVersionDialog.and.returnValue(of({ action: NewVersionUploaderDataAction.upload }));
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnReplaceOldFileVersionWithNew).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('Should show notification error if new version uploader dialog return error', async () => {
|
||||
const mockError = {value: 'Upload error'};
|
||||
spyOnOpenUploadNewVersionDialog.and.returnValue(throwError(mockError));
|
||||
await fixture.whenStable();
|
||||
widget.onUploadNewFileVersion(mockNode);
|
||||
expect(spyOnReplaceOldFileVersionWithNew).not.toHaveBeenCalled();
|
||||
expect(spyOnShowError).toHaveBeenCalledWith(mockError.value);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@@ -35,7 +35,7 @@ import { ContentCloudNodeSelectorService } from '../../../services/content-cloud
|
||||
import { ProcessCloudContentService } from '../../../services/process-cloud-content.service';
|
||||
import { UploadCloudWidgetComponent } from './upload-cloud.widget';
|
||||
import { DestinationFolderPathModel, DestinationFolderPathType } from '../../../models/form-cloud-representation.model';
|
||||
import { ContentNodeSelectorPanelService } from '@alfresco/adf-content-services';
|
||||
import { ContentNodeSelectorPanelService, NewVersionUploaderData, NewVersionUploaderDataAction, NewVersionUploaderDialogData, NewVersionUploaderService, VersionManagerUploadData } from '@alfresco/adf-content-services';
|
||||
|
||||
export const RETRIEVE_METADATA_OPTION = 'retrieveMetadata';
|
||||
export const ALIAS_ROOT_FOLDER = '-root-';
|
||||
@@ -81,7 +81,8 @@ export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent i
|
||||
private contentNodeSelectorService: ContentCloudNodeSelectorService,
|
||||
private appConfigService: AppConfigService,
|
||||
private apiService: AlfrescoApiService,
|
||||
private contentNodeSelectorPanelService: ContentNodeSelectorPanelService
|
||||
private contentNodeSelectorPanelService: ContentNodeSelectorPanelService,
|
||||
private newVersionUploaderService: NewVersionUploaderService
|
||||
) {
|
||||
super(formService, thumbnails, processCloudContentService, notificationService, logger);
|
||||
}
|
||||
@@ -211,6 +212,16 @@ export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent i
|
||||
this.processCloudContentService.downloadFile(file.id);
|
||||
}
|
||||
|
||||
onUploadNewFileVersion(node: NewVersionUploaderDialogData): void {
|
||||
this.newVersionUploaderService.openUploadNewVersionDialog(node).subscribe((newVersionUploaderData: NewVersionUploaderData) => {
|
||||
if (newVersionUploaderData.action === NewVersionUploaderDataAction.upload) {
|
||||
this.replaceOldFileVersionWithNew(newVersionUploaderData as VersionManagerUploadData);
|
||||
}
|
||||
},
|
||||
error => this.notificationService.showError(error.value)
|
||||
);
|
||||
}
|
||||
|
||||
onAttachFileClicked(nodeSelector: any) {
|
||||
nodeSelector.nodeId = nodeSelector.id;
|
||||
this.fileClicked(new ContentLinkModel(nodeSelector));
|
||||
|
@@ -14,7 +14,7 @@
|
||||
[alt]="mimeTypeIcon" role="button" tabindex="0" />
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="fileName">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'FORM.FIELD.FILE_NAME' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
@@ -22,7 +22,7 @@
|
||||
(click)="onRowClicked(element)">{{element.name}}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container *ngFor="let columnName of field?.params?.displayableCMProperties" [matColumnDef]="columnName.name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ columnName.title ? columnName.title : columnName.name | titlecase
|
||||
}}</th>
|
||||
@@ -31,7 +31,7 @@
|
||||
(click)="onRowClicked(row)">{{ getColumnValue(row, columnName) }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="action">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
@@ -62,11 +62,19 @@
|
||||
<mat-icon class="mat-24">highlight_off</mat-icon>
|
||||
<span>{{ 'FORM.FIELD.REMOVE_FILE' | translate }}</span>
|
||||
</button>
|
||||
<div *ngIf="displayMenuOption('newVersion')">
|
||||
<button [adf-upload]="true" [mode]="['click']"
|
||||
(upload-files)="onUploadNewFileVersion($event, element);"
|
||||
id="{{'file-'+ element?.id +'-upload-new-version'}}" mat-menu-item>
|
||||
<mat-icon class="mat-24">file_upload</mat-icon>
|
||||
<span>{{ 'ADF_VERSION_LIST.ACTIONS.UPLOAD.TITLE' | translate }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
@@ -20,6 +20,7 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { LocalizedDatePipe, ThumbnailService } from '@alfresco/adf-core';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { NewVersionUploaderDialogData } from '@alfresco/adf-content-services';
|
||||
|
||||
export const RETRIEVE_METADATA_OPTION = 'retrieveMetadata';
|
||||
|
||||
@@ -56,6 +57,9 @@ export class FilePropertiesTableCloudComponent {
|
||||
@Output()
|
||||
downloadFile: EventEmitter<Node> = new EventEmitter<Node>();
|
||||
|
||||
@Output()
|
||||
uploadNewFileVersion: EventEmitter<NewVersionUploaderDialogData> = new EventEmitter<NewVersionUploaderDialogData>();
|
||||
|
||||
@Output()
|
||||
contentModelFileHandler: EventEmitter<any> = new EventEmitter<Node>();
|
||||
|
||||
@@ -76,6 +80,14 @@ export class FilePropertiesTableCloudComponent {
|
||||
this.downloadFile.emit(file);
|
||||
}
|
||||
|
||||
onUploadNewFileVersion(customEvent: any, node: Node){
|
||||
const newVersionUploaderDialogData: NewVersionUploaderDialogData = {
|
||||
file: customEvent.detail.files[0].file,
|
||||
node
|
||||
};
|
||||
this.uploadNewFileVersion.emit(newVersionUploaderDialogData);
|
||||
}
|
||||
|
||||
contentModelFormFileHandler(file?: any) {
|
||||
this.contentModelFileHandler.emit(file);
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ import { mergeMap } from 'rxjs/operators';
|
||||
import { WidgetComponent, LogService, FormService, ThumbnailService, NotificationService } from '@alfresco/adf-core';
|
||||
import { ProcessCloudContentService } from '../../../services/process-cloud-content.service';
|
||||
import { FileSourceTypes, DestinationFolderPathType } from '../../../models/form-cloud-representation.model';
|
||||
import { VersionManagerUploadData } from '@alfresco/adf-content-services';
|
||||
|
||||
@Component({
|
||||
selector: 'upload-cloud-widget',
|
||||
@@ -78,6 +79,13 @@ export class UploadCloudWidgetComponent extends WidgetComponent implements OnIni
|
||||
}
|
||||
}
|
||||
|
||||
replaceOldFileVersionWithNew(versionManagerData: VersionManagerUploadData) {
|
||||
const currentUploadedFileIndex = this.uploadedFiles.findIndex(file => file.name === versionManagerData.currentVersion.name);
|
||||
this.uploadedFiles[currentUploadedFileIndex] = { ...versionManagerData.newVersion.value.entry};
|
||||
this.field.value = [...this.uploadedFiles];
|
||||
this.field.form.values[this.field.id] = [...this.uploadedFiles];
|
||||
}
|
||||
|
||||
onFileChanged(event: any) {
|
||||
const files: File[] = [];
|
||||
const filesSaved: Node[] = [];
|
||||
|
@@ -24,7 +24,7 @@ import { MaterialModule } from '../material.module';
|
||||
import { FormCloudComponent } from './components/form-cloud.component';
|
||||
import { FormDefinitionSelectorCloudComponent } from './components/form-definition-selector-cloud.component';
|
||||
import { FormCustomOutcomesComponent } from './components/form-cloud-custom-outcomes.component';
|
||||
import { ContentMetadataModule, ContentNodeSelectorModule } from '@alfresco/adf-content-services';
|
||||
import { ContentMetadataModule, ContentNodeSelectorModule, UploadModule } from '@alfresco/adf-content-services';
|
||||
|
||||
import { DateCloudWidgetComponent } from './components/widgets/date/date-cloud.widget';
|
||||
import { DropdownCloudWidgetComponent } from './components/widgets/dropdown/dropdown-cloud.widget';
|
||||
@@ -51,7 +51,8 @@ import { FilePropertiesTableCloudComponent } from './components/widgets/attach-f
|
||||
ContentNodeSelectorModule,
|
||||
PeopleCloudModule,
|
||||
GroupCloudModule,
|
||||
ContentMetadataModule
|
||||
ContentMetadataModule,
|
||||
UploadModule
|
||||
],
|
||||
declarations: [
|
||||
FormCloudComponent,
|
||||
|
Reference in New Issue
Block a user