mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
#244 breadcrumb as a separate component (doclist only)
This commit is contained in:
parent
bf7414fc85
commit
e101f22e28
@ -3,6 +3,10 @@
|
||||
[currentFolderPath]="currentPath"
|
||||
[uploaddirectory]="currentPath"
|
||||
(onSuccess)="documentList.reload()">
|
||||
<alfresco-document-list-breadcrumb
|
||||
[currentFolderPath]="currentPath"
|
||||
[target]="documentList">
|
||||
</alfresco-document-list-breadcrumb>
|
||||
<alfresco-document-list
|
||||
#documentList
|
||||
[currentFolderPath]="currentPath"
|
||||
|
@ -48,7 +48,14 @@ import {
|
||||
<hr>
|
||||
<div class="container">
|
||||
|
||||
<alfresco-document-list #doclist>
|
||||
<alfresco-document-list-breadcrumb
|
||||
[currentFolderPath]="currentPath"
|
||||
[target]="documentList">
|
||||
</alfresco-document-list-breadcrumb>
|
||||
<alfresco-document-list
|
||||
#documentList
|
||||
[currentFolderPath]="currentPath"
|
||||
(folderChange)="onFolderChanged($event)">
|
||||
|
||||
<content-columns>
|
||||
<content-column source="$thumbnail" type="image"></content-column>
|
||||
@ -144,6 +151,7 @@ import {
|
||||
})
|
||||
class DocumentListDemo implements OnInit {
|
||||
|
||||
currentPath: string = '/';
|
||||
authenticated: boolean;
|
||||
|
||||
public host: string = 'http://devproducts-platform.alfresco.me';
|
||||
@ -202,6 +210,12 @@ class DocumentListDemo implements OnInit {
|
||||
this.authenticated = false;
|
||||
});
|
||||
}
|
||||
|
||||
onFolderChanged(event?: any) {
|
||||
if (event) {
|
||||
this.currentPath = event.path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap(DocumentListDemo, [
|
||||
|
@ -21,6 +21,7 @@ import { ContentColumnList } from './src/components/content-column-list';
|
||||
import { ContentAction } from './src/components/content-action';
|
||||
import { ContentActionList } from './src/components/content-action-list';
|
||||
import { EmptyFolderContent } from './src/components/empty-folder-content';
|
||||
import { DocumentListBreadcrumb } from './src/components/document-list-breadcrumb.component';
|
||||
|
||||
import { FolderActionsService } from './src/services/folder-actions.service';
|
||||
import { DocumentActionsService } from './src/services/document-actions.service';
|
||||
@ -33,6 +34,7 @@ export * from './src/components/content-column-list';
|
||||
export * from './src/components/content-action';
|
||||
export * from './src/components/content-action-list';
|
||||
export * from './src/components/empty-folder-content';
|
||||
export * from './src/components/document-list-breadcrumb.component';
|
||||
|
||||
// models
|
||||
export * from './src/models/column-sorting.model';
|
||||
@ -42,28 +44,14 @@ export * from './src/services/folder-actions.service';
|
||||
export * from './src/services/document-actions.service';
|
||||
export * from './src/services/alfresco.service';
|
||||
|
||||
export default {
|
||||
directives: [
|
||||
DocumentList,
|
||||
ContentColumn,
|
||||
ContentColumnList,
|
||||
ContentAction,
|
||||
ContentActionList
|
||||
],
|
||||
providers: [
|
||||
AlfrescoService,
|
||||
FolderActionsService,
|
||||
DocumentActionsService
|
||||
]
|
||||
};
|
||||
|
||||
export const DOCUMENT_LIST_DIRECTIVES: [any] = [
|
||||
DocumentList,
|
||||
ContentColumn,
|
||||
ContentColumnList,
|
||||
ContentAction,
|
||||
ContentActionList,
|
||||
EmptyFolderContent
|
||||
EmptyFolderContent,
|
||||
DocumentListBreadcrumb
|
||||
];
|
||||
|
||||
export const DOCUMENT_LIST_PROVIDERS: [any] = [
|
||||
|
@ -0,0 +1,25 @@
|
||||
/* breadcrumb */
|
||||
|
||||
:host .breadcrumb {
|
||||
text-align: left;
|
||||
padding: 8px 15px;
|
||||
list-style: none;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
:host .breadcrumb > li {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:host .breadcrumb > li+li:before {
|
||||
content: "/\00a0";
|
||||
padding: 0 0 0 5px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
:host .breadcrumb > .active {
|
||||
color: #777;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<ol data-automation-id="breadcrumb" class="breadcrumb">
|
||||
<li *ngFor="let r of route; let last = last" [class.active]="last" [ngSwitch]="last">
|
||||
<span *ngSwitchCase="true">{{r.name}}</span>
|
||||
<a *ngSwitchDefault
|
||||
href="#"
|
||||
[attr.data-automation-id]="'breadcrumb_' + r.name"
|
||||
(click)="onRoutePathClick(r, $event)">
|
||||
{{r.name}}
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
@ -0,0 +1,115 @@
|
||||
/*!
|
||||
* @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,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter
|
||||
} from '@angular/core';
|
||||
import { DocumentList } from './document-list';
|
||||
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
moduleId: __moduleName,
|
||||
selector: 'alfresco-document-list-breadcrumb',
|
||||
templateUrl: './document-list-breadcrumb.component.html',
|
||||
styleUrls: ['./document-list-breadcrumb.component.css']
|
||||
})
|
||||
export class DocumentListBreadcrumb {
|
||||
|
||||
private _currentFolderPath: string = '/';
|
||||
|
||||
get currentFolderPath(): string {
|
||||
return this._currentFolderPath;
|
||||
}
|
||||
|
||||
@Input()
|
||||
set currentFolderPath(val: string) {
|
||||
if (this._currentFolderPath !== val) {
|
||||
this._currentFolderPath = val;
|
||||
|
||||
if (val) {
|
||||
this.route = this.parsePath(val);
|
||||
} else {
|
||||
this.route = [ this.rootFolder ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Input()
|
||||
target: DocumentList;
|
||||
|
||||
private rootFolder: PathNode = {
|
||||
name: 'Root',
|
||||
path: '/'
|
||||
};
|
||||
|
||||
route: PathNode[] = [ this.rootFolder ];
|
||||
|
||||
@Output()
|
||||
navigate: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
onRoutePathClick(route: PathNode, e?: Event) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (route) {
|
||||
this.navigate.emit({
|
||||
value: {
|
||||
name: route.name,
|
||||
path: route.path
|
||||
}
|
||||
});
|
||||
|
||||
if (this.target) {
|
||||
this.target.changePath(route.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private parsePath(path: string): PathNode[] {
|
||||
let parts = path.split('/').filter(val => val ? true : false);
|
||||
|
||||
let result = [
|
||||
this.rootFolder
|
||||
];
|
||||
|
||||
let parentPath: string = this.rootFolder.path;
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
if (!parentPath.endsWith('/')) {
|
||||
parentPath += '/';
|
||||
}
|
||||
parentPath += parts[i];
|
||||
|
||||
result.push({
|
||||
name: parts[i],
|
||||
path: parentPath
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PathNode {
|
||||
name: string;
|
||||
path: string;
|
||||
}
|
@ -28,31 +28,7 @@
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* breadcrumb */
|
||||
|
||||
:host .breadcrumb {
|
||||
text-align: left;
|
||||
padding: 8px 15px;
|
||||
list-style: none;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
margin: 0 0 4px;
|
||||
}
|
||||
|
||||
:host .breadcrumb > li {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:host .breadcrumb > li+li:before {
|
||||
content: "/\00a0";
|
||||
padding: 0 0 0 5px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
:host .breadcrumb > .active {
|
||||
color: #777;
|
||||
}
|
||||
/* Empty folder */
|
||||
|
||||
:host .empty-folder-content {
|
||||
padding: 0 !important;
|
||||
|
@ -1,9 +1,3 @@
|
||||
<ol *ngIf="breadcrumb" data-automation-id="breadcrumb" class="breadcrumb">
|
||||
<li *ngFor="let r of route; let last = last" [class.active]="last" [ngSwitch]="last">
|
||||
<span *ngSwitchCase="true">{{r.name}}</span>
|
||||
<a *ngSwitchDefault href="#" [attr.data-automation-id]="'breadcrumb_' + r.name" (click)="goToRoute(r, $event)">{{r.name}}</a>
|
||||
</li>
|
||||
</ol>
|
||||
<table *ngIf="folder" class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -70,26 +70,6 @@ describe('DocumentList', () => {
|
||||
expect(documentList.columns[0]).toBe(column);
|
||||
});
|
||||
|
||||
it('should setup default root for breadcrumb', () => {
|
||||
documentList.ngOnInit();
|
||||
expect(documentList.route.length).toBe(1);
|
||||
expect(documentList.route[0]).toBe(documentList.rootFolder);
|
||||
});
|
||||
|
||||
it('should display custom root path', () => {
|
||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||
|
||||
let root = {
|
||||
name: '<root>',
|
||||
path: '<path>'
|
||||
};
|
||||
|
||||
documentList.currentFolderPath = root.path;
|
||||
documentList.rootFolder = root;
|
||||
documentList.ngOnInit();
|
||||
expect(documentList.displayFolderContent).toHaveBeenCalledWith(root.path);
|
||||
});
|
||||
|
||||
it('should fetch folder', () => {
|
||||
let folder = {
|
||||
'nodeRef': 'workspace://SpacesStore/8bb36efb-c26d-4d2b-9199-ab6922f53c28'
|
||||
@ -156,15 +136,6 @@ describe('DocumentList', () => {
|
||||
expect(action.handler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update current folder path', () => {
|
||||
expect(documentList.currentFolderPath).toBe(documentList.rootFolder.path);
|
||||
|
||||
let path = '<path>';
|
||||
documentList.displayFolderContent(path);
|
||||
|
||||
expect(documentList.currentFolderPath).toBe(path);
|
||||
});
|
||||
|
||||
it('should give no content actions for empty target', () => {
|
||||
let actions = documentList.getContentActions(null, 'button');
|
||||
expect(actions.length).toBe(0);
|
||||
@ -270,10 +241,6 @@ describe('DocumentList', () => {
|
||||
documentList.onItemClick(node);
|
||||
|
||||
expect(documentList.displayFolderContent).toHaveBeenCalledWith(path);
|
||||
|
||||
let routeEntry = documentList.route.pop();
|
||||
expect(routeEntry.name).toBe(node.entry.name);
|
||||
expect(routeEntry.path).toBe(path);
|
||||
});
|
||||
|
||||
it('should not display folder content when no target node provided', () => {
|
||||
|
@ -61,9 +61,6 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
||||
@Input('navigation-mode')
|
||||
navigationMode: string = 'dblclick'; // click|dblclick
|
||||
|
||||
@Input()
|
||||
breadcrumb: boolean = true;
|
||||
|
||||
@Input()
|
||||
thumbnails: boolean = false;
|
||||
|
||||
@ -79,16 +76,10 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
||||
@Output()
|
||||
preview: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
rootFolder = {
|
||||
name: 'Root',
|
||||
path: '/'
|
||||
};
|
||||
|
||||
@Input()
|
||||
currentFolderPath: string = this.DEFAULT_ROOT_FOLDER;
|
||||
|
||||
errorMessage;
|
||||
route: { name: string, path: string }[] = [];
|
||||
|
||||
actions: ContentActionModel[] = [];
|
||||
columns: ContentColumnModel[] = [];
|
||||
@ -180,7 +171,6 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
||||
|
||||
changePath(path: string) {
|
||||
this.currentFolderPath = path || this.DEFAULT_ROOT_FOLDER;
|
||||
this.route = this.parsePath(this.currentFolderPath);
|
||||
this.displayFolderContent(this.currentFolderPath);
|
||||
}
|
||||
|
||||
@ -266,33 +256,10 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
||||
private performNavigation(node: MinimalNodeEntity) {
|
||||
if (node && node.entry && node.entry.isFolder) {
|
||||
let path = this.getNodePath(node);
|
||||
this.route.push({
|
||||
name: node.entry.name,
|
||||
path: path
|
||||
});
|
||||
this.displayFolderContent(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a breadcrumb route is clicked.
|
||||
* @param r Route to navigate to
|
||||
* @param e DOM event
|
||||
*/
|
||||
goToRoute(r, e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (this.navigate) {
|
||||
let idx = this.route.indexOf(r);
|
||||
if (idx > -1) {
|
||||
this.route.splice(idx + 1);
|
||||
this.displayFolderContent(r.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets thumbnail URL for the given node.
|
||||
* @param node Node to get URL for.
|
||||
@ -483,30 +450,6 @@ export class DocumentList implements OnInit, AfterViewChecked, AfterContentInit,
|
||||
return val;
|
||||
}
|
||||
|
||||
private parsePath(path: string): { name: string, path: string }[] {
|
||||
let parts = path.split('/').filter(val => val ? true : false);
|
||||
|
||||
let result = [
|
||||
this.rootFolder
|
||||
];
|
||||
|
||||
let parentPath: string = this.rootFolder.path;
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
if (!parentPath.endsWith('/')) {
|
||||
parentPath += '/';
|
||||
}
|
||||
parentPath += parts[i];
|
||||
|
||||
result.push({
|
||||
name: parts[i],
|
||||
path: parentPath
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
private _hasEntries(node: NodePaging): boolean {
|
||||
return (node && node.list && node.list.entries && node.list.entries.length > 0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user