mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-1188] Upload related components, unify interfaces, deprecate disableWithNoPermission (#2216)
* Deprecate enabled input property in UploadDragAreaComponent * Refactoring about disabled property * using adf-node-permission directive, deprecating disableWithNoPermission * Parent component access from directive * Upliad drag area component uses the directive also * Usage of property instead of helper method in the NodePermissionSubjects * Fix small issues * Update readme files
This commit is contained in:
committed by
Mario Romano
parent
9cd188aa4f
commit
ac55704220
@@ -6,7 +6,8 @@
|
||||
<alfresco-upload-drag-area
|
||||
[parentId]="documentList.currentFolderId"
|
||||
[versioning]="versioning"
|
||||
[enabled]="documentList.hasCreatePermission()">
|
||||
[adf-node-permission]="'create'"
|
||||
[adf-nodes]="getCurrentDocumentListNode()">
|
||||
<div *ngIf="errorMessage" class="error-message">
|
||||
<button (click)="resetError()" md-icon-button>
|
||||
<md-icon>highlight_off</md-icon>
|
||||
@@ -275,7 +276,8 @@
|
||||
[multipleFiles]="multipleFileUpload"
|
||||
[uploadFolders]="folderUpload"
|
||||
[versioning]="versioning"
|
||||
[disableWithNoPermission]="disableWithNoPermission"
|
||||
[adf-node-permission]="'create'"
|
||||
[adf-nodes]="getCurrentDocumentListNode()"
|
||||
(permissionEvent)="handlePermissionError($event)">
|
||||
</alfresco-upload-button>
|
||||
</div>
|
||||
@@ -290,7 +292,8 @@
|
||||
[multipleFiles]="multipleFileUpload"
|
||||
[uploadFolders]="folderUpload"
|
||||
[versioning]="versioning"
|
||||
[disableWithNoPermission]="disableWithNoPermission"
|
||||
[adf-node-permission]="'create'"
|
||||
[adf-nodes]="getCurrentDocumentListNode()"
|
||||
(permissionEvent)="handlePermissionError($event)">
|
||||
</alfresco-upload-button>
|
||||
</div>
|
||||
|
@@ -143,6 +143,14 @@ export class FilesComponent implements OnInit {
|
||||
// this.permissionsStyle.push(new PermissionStyleModel('document-list__disable', PermissionsEnum.NOT_CREATE, false, true));
|
||||
}
|
||||
|
||||
getCurrentDocumentListNode(): MinimalNodeEntity[] {
|
||||
if (this.documentList.folderNode) {
|
||||
return [ { entry: this.documentList.folderNode } ];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
onNavigationError(err: any) {
|
||||
if (err) {
|
||||
this.errorMessage = err.message || 'Navigation error';
|
||||
|
@@ -127,11 +127,13 @@ export { CardViewModule } from './src/components/view/card-view.module';
|
||||
export { CollapsableModule } from './src/components/collapsable/collapsable.module';
|
||||
export { CardViewItem } from './src/interface/card-view-item.interface';
|
||||
export { TimeAgoPipe } from './src/pipes/time-ago.pipe';
|
||||
export { EXTENDIBLE_COMPONENT } from './src/interface/injection.tokens';
|
||||
|
||||
export * from './src/components/data-column/data-column.component';
|
||||
export * from './src/components/data-column/data-column-list.component';
|
||||
export * from './src/directives/upload.directive';
|
||||
export * from './src/directives/highlight.directive';
|
||||
export * from './src/directives/node-permission.directive';
|
||||
export * from './src/utils/index';
|
||||
export * from './src/events/base.event';
|
||||
export * from './src/events/base-ui.event';
|
||||
|
@@ -15,12 +15,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ElementRef, SimpleChange } from '@angular/core';
|
||||
import { Component, ElementRef, SimpleChange } from '@angular/core';
|
||||
import { AlfrescoContentService } from './../services/alfresco-content.service';
|
||||
import { NodePermissionDirective } from './node-permission.directive';
|
||||
import { NodePermissionDirective, NodePermissionSubject } from './node-permission.directive';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-text-subject'
|
||||
})
|
||||
class TestComponent implements NodePermissionSubject {
|
||||
disabled: boolean = false;
|
||||
}
|
||||
|
||||
describe('NodePermissionDirective', () => {
|
||||
|
||||
describe('HTML nativeElement as subject', () => {
|
||||
|
||||
it('updates element once it is loaded', () => {
|
||||
const directive = new NodePermissionDirective(null, null, null);
|
||||
spyOn(directive, 'updateElement').and.stub();
|
||||
@@ -108,5 +117,36 @@ describe('NodePermissionDirective', () => {
|
||||
expect(directive.updateElement()).toBeFalsy();
|
||||
expect(directive.disableElement).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Angular component as subject', () => {
|
||||
|
||||
it('disables decorated component', () => {
|
||||
const contentService = new AlfrescoContentService(null, null, null);
|
||||
spyOn(contentService, 'hasPermission').and.returnValue(false);
|
||||
|
||||
let testComponent = new TestComponent();
|
||||
testComponent.disabled = false;
|
||||
const directive = new NodePermissionDirective(null, null, contentService, testComponent);
|
||||
directive.nodes = <any> [{}, {}];
|
||||
|
||||
directive.updateElement();
|
||||
|
||||
expect(testComponent.disabled).toBeTruthy();
|
||||
});
|
||||
|
||||
it('enables decorated component', () => {
|
||||
const contentService = new AlfrescoContentService(null, null, null);
|
||||
spyOn(contentService, 'hasPermission').and.returnValue(true);
|
||||
|
||||
let testComponent = new TestComponent();
|
||||
testComponent.disabled = true;
|
||||
const directive = new NodePermissionDirective(null, null, contentService, testComponent);
|
||||
directive.nodes = <any> [{}, {}];
|
||||
|
||||
directive.updateElement();
|
||||
|
||||
expect(testComponent.disabled).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -15,10 +15,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, Directive, ElementRef, Input, OnChanges, Renderer2, SimpleChanges } from '@angular/core';
|
||||
import { AfterViewInit, Directive, ElementRef, Host, Inject, Input, OnChanges, Optional, Renderer2, SimpleChanges } from '@angular/core';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
import { EXTENDIBLE_COMPONENT } from './../interface/injection.tokens';
|
||||
import { AlfrescoContentService } from './../services/alfresco-content.service';
|
||||
|
||||
export interface NodePermissionSubject {
|
||||
disabled: boolean;
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-node-permission]'
|
||||
})
|
||||
@@ -32,7 +37,11 @@ export class NodePermissionDirective implements OnChanges, AfterViewInit {
|
||||
|
||||
constructor(private elementRef: ElementRef,
|
||||
private renderer: Renderer2,
|
||||
private contentService: AlfrescoContentService) {
|
||||
private contentService: AlfrescoContentService,
|
||||
|
||||
@Host()
|
||||
@Optional()
|
||||
@Inject(EXTENDIBLE_COMPONENT) private parentComponent?: NodePermissionSubject) {
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
@@ -55,14 +64,30 @@ export class NodePermissionDirective implements OnChanges, AfterViewInit {
|
||||
let enable = this.hasPermission(this.nodes, this.permission);
|
||||
|
||||
if (enable) {
|
||||
this.enableElement();
|
||||
this.enable();
|
||||
} else {
|
||||
this.disableElement();
|
||||
this.disable();
|
||||
}
|
||||
|
||||
return enable;
|
||||
}
|
||||
|
||||
private enable(): void {
|
||||
if (this.parentComponent) {
|
||||
this.parentComponent.disabled = false;
|
||||
} else {
|
||||
this.enableElement();
|
||||
}
|
||||
}
|
||||
|
||||
private disable(): void {
|
||||
if (this.parentComponent) {
|
||||
this.parentComponent.disabled = true;
|
||||
} else {
|
||||
this.disableElement();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables decorated element
|
||||
*
|
||||
|
@@ -1,5 +1,19 @@
|
||||
# Node Permission Directive
|
||||
|
||||
<!-- markdown-toc start - Don't edit this section. npm run toc to generate it-->
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Properties](#properties)
|
||||
- [HTML element example](#html-element-example)
|
||||
- [Angular component example](#angular-component-example)
|
||||
* [Implementing the NodePermissionSubject interface](#implementing-the-nodepermissionsubject-interface)
|
||||
* [Defining your components as an EXTENDIBLE_COMPONENT parent component](#defining-your-components-as-an-extendible_component-parent-component)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
<!-- markdown-toc end -->
|
||||
|
||||
The `NodePermissionDirective` allows you to disable an HTML element or Angular component
|
||||
by taking a collection of the `MinimalNodeEntity` instances and checking the particular permission.
|
||||
|
||||
@@ -8,7 +22,14 @@ The decorated element will be disabled if:
|
||||
- there are no nodes in the collection
|
||||
- at least one of the nodes has no expected permission
|
||||
|
||||
## Basic example
|
||||
## Properties
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| adf-node-permission | [Permissions](https://github.com/Alfresco/alfresco-ng2-components/blob/master/ng2-components/ng2-alfresco-core/src/models/permissions.enum.ts) | null | Node permission to check (create, delete, update, updatePermissions, !create, !delete, !update, !updatePermissions)|
|
||||
| adf-nodes | MinimalNodeEntity[] | [] | Nodes to check permission for |
|
||||
|
||||
## HTML element example
|
||||
|
||||
The best example to show `NodePermissionDirective` in action is by binding DocumentList selection property to a toolbar button.
|
||||
|
||||
@@ -30,9 +51,47 @@ For example the "Delete" button should be disabled if no selection is present or
|
||||
|
||||
The button will become disabled by default, and is going to change its state once user selects/unselects one or multiple documents that current user has permission to delete.
|
||||
|
||||
## Properties
|
||||
## Angular component example
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| adf-node-permission | [Permissions](https://github.com/Alfresco/alfresco-ng2-components/blob/master/ng2-components/ng2-alfresco-core/src/models/permissions.enum.ts) | null | Node permission to check (create, delete, update, updatePermissions, !create, !delete, !update, !updatePermissions)|
|
||||
| adf-nodes | MinimalNodeEntity[] | [] | Nodes to check permission for |
|
||||
You can apply the directive on any angular component which implements the NodePermissionSubject interface. The upload drag area component can be a good candidate, since this one implements that interface. Applying the directive on an angular component is pretty much the same as applying it on an html element.
|
||||
|
||||
```html
|
||||
<alfresco-upload-drag-area
|
||||
[parentId]="..."
|
||||
[versioning]="..."
|
||||
[adf-node-permission]="'create'"
|
||||
[adf-nodes]="getCurrentDocumentListNode()">
|
||||
...
|
||||
</alfresco-upload-drag-area>
|
||||
```
|
||||
|
||||
When designing a component you want to work this directive with, you have two important things to care about.
|
||||
|
||||
### Implementing the NodePermissionSubject interface
|
||||
|
||||
The component has to implement the NodePermissionSubject interface which basically means it has to have a boolean **disabled** property. This is the property which will be set by the directive.
|
||||
|
||||
```js
|
||||
import { NodePermissionSubject } from 'ng2-alfresco-core';
|
||||
|
||||
@Component({...})
|
||||
export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
public disabled: boolean = false;
|
||||
}
|
||||
```
|
||||
|
||||
### Defining your components as an EXTENDIBLE_COMPONENT parent component
|
||||
|
||||
The directive will look up the component in the dependency injection tree, up to at most one step above the current DI level (@Host). Because of this, you have to provide your component with forward referencing as the EXTENDIBLE_COMPONENT.
|
||||
|
||||
```js
|
||||
import { EXTENDIBLE_COMPONENT } from 'ng2-alfresco-core';
|
||||
|
||||
@Component({
|
||||
...
|
||||
providers: [
|
||||
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadDragAreaComponent)}
|
||||
]
|
||||
})
|
||||
export class UploadDragAreaComponent implements NodePermissionSubject { ... }
|
||||
```
|
||||
|
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* @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, InjectionToken } from '@angular/core';
|
||||
|
||||
export const EXTENDIBLE_COMPONENT = new InjectionToken<Component>('extendible.component');
|
@@ -92,7 +92,7 @@ npm install ng2-alfresco-upload
|
||||
| parentId | string | empty | The ID of the root. It can be the nodeId if you are using the upload for the Content Service or taskId/processId for the Process Service. |
|
||||
| versioning | boolean | false | Versioning false is the default uploader behaviour and it renames the file using an integer suffix if there is a name clash. Versioning true to indicate that a major version should be created |
|
||||
| staticTitle | string | (predefined) | define the text of the upload button |
|
||||
| disableWithNoPermission | boolean | false | If the value is true and the user doesn't have the permission to delete the node the button will be disabled |
|
||||
| **(deprecated)** disableWithNoPermission ***use node permission directive from core instead*** | boolean | false | If the value is true and the user doesn't have the permission to delete the node the button will be disabled |
|
||||
| tooltip | string | | Custom tooltip |
|
||||
|
||||
### Events
|
||||
@@ -171,7 +171,8 @@ export class AppComponent {
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| enabled | boolean | true | Toggle component enabled state |
|
||||
| disabled | boolean | false | Toggle component disabled state |
|
||||
| **(deprecated)** enabled | boolean | true | Toggle component enabled state |
|
||||
| **(deprecated)** showNotificationBar | boolean | true | Hide/show notification bar. **Deprecated in 1.6.0: use UploadService events and NotificationService api instead.** |
|
||||
| rootFolderId | string | '-root-' | The ID of the root folder node. |
|
||||
| **(deprecated)** currentFolderPath | string | '/' | define the path where the files are uploaded. **Deprecated in 1.6.0: use rootFolderId instead.** |
|
||||
|
@@ -15,31 +15,47 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { Component, EventEmitter, forwardRef, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
import { AlfrescoApiService, AlfrescoTranslationService, FileModel, FileUtils, LogService, NotificationService, UploadService } from 'ng2-alfresco-core';
|
||||
import {
|
||||
AlfrescoApiService,
|
||||
AlfrescoTranslationService,
|
||||
EXTENDIBLE_COMPONENT,
|
||||
FileModel,
|
||||
FileUtils,
|
||||
LogService,
|
||||
NodePermissionSubject,
|
||||
NotificationService,
|
||||
UploadService
|
||||
} from 'ng2-alfresco-core';
|
||||
import { Observable, Subject } from 'rxjs/Rx';
|
||||
import { PermissionModel } from '../models/permissions.model';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-upload-button, alfresco-upload-button',
|
||||
templateUrl: './upload-button.component.html',
|
||||
styleUrls: ['./upload-button.component.css']
|
||||
styleUrls: ['./upload-button.component.css'],
|
||||
providers: [
|
||||
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadButtonComponent)}
|
||||
]
|
||||
})
|
||||
export class UploadButtonComponent implements OnInit, OnChanges {
|
||||
export class UploadButtonComponent implements OnInit, OnChanges, NodePermissionSubject {
|
||||
|
||||
/** @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead. */
|
||||
@Input()
|
||||
showNotificationBar: boolean = true;
|
||||
|
||||
/** @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already. */
|
||||
@Input()
|
||||
currentFolderPath: string = '/';
|
||||
|
||||
/** @deprecated Deprecated in 1.8.0, use the button with combination of adf-node-permission directive */
|
||||
@Input()
|
||||
disableWithNoPermission: boolean = false;
|
||||
|
||||
@Input()
|
||||
disabled: boolean = false;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof UploadButtonComponent
|
||||
*/
|
||||
@Input()
|
||||
showNotificationBar: boolean = true;
|
||||
|
||||
@Input()
|
||||
uploadFolders: boolean = false;
|
||||
|
||||
@@ -58,21 +74,9 @@ export class UploadButtonComponent implements OnInit, OnChanges {
|
||||
@Input()
|
||||
tooltip: string = null;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already.
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UploadDragAreaComponent
|
||||
*/
|
||||
@Input()
|
||||
currentFolderPath: string = '/';
|
||||
|
||||
@Input()
|
||||
rootFolderId: string = '-root-';
|
||||
|
||||
@Input()
|
||||
disableWithNoPermission: boolean = false;
|
||||
|
||||
@Output()
|
||||
onSuccess = new EventEmitter();
|
||||
|
||||
@@ -117,6 +121,7 @@ export class UploadButtonComponent implements OnInit, OnChanges {
|
||||
return this.disabled ? true : undefined;
|
||||
}
|
||||
|
||||
/** @deprecated Deprecated in 1.8.0, use the button with combination of adf-node-permission directive */
|
||||
isDisableWithNoPermission(): boolean {
|
||||
return !this.hasPermission && this.disableWithNoPermission ? true : undefined;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<div [file-draggable]="enabled" id="UploadBorder" class="upload-border"
|
||||
<div [file-draggable]="isDroppable()" id="UploadBorder" class="upload-border"
|
||||
(onFilesDropped)="onFilesDropped($event)"
|
||||
(onFilesEntityDropped)="onFilesEntityDropped($event)"
|
||||
(onFolderEntityDropped)="onFolderEntityDropped($event)"
|
||||
|
@@ -23,7 +23,8 @@ import { TranslationMock } from '../assets/translation.service.mock';
|
||||
import { FileDraggableDirective } from '../directives/file-draggable.directive';
|
||||
import { UploadDragAreaComponent } from './upload-drag-area.component';
|
||||
|
||||
let fakeShareDataRow = {
|
||||
function getFakeShareDataRow(allowableOperations = ['delete', 'update', 'create']) {
|
||||
return {
|
||||
obj: {
|
||||
entry: {
|
||||
createdAt: '2017-06-04T04:32:15.597Z',
|
||||
@@ -49,14 +50,11 @@ let fakeShareDataRow = {
|
||||
name: 'pippo',
|
||||
id: '7462d28e-bd43-4b91-9e7b-0d71598680ac',
|
||||
nodeType: 'cm:folder',
|
||||
allowableOperations: [
|
||||
'delete',
|
||||
'update',
|
||||
'create'
|
||||
]
|
||||
allowableOperations
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
describe('UploadDragAreaComponent', () => {
|
||||
|
||||
@@ -100,6 +98,96 @@ describe('UploadDragAreaComponent', () => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
describe('When disabled', () => {
|
||||
|
||||
it('should NOT upload the list of files dropped', () => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
fixture.detectChanges();
|
||||
|
||||
const file = <File> {name: 'fake-name-1', size: 10, webkitRelativePath: 'fake-folder1/fake-name-1.json'};
|
||||
let filesList = [file];
|
||||
component.onFilesDropped(filesList);
|
||||
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should NOT upload the file dropped', () => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
fixture.detectChanges();
|
||||
|
||||
let itemEntity = {
|
||||
fullPath: '/folder-fake/file-fake.png',
|
||||
isDirectory: false,
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
component.onFilesEntityDropped(itemEntity);
|
||||
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should NOT upload the folder dropped', (done) => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
fixture.detectChanges();
|
||||
|
||||
let itemEntity = {
|
||||
isDirectory: true,
|
||||
createReader: () => {
|
||||
return {
|
||||
readEntries: (cb) => {
|
||||
cb([]);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
component.onFolderEntityDropped(itemEntity);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should NOT upload the files', () => {
|
||||
component.enabled = false;
|
||||
spyOn(uploadService, 'addToQueue');
|
||||
spyOn(uploadService, 'uploadFilesInTheQueue');
|
||||
|
||||
let fakeItem = {
|
||||
fullPath: '/folder-fake/file-fake.png',
|
||||
isDirectory: false,
|
||||
isFile: true,
|
||||
name: 'file-fake.png',
|
||||
file: (callbackFile) => {
|
||||
let fileFake = new File(['fakefake'], 'file-fake.png', {type: 'image/png'});
|
||||
callbackFile(fileFake);
|
||||
}
|
||||
};
|
||||
fixture.detectChanges();
|
||||
|
||||
let fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
|
||||
detail: { data: getFakeShareDataRow([]), files: [fakeItem] }
|
||||
});
|
||||
component.onUploadFiles(fakeCustomEvent);
|
||||
|
||||
expect(uploadService.addToQueue).not.toHaveBeenCalled();
|
||||
expect(uploadService.uploadFilesInTheQueue).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should upload the list of files dropped', (done) => {
|
||||
component.currentFolderPath = '/root-fake-/sites-fake/folder-fake';
|
||||
component.onSuccess = null;
|
||||
@@ -203,7 +291,7 @@ describe('UploadDragAreaComponent', () => {
|
||||
|
||||
let fakeCustomEvent: CustomEvent = new CustomEvent('CustomEvent', {
|
||||
detail: {
|
||||
data: fakeShareDataRow,
|
||||
data: getFakeShareDataRow(),
|
||||
files: [fakeItem]
|
||||
}
|
||||
});
|
||||
|
@@ -15,49 +15,59 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { AlfrescoTranslationService, FileInfo, FileModel, FileUtils, NotificationService, UploadService } from 'ng2-alfresco-core';
|
||||
import { Component, EventEmitter, forwardRef, Input, Output } from '@angular/core';
|
||||
import {
|
||||
AlfrescoTranslationService,
|
||||
EXTENDIBLE_COMPONENT,
|
||||
FileInfo,
|
||||
FileModel,
|
||||
FileUtils,
|
||||
NodePermissionSubject,
|
||||
NotificationService,
|
||||
UploadService
|
||||
} from 'ng2-alfresco-core';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-upload-drag-area, alfresco-upload-drag-area',
|
||||
templateUrl: './upload-drag-area.component.html',
|
||||
styleUrls: ['./upload-drag-area.component.css']
|
||||
styleUrls: ['./upload-drag-area.component.css'],
|
||||
providers: [
|
||||
{ provide: EXTENDIBLE_COMPONENT, useExisting: forwardRef(() => UploadDragAreaComponent)}
|
||||
]
|
||||
})
|
||||
export class UploadDragAreaComponent {
|
||||
export class UploadDragAreaComponent implements NodePermissionSubject {
|
||||
|
||||
/** @deprecated Deprecated in favor of disabled input property */
|
||||
@Input()
|
||||
enabled: boolean = true;
|
||||
set enabled(enabled: boolean) {
|
||||
console.warn('Deprecated: enabled input property should not be used for UploadDragAreaComponent. Please use disabled instead.');
|
||||
this.disabled = !enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead.
|
||||
*
|
||||
* @type {boolean}
|
||||
* @memberof UploadButtonComponent
|
||||
*/
|
||||
/** @deprecated Deprecated in favor of disabled input property */
|
||||
get enabled(): boolean {
|
||||
console.warn('Deprecated: enabled input property should not be used for UploadDragAreaComponent. Please use disabled instead.');
|
||||
return !this.disabled;
|
||||
}
|
||||
|
||||
/** @deprecated Deprecated in 1.6.0, you can use UploadService events and NotificationService api instead. */
|
||||
@Input()
|
||||
showNotificationBar: boolean = true;
|
||||
|
||||
@Input()
|
||||
versioning: boolean = false;
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already. Use rootFolderId instead.
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UploadDragAreaComponent
|
||||
*/
|
||||
/** @deprecated Deprecated in 1.6.0, this property is not used for couple of releases already. Use rootFolderId instead. */
|
||||
@Input()
|
||||
currentFolderPath: string = '/';
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated in 1.6.2, this property is not used for couple of releases already. Use parentId instead.
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof UploadDragAreaComponent
|
||||
*/
|
||||
/** @deprecated Deprecated in 1.6.2, this property is not used for couple of releases already. Use parentId instead. */
|
||||
@Input()
|
||||
rootFolderId: string = '-root-';
|
||||
|
||||
@Input()
|
||||
disabled: boolean = false;
|
||||
|
||||
@Input()
|
||||
versioning: boolean = false;
|
||||
|
||||
@Input()
|
||||
parentId: string;
|
||||
|
||||
@@ -69,38 +79,13 @@ export class UploadDragAreaComponent {
|
||||
private notificationService: NotificationService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 'upload-files' events raised by child components.
|
||||
* @param event DOM event
|
||||
*/
|
||||
onUploadFiles(event: CustomEvent) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
let isAllowed: boolean = this.isAllowed(event.detail.data.obj.entry);
|
||||
if (isAllowed) {
|
||||
let files: FileInfo[] = event.detail.files;
|
||||
if (files && files.length > 0) {
|
||||
let parentId = this.parentId || this.rootFolderId;
|
||||
if (event.detail.data && event.detail.data.obj.entry.isFolder) {
|
||||
parentId = event.detail.data.obj.entry.id || this.parentId || this.rootFolderId;
|
||||
}
|
||||
const fileModels = files.map(fileInfo => new FileModel(fileInfo.file, {
|
||||
newVersion: this.versioning,
|
||||
path: fileInfo.relativeFolder,
|
||||
parentId: parentId
|
||||
}));
|
||||
this.uploadFiles(fileModels, isAllowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when files are dropped in the drag area.
|
||||
*
|
||||
* @param {File[]} files - files dropped in the drag area.
|
||||
*/
|
||||
onFilesDropped(files: File[]): void {
|
||||
if (this.enabled && files.length) {
|
||||
if (!this.disabled && files.length) {
|
||||
const fileModels = files.map(file => new FileModel(file, {
|
||||
newVersion: this.versioning,
|
||||
path: '/',
|
||||
@@ -117,10 +102,11 @@ export class UploadDragAreaComponent {
|
||||
|
||||
/**
|
||||
* Called when the file are dropped in the drag area
|
||||
*
|
||||
* @param item - FileEntity
|
||||
*/
|
||||
onFilesEntityDropped(item: any): void {
|
||||
if (this.enabled) {
|
||||
if (!this.disabled) {
|
||||
item.file((file: File) => {
|
||||
const fileModel = new FileModel(file, {
|
||||
newVersion: this.versioning,
|
||||
@@ -138,10 +124,11 @@ export class UploadDragAreaComponent {
|
||||
|
||||
/**
|
||||
* Called when a folder are dropped in the drag area
|
||||
*
|
||||
* @param folder - name of the dropped folder
|
||||
*/
|
||||
onFolderEntityDropped(folder: any): void {
|
||||
if (this.enabled && folder.isDirectory) {
|
||||
if (!this.disabled && folder.isDirectory) {
|
||||
FileUtils.flattern(folder).then(entries => {
|
||||
let files = entries.map(entry => {
|
||||
return new FileModel(entry.file, {
|
||||
@@ -178,6 +165,7 @@ export class UploadDragAreaComponent {
|
||||
|
||||
/**
|
||||
* Show the error inside Notification bar
|
||||
*
|
||||
* @param Error message
|
||||
* @private
|
||||
*/
|
||||
@@ -185,8 +173,44 @@ export class UploadDragAreaComponent {
|
||||
this.notificationService.openSnackMessage(errorMessage, 3000);
|
||||
}
|
||||
|
||||
private uploadFiles(files: FileModel[], isAllowed: boolean): void {
|
||||
if (isAllowed && files.length) {
|
||||
/** Returns true or false considering the component options and node permissions */
|
||||
isDroppable(): boolean {
|
||||
return !this.disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 'upload-files' events raised by child components.
|
||||
*
|
||||
* @param event DOM event
|
||||
*/
|
||||
onUploadFiles(event: CustomEvent) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
let isAllowed: boolean = this.hasCreatePermission(event.detail.data.obj.entry);
|
||||
if (isAllowed) {
|
||||
let files: FileInfo[] = event.detail.files;
|
||||
if (files && files.length > 0) {
|
||||
let parentId = this.parentId || this.rootFolderId;
|
||||
if (event.detail.data && event.detail.data.obj.entry.isFolder) {
|
||||
parentId = event.detail.data.obj.entry.id || this.parentId || this.rootFolderId;
|
||||
}
|
||||
const fileModels = files.map(fileInfo => new FileModel(fileInfo.file, {
|
||||
newVersion: this.versioning,
|
||||
path: fileInfo.relativeFolder,
|
||||
parentId: parentId
|
||||
}));
|
||||
this.uploadFiles(fileModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the actual file uploading and show the notification
|
||||
*
|
||||
* @param files
|
||||
*/
|
||||
private uploadFiles(files: FileModel[]): void {
|
||||
if (files.length) {
|
||||
this.uploadService.addToQueue(...files);
|
||||
this.uploadService.uploadFilesInTheQueue(this.onSuccess);
|
||||
let latestFilesAdded = this.uploadService.getQueue();
|
||||
@@ -196,6 +220,11 @@ export class UploadDragAreaComponent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if "create" permission is present on the given node
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
private hasCreatePermission(node: any): boolean {
|
||||
let isPermitted = false;
|
||||
if (node && node['allowableOperations']) {
|
||||
@@ -204,8 +233,4 @@ export class UploadDragAreaComponent {
|
||||
}
|
||||
return isPermitted;
|
||||
}
|
||||
|
||||
private isAllowed(node: any) {
|
||||
return this.enabled || this.hasCreatePermission(node);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user