mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ASF-1227] new adf-node-permission directive (#2154)
* directive implementation * update docs * unit tests and api docs * code improvements * simplify code * update type def and docs
This commit is contained in:
parent
152e7805bc
commit
91ef0b6947
@ -30,7 +30,9 @@
|
||||
<button md-icon-button (click)="onCreateFolderClicked($event)">
|
||||
<md-icon>create_new_folder</md-icon>
|
||||
</button>
|
||||
<button md-icon-button>
|
||||
<button md-icon-button
|
||||
adf-node-permission="delete"
|
||||
[adf-nodes]="documentList.selection">
|
||||
<md-icon>delete</md-icon>
|
||||
</button>
|
||||
|
||||
|
@ -90,6 +90,11 @@ You should see result similar to the following one:
|
||||
|
||||
For more details about the [toolbar](src/components/toolbar/toolbar.md).
|
||||
|
||||
| Feature | Notes | Docs |
|
||||
| --- | --- | --- |
|
||||
| toolbar | toolbar component | [Docs](src/components/toolbar/toolbar.md) |
|
||||
| node-permission | disable elements based on node permissions | [Docs](src/directives/node-permission.md)
|
||||
|
||||
## Upload Directive
|
||||
|
||||
Allows your components or common HTML elements reacting on File drag and drop in order to upload content.
|
||||
|
@ -98,6 +98,7 @@ export { DiscoveryApiService } from './src/services/discovery-api.service';
|
||||
|
||||
import { DataColumnListComponent } from './src/components/data-column/data-column-list.component';
|
||||
import { DataColumnComponent } from './src/components/data-column/data-column.component';
|
||||
import { NodePermissionDirective } from './src/directives/node-permission.directive';
|
||||
import { UploadDirective } from './src/directives/upload.directive';
|
||||
import { FileSizePipe } from './src/pipes/file-size.pipe';
|
||||
import { HighlightPipe } from './src/pipes/text-highlight.pipe';
|
||||
@ -209,6 +210,7 @@ export function createTranslateLoader(http: Http, logService: LogService) {
|
||||
declarations: [
|
||||
...obsoleteMdlDirectives(),
|
||||
UploadDirective,
|
||||
NodePermissionDirective,
|
||||
DataColumnComponent,
|
||||
DataColumnListComponent,
|
||||
FileSizePipe,
|
||||
@ -229,6 +231,7 @@ export function createTranslateLoader(http: Http, logService: LogService) {
|
||||
ToolbarModule,
|
||||
...obsoleteMdlDirectives(),
|
||||
UploadDirective,
|
||||
NodePermissionDirective,
|
||||
DataColumnComponent,
|
||||
DataColumnListComponent,
|
||||
FileSizePipe,
|
||||
|
@ -0,0 +1,112 @@
|
||||
/*!
|
||||
* @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 { ElementRef, SimpleChange } from '@angular/core';
|
||||
import { AlfrescoContentService } from './../services/alfresco-content.service';
|
||||
import { NodePermissionDirective } from './node-permission.directive';
|
||||
|
||||
describe('NodePermissionDirective', () => {
|
||||
|
||||
it('updates element once it is loaded', () => {
|
||||
const directive = new NodePermissionDirective(null, null, null);
|
||||
spyOn(directive, 'updateElement').and.stub();
|
||||
|
||||
directive.ngAfterViewInit();
|
||||
|
||||
expect(directive.updateElement).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('updates element on nodes change', () => {
|
||||
const directive = new NodePermissionDirective(null, null, null);
|
||||
spyOn(directive, 'updateElement').and.stub();
|
||||
|
||||
const nodes = [{}, {}];
|
||||
const change = new SimpleChange([], nodes, false);
|
||||
directive.ngOnChanges({ nodes: change });
|
||||
|
||||
expect(directive.updateElement).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('updates element only on subsequent change', () => {
|
||||
const directive = new NodePermissionDirective(null, null, null);
|
||||
spyOn(directive, 'updateElement').and.stub();
|
||||
|
||||
const nodes = [{}, {}];
|
||||
const change = new SimpleChange([], nodes, true);
|
||||
directive.ngOnChanges({ nodes: change });
|
||||
|
||||
expect(directive.updateElement).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('enables decorated element', () => {
|
||||
const renderer = jasmine.createSpyObj('renderer', ['removeAttribute']);
|
||||
const elementRef = new ElementRef({});
|
||||
const directive = new NodePermissionDirective(elementRef, renderer, null);
|
||||
|
||||
directive.enableElement();
|
||||
|
||||
expect(renderer.removeAttribute).toHaveBeenCalledWith(elementRef.nativeElement, 'disabled');
|
||||
});
|
||||
|
||||
it('disables decorated element', () => {
|
||||
const renderer = jasmine.createSpyObj('renderer', ['setAttribute']);
|
||||
const elementRef = new ElementRef({});
|
||||
const directive = new NodePermissionDirective(elementRef, renderer, null);
|
||||
|
||||
directive.disableElement();
|
||||
|
||||
expect(renderer.setAttribute).toHaveBeenCalledWith(elementRef.nativeElement, 'disabled', 'true');
|
||||
});
|
||||
|
||||
it('disables element when nodes not available', () => {
|
||||
const directive = new NodePermissionDirective(null, null, null);
|
||||
spyOn(directive, 'disableElement').and.stub();
|
||||
|
||||
directive.nodes = null;
|
||||
expect(directive.updateElement()).toBeFalsy();
|
||||
|
||||
directive.nodes = [];
|
||||
expect(directive.updateElement()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('enables element when all nodes have expected permission', () => {
|
||||
const contentService = new AlfrescoContentService(null, null, null);
|
||||
spyOn(contentService, 'hasPermission').and.returnValue(true);
|
||||
|
||||
const directive = new NodePermissionDirective(null, null, contentService);
|
||||
spyOn(directive, 'enableElement').and.stub();
|
||||
|
||||
directive.nodes = <any> [{}, {}];
|
||||
|
||||
expect(directive.updateElement()).toBeTruthy();
|
||||
expect(directive.enableElement).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('disables element when one of the nodes have no permission', () => {
|
||||
const contentService = new AlfrescoContentService(null, null, null);
|
||||
spyOn(contentService, 'hasPermission').and.returnValue(false);
|
||||
|
||||
const directive = new NodePermissionDirective(null, null, contentService);
|
||||
spyOn(directive, 'disableElement').and.stub();
|
||||
|
||||
directive.nodes = <any> [{}, {}];
|
||||
|
||||
expect(directive.updateElement()).toBeFalsy();
|
||||
expect(directive.disableElement).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
@ -0,0 +1,100 @@
|
||||
/*!
|
||||
* @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 { AfterViewInit, Directive, ElementRef, Input, OnChanges, Renderer2, SimpleChanges } from '@angular/core';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
import { AlfrescoContentService } from './../services/alfresco-content.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-node-permission]'
|
||||
})
|
||||
export class NodePermissionDirective implements OnChanges, AfterViewInit {
|
||||
|
||||
@Input('adf-node-permission')
|
||||
permission: string = null;
|
||||
|
||||
@Input('adf-nodes')
|
||||
nodes: MinimalNodeEntity[] = [];
|
||||
|
||||
constructor(private elementRef: ElementRef,
|
||||
private renderer: Renderer2,
|
||||
private contentService: AlfrescoContentService) {
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.updateElement();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.nodes && !changes.nodes.firstChange) {
|
||||
this.updateElement();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates disabled state for the decorated elememtn
|
||||
*
|
||||
* @returns {boolean} True if decorated element got disabled, otherwise False
|
||||
* @memberof NodePermissionDirective
|
||||
*/
|
||||
updateElement(): boolean {
|
||||
let enable = this.hasPermission(this.nodes, this.permission);
|
||||
|
||||
if (enable) {
|
||||
this.enableElement();
|
||||
} else {
|
||||
this.disableElement();
|
||||
}
|
||||
|
||||
return enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables decorated element
|
||||
*
|
||||
* @memberof NodePermissionDirective
|
||||
*/
|
||||
enableElement(): void {
|
||||
this.renderer.removeAttribute(this.elementRef.nativeElement, 'disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables decorated element
|
||||
*
|
||||
* @memberof NodePermissionDirective
|
||||
*/
|
||||
disableElement(): void {
|
||||
this.renderer.setAttribute(this.elementRef.nativeElement, 'disabled', 'true');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether all nodes have a particular permission
|
||||
*
|
||||
* @param {MinimalNodeEntity[]} nodes Node collection to check
|
||||
* @param {string} permission Permission to check for each node
|
||||
* @returns {boolean} True if all nodes have provided permission, otherwise False
|
||||
* @memberof NodePermissionDirective
|
||||
*/
|
||||
hasPermission(nodes: MinimalNodeEntity[], permission: string): boolean {
|
||||
if (nodes && nodes.length > 0) {
|
||||
return nodes.every(node => this.contentService.hasPermission(node.entry, permission));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
# Node Permission Directive
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
The best example to show `NodePermissionDirective` in action is by binding DocumentList selection property to a toolbar button.
|
||||
|
||||
For example the "Delete" button should be disabled if no selection is present or if user has no rights to delete at least one node in the selection.
|
||||
|
||||
```html
|
||||
<adf-toolbar title="toolbar example">
|
||||
<button md-icon-button
|
||||
adf-node-permission="delete"
|
||||
[adf-nodes]="documentList.selection">
|
||||
<md-icon>delete</md-icon>
|
||||
</button>
|
||||
</adf-toolbar>
|
||||
|
||||
<adf-document-list #documentList ...>
|
||||
...
|
||||
</adf-document-list>
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| adf-node-permission | string | null | Node permission to check |
|
||||
| adf-nodes | MinimalNodeEntity[] | [] | Nodes to check permission for |
|
Loading…
x
Reference in New Issue
Block a user