[ADF-2368] Version manager update (#3058)

* Add auto file renaming in FE side

* Add error handling, file type restriction

* Documentation

* Fix ts-lint error

* Test the service

* Fix fdescribe...
This commit is contained in:
Popovics András 2018-03-09 23:55:24 +01:00 committed by Eugenio Romano
parent 4ee7cc0870
commit 8859d3466e
15 changed files with 150 additions and 12 deletions

View File

@ -9,7 +9,7 @@
<adf-info-drawer-tab label="Versions">
<mat-card>
<mat-card-content>
<adf-version-manager [node]="node">
<adf-version-manager [node]="node" (uploadError)="uploadError($event)">
</adf-version-manager>
</mat-card-content>
</mat-card>

View File

@ -18,6 +18,7 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { MatSnackBar } from '@angular/material';
@Component({
selector: 'app-file-view',
@ -30,6 +31,7 @@ export class FileViewComponent implements OnInit {
constructor(
private router: Router,
private route: ActivatedRoute,
private snackBar: MatSnackBar,
private apiService: AlfrescoApiService) {}
ngOnInit() {
@ -51,4 +53,7 @@ export class FileViewComponent implements OnInit {
});
}
uploadError(errorMessage: string) {
this.snackBar.open(errorMessage, '', { duration: 4000 });
}
}

View File

@ -1,6 +1,6 @@
<header mat-dialog-title>{{'VERSION.DIALOG.TITLE' | translate}}</header>
<section mat-dialog-content>
<adf-version-manager [node]="contentEntry"></adf-version-manager>
<adf-version-manager [node]="contentEntry" (uploadError)="uploadError($event)"></adf-version-manager>
</section>
<footer mat-dialog-actions fxLayout="row" fxLayoutAlign="end center">
<button mat-button (click)="close()">{{'VERSION.DIALOG.CLOSE' | translate}}</button>

View File

@ -18,6 +18,7 @@
import { Component, Inject, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
import { MatSnackBar } from '@angular/material';
@Component({
templateUrl: './version-manager-dialog-adapter.component.html',
@ -28,10 +29,15 @@ export class VersionManagerDialogAdapterComponent {
public contentEntry: MinimalNodeEntryEntity;
constructor(@Inject(MAT_DIALOG_DATA) data: any,
private snackBar: MatSnackBar,
private containingDialog?: MatDialogRef<VersionManagerDialogAdapterComponent>) {
this.contentEntry = data.contentEntry;
}
uploadError(errorMessage: string) {
this.snackBar.open(errorMessage, '', { duration: 4000 });
}
close() {
this.containingDialog.close();
}

View File

@ -27,6 +27,7 @@ import {
MatListModule,
MatMenuModule,
MatToolbarModule,
MatSnackBarModule,
MatExpansionModule
} from '@angular/material';
@ -41,6 +42,7 @@ const MATERIAL_MODULES = [
MatListModule,
MatMenuModule,
MatToolbarModule,
MatSnackBarModule,
MatExpansionModule
];

View File

@ -2,12 +2,12 @@
Added: v2.0.0
Status: Active
---
# Upload Button Component
# Upload Button Components
## Upload Button Component
Activates a file upload.
## Basic Usage
```html
<adf-upload-button
[rootFolderId]="-my-"
@ -43,6 +43,41 @@ Activates a file upload.
| createFolder | `EventEmitter<{}>` | Emitted when a folder is created. |
| permissionEvent | `EventEmitter<PermissionModel>` | Emitted when delete permission is missing. |
## Upload Version Button Component (Workaround)
Activates a file version upload.
Until further backend API improvements, this component is meant to be used to enrich the feature of node version uploading and to decrease the restrictions currently applied to the node version upload.
```html
<adf-upload-version-button
staticTitle="Upload new version"
[node]="node"
[rootFolderId]="node.parentId"
[versioning]="true"
(success)="onUploadSuccess($event)"
(error)="onUploadError($event)">
</adf-upload-version-button>
```
### Properties
Since UploadVersionButtonComponent extends UploadButtonComponent, the properties are the same. Note that some properties doesn't make sense in case of version upload button, thus are just simply ignored. For the version upload button the **node** (which is about to be versioned) is a mandatory input parameter.
### Events
Since UploadVersionButtonComponent extends UploadButtonComponent the properties are the same.
### Restrictions
At the moment the API only allows new version uploads for a node, if the name of the new version is exactly the same as the old version (**and most importantly the extension**). Because of it, this workaround component uploads the chosen file with the same name as what the original file had (that is the reason, the **node** is a mandatory dependency for this component).
So at the end what this component can and can not do:
**Can**:
- upload a new version from the same file extension regardless of the file name.
**Can not**:
- upload a new version which has a different file extension, than what the originally uploaded file had. (an error message is emitted on the error EventEmitter of the component).
## Details
### How to show notification message with no permission

View File

@ -104,6 +104,12 @@
"UPLOAD_FILE": "Upload file",
"UPLOAD_FOLDER": "Upload folder"
},
"VERSION": {
"MESSAGES": {
"NO_ACCEPTED_FILE_TYPES": "Please note that setting of acceptedFilesType has no effect for new version upload. File type will be the same as the original file's.",
"INCOMPATIBLE_VERSION": "Only files from the same type are allowed to be uploaded as a new version."
}
},
"MESSAGES": {
"UPLOAD_CANCELED": "Upload canceled",
"UPLOAD_COMPLETED": "Uploaded {{ completed }} / {{ total }}",

View File

@ -114,9 +114,10 @@ export class UploadButtonComponent implements OnInit, OnChanges, NodePermissionS
private permissionValue: Subject<boolean> = new Subject<boolean>();
constructor(private uploadService: UploadService,
private translateService: TranslationService,
private logService: LogService,
private apiService: AlfrescoApiService) {
private apiService: AlfrescoApiService,
protected translateService: TranslationService,
protected logService: LogService
) {
}
ngOnInit() {
@ -181,7 +182,7 @@ export class UploadButtonComponent implements OnInit, OnChanges, NodePermissionS
*
* @param file
*/
private createFileModel(file: File): FileModel {
protected createFileModel(file: File): FileModel {
return new FileModel(file, {
newVersion: this.versioning,
parentId: this.rootFolderId,
@ -194,7 +195,7 @@ export class UploadButtonComponent implements OnInit, OnChanges, NodePermissionS
*
* @param file FileModel
*/
private isFileAcceptable(file: FileModel): boolean {
protected isFileAcceptable(file: FileModel): boolean {
if (this.acceptedFilesType === '*') {
return true;
}

View File

@ -0,0 +1,58 @@
/*!
* @license
* Copyright 2016 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 { Component, forwardRef, Input, OnChanges, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
import { UploadButtonComponent } from './upload-button.component';
import { FileModel, EXTENDIBLE_COMPONENT } from '@alfresco/adf-core';
@Component({
selector: 'adf-upload-version-button',
templateUrl: './upload-button.component.html',
styleUrls: ['./upload-button.component.scss'],
viewProviders: [
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadVersionButtonComponent) }
],
encapsulation: ViewEncapsulation.None
})
export class UploadVersionButtonComponent extends UploadButtonComponent implements OnChanges {
@Input()
node: MinimalNodeEntryEntity;
ngOnChanges(changes: SimpleChanges) {
super.ngOnChanges(changes);
if (changes['acceptedFilesType']) {
const message = this.translateService.instant('FILE_UPLOAD.VERSION.MESSAGES.NO_ACCEPTED_FILE_TYPES');
this.logService.error(message);
}
this.acceptedFilesType = '.' + this.node.name.split('.').pop();
}
protected createFileModel(file: File): FileModel {
const fileModel = super.createFileModel(file);
fileModel.options.newVersionBaseName = this.node.name;
if (!this.isFileAcceptable(fileModel)) {
const message = this.translateService.instant('FILE_UPLOAD.VERSION.MESSAGES.INCOMPATIBLE_VERSION');
this.error.emit(message);
}
return fileModel;
}
}

View File

@ -16,6 +16,7 @@
*/
export * from './components/upload-button.component';
export * from './components/upload-version-button.component';
export * from './components/file-uploading-dialog.component';
export * from './components/upload-drag-area.component';
export * from './components/file-uploading-list.component';

View File

@ -24,6 +24,7 @@ import { FileUploadingDialogComponent } from './components/file-uploading-dialog
import { FileUploadingListRowComponent } from './components/file-uploading-list-row.component';
import { FileUploadingListComponent } from './components/file-uploading-list.component';
import { UploadButtonComponent } from './components/upload-button.component';
import { UploadVersionButtonComponent } from './components/upload-version-button.component';
import { UploadDragAreaComponent } from './components/upload-drag-area.component';
import { PipeModule } from '@alfresco/adf-core';
@ -40,6 +41,7 @@ import { FileDraggableDirective } from './directives/file-draggable.directive';
FileDraggableDirective,
UploadDragAreaComponent,
UploadButtonComponent,
UploadVersionButtonComponent,
FileUploadingDialogComponent,
FileUploadingListComponent,
FileUploadingListRowComponent
@ -48,6 +50,7 @@ import { FileDraggableDirective } from './directives/file-draggable.directive';
FileDraggableDirective,
UploadDragAreaComponent,
UploadButtonComponent,
UploadVersionButtonComponent,
FileUploadingDialogComponent,
FileUploadingListComponent,
FileUploadingListRowComponent

View File

@ -1,10 +1,11 @@
<adf-upload-button
<adf-upload-version-button
data-automation-id="adf-new-version-file-upload"
class="adf-new-version-file-upload"
staticTitle="Upload new version"
[node]="node"
[rootFolderId]="node.parentId"
tooltip="Restriction: upload file with the same name to create a new version of it"
[versioning]="true"
(success)="onUploadSuccess($event)"
(error)="onUploadError($event)">
</adf-upload-button>
</adf-upload-version-button>

View File

@ -23,6 +23,7 @@ export interface FileUploadProgress {
export interface FileUploadOptions {
newVersion?: boolean;
newVersionBaseName?: string;
parentId?: string;
path?: string;
}

View File

@ -164,6 +164,20 @@ describe('UploadService', () => {
expect(jasmine.Ajax.requests.mostRecent().params.has('majorVersion')).toBe(true);
});
it('If newVersionBaseName is set, name should be a param', () => {
let emitter = new EventEmitter();
const filesFake = new FileModel(<File> { name: 'fake-name', size: 10 }, {
newVersion: true,
newVersionBaseName: 'name-under-test'
});
service.addToQueue(filesFake);
service.uploadFilesInTheQueue(emitter);
expect(jasmine.Ajax.requests.mostRecent().params.has('name')).toBe(true);
expect(jasmine.Ajax.requests.mostRecent().params.get('name')).toBe('name-under-test');
});
it('should use custom root folder ID given to the service', (done) => {
let emitter = new EventEmitter();

View File

@ -164,6 +164,11 @@ export class UploadService {
} else {
opts.autoRename = true;
}
if (file.options.newVersionBaseName) {
opts.name = file.options.newVersionBaseName;
}
return this.apiService.getInstance().upload.uploadFile(
file.file,
file.options.path,