mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
Allow navigation to folders from search results (#1209)
* Allow navigation to folders from search results - Uses router to pass ID of the folder - Modified document list component to accept folder ID without path - Current limitations - Breadcrumb cannot currently be shown when navigating via folder id - Clicking between folders does not update the current route * Allow root folder ID to be changed and have documentlist reload - e.g switching from Company home to My Files * New tests for navigating to folders based on ID Refs #666
This commit is contained in:
@@ -54,6 +54,11 @@ export const appRoutes: Routes = [
|
||||
component: FilesComponent,
|
||||
canActivate: [AuthGuardEcm]
|
||||
},
|
||||
{
|
||||
path: 'files/:id',
|
||||
component: FilesComponent,
|
||||
canActivate: [AuthGuardEcm]
|
||||
},
|
||||
{
|
||||
path: 'datatable',
|
||||
component: DataTableDemoComponent,
|
||||
|
@@ -5,7 +5,7 @@
|
||||
(onSuccess)="documentList.reload()">
|
||||
<alfresco-document-list-breadcrumb
|
||||
[currentFolderPath]="currentPath"
|
||||
[target]="documentList">
|
||||
(pathChanged)="onBreadcrumbPathChanged($event)" *ngIf="!currentFolderId">
|
||||
</alfresco-document-list-breadcrumb>
|
||||
<div *ngIf="errorMessage" class="error-message">
|
||||
<button (click)="resetError()" class="mdl-button mdl-js-button mdl-button--icon">
|
||||
@@ -15,7 +15,9 @@
|
||||
</div>
|
||||
<alfresco-document-list
|
||||
#documentList
|
||||
[rootFolderId]="rootFolderId"
|
||||
[currentFolderPath]="currentPath"
|
||||
[currentFolderId]="currentFolderId"
|
||||
[contextMenuActions]="true"
|
||||
[contentActions]="true"
|
||||
(error)="onNavigationError($event)"
|
||||
|
@@ -15,8 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Component, OnInit, Optional, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
|
||||
import {
|
||||
DocumentActionsService,
|
||||
@@ -34,6 +34,8 @@ import { FormService } from 'ng2-activiti-form';
|
||||
})
|
||||
export class FilesComponent implements OnInit {
|
||||
currentPath: string = '/Sites/swsdp/documentLibrary';
|
||||
rootFolderId: string = '-root-';
|
||||
currentFolderId: string = null;
|
||||
|
||||
errorMessage: string = null;
|
||||
fileNodeId: any;
|
||||
@@ -51,7 +53,8 @@ export class FilesComponent implements OnInit {
|
||||
constructor(private documentActions: DocumentActionsService,
|
||||
public auth: AlfrescoAuthenticationService,
|
||||
private formService: FormService,
|
||||
private router: Router) {
|
||||
private router: Router,
|
||||
@Optional() private route: ActivatedRoute) {
|
||||
documentActions.setHandler('my-handler', this.myDocumentActionHandler.bind(this));
|
||||
}
|
||||
|
||||
@@ -82,6 +85,12 @@ export class FilesComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
onBreadcrumbPathChanged(event?: any) {
|
||||
if (event) {
|
||||
this.currentPath = event.value;
|
||||
}
|
||||
}
|
||||
|
||||
toggleMultipleFileUpload() {
|
||||
this.multipleFileUpload = !this.multipleFileUpload;
|
||||
return this.multipleFileUpload;
|
||||
@@ -104,6 +113,11 @@ export class FilesComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.route) {
|
||||
this.route.params.forEach((params: Params) => {
|
||||
this.currentFolderId = params.hasOwnProperty('id') ? params['id'] : null;
|
||||
});
|
||||
}
|
||||
if (this.auth.isBpmLoggedIn()) {
|
||||
this.formService.getProcessDefinitions().subscribe(
|
||||
defs => this.setupBpmActions(defs || []),
|
||||
|
@@ -1,11 +1,10 @@
|
||||
<alfresco-search-control *ngIf="isLoggedIn()"
|
||||
[searchTerm]="searchTerm"
|
||||
[autocomplete]="false"
|
||||
[liveSearchResultType]="'cm:content'"
|
||||
(searchSubmit)="onSearchSubmit($event);"
|
||||
(searchChange)="onSearchTermChange($event);"
|
||||
(expand)="onExpandToggle($event);"
|
||||
(fileSelect)="onFileClicked($event)">
|
||||
(fileSelect)="onItemClicked($event)">
|
||||
</alfresco-search-control>
|
||||
|
||||
<alfresco-viewer [(showViewer)]="fileShowed"
|
||||
|
@@ -18,6 +18,7 @@
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'search-bar',
|
||||
@@ -51,10 +52,12 @@ export class SearchBarComponent {
|
||||
}]);
|
||||
}
|
||||
|
||||
onFileClicked(event) {
|
||||
if (event.value.entry.isFile) {
|
||||
this.fileNodeId = event.value.entry.id;
|
||||
onItemClicked(event: MinimalNodeEntity) {
|
||||
if (event.entry.isFile) {
|
||||
this.fileNodeId = event.entry.id;
|
||||
this.fileShowed = true;
|
||||
} else if (event.entry.isFolder) {
|
||||
this.router.navigate(['/files', event.entry.id]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<div class="search-results-container">
|
||||
<h1>Search results</h1>
|
||||
<alfresco-search [resultType]="'cm:content'" (preview)="onFileClicked($event)"></alfresco-search>
|
||||
<alfresco-search (navigate)="onNavigateItem($event)"></alfresco-search>
|
||||
</div>
|
||||
|
||||
<alfresco-viewer [(showViewer)]="fileShowed" [fileNodeId]="fileNodeId" [overlayMode]="true">
|
||||
|
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'search-component',
|
||||
@@ -48,10 +50,15 @@ export class SearchComponent {
|
||||
fileShowed: boolean = false;
|
||||
fileNodeId: string;
|
||||
|
||||
onFileClicked(event) {
|
||||
if (event.value.entry.isFile) {
|
||||
this.fileNodeId = event.value.entry.id;
|
||||
constructor(public router: Router) {
|
||||
}
|
||||
|
||||
onNavigateItem(event: MinimalNodeEntity) {
|
||||
if (event.entry.isFile) {
|
||||
this.fileNodeId = event.entry.id;
|
||||
this.fileShowed = true;
|
||||
} else if (event.entry.isFolder) {
|
||||
this.router.navigate(['/files', event.entry.id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -168,7 +168,9 @@ platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `rootPath` | string | -root- | Root node path, i.e. `-root-`, `-shared-`, `-my-`, etc. |
|
||||
| `rootFolderId` | string | -root- | Root node ID, i.e. `-root-`, `-shared-`, `-my-`, etc. or a fixed node ID |
|
||||
| `currentFolderPath` | string | null | Initial path of displayed folder below the root node, e.g. "/Sites/swsdp/documentLibrary" |
|
||||
| `currentFolderId` | string | null | Initial node ID of displayed folder, if given |
|
||||
| `navigate` | boolean | true | Toggles navigation to folder content or file preview |
|
||||
| `navigationMode` | string (click\|dblclick) | dblclick | User interaction for folder navigation or file preview |
|
||||
| `thumbnails` | boolean | false | Show document thumbnails rather than icons |
|
||||
|
@@ -87,7 +87,7 @@ describe('DocumentListBreadcrumb', () => {
|
||||
|
||||
it('should update document list on click', (done) => {
|
||||
let documentList = new DocumentList(null, null, null);
|
||||
spyOn(documentList, 'displayFolderContent').and.returnValue(Promise.resolve());
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.resolve());
|
||||
|
||||
let node = <PathNode> { name: 'name', path: '/path' };
|
||||
component.target = documentList;
|
||||
|
@@ -83,8 +83,11 @@ export class DocumentListBreadcrumb {
|
||||
}
|
||||
});
|
||||
|
||||
this.currentFolderPath = route.path;
|
||||
|
||||
if (this.target) {
|
||||
this.target.currentFolderPath = route.path;
|
||||
this.target.loadFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NgZone, TemplateRef } from '@angular/core';
|
||||
import { NgZone, SimpleChange, TemplateRef } from '@angular/core';
|
||||
import { DataTableComponent, DataColumn, DataRowEvent } from 'ng2-alfresco-datatable';
|
||||
import { DocumentList } from './document-list';
|
||||
import { DocumentListServiceMock } from './../assets/document-list.service.mock';
|
||||
@@ -48,12 +48,12 @@ describe('DocumentList', () => {
|
||||
window['componentHandler'] = componentHandler;
|
||||
});
|
||||
|
||||
it('should update root path', () => {
|
||||
it('should update root folder ID', () => {
|
||||
let adapter = documentList.data;
|
||||
expect(adapter.rootPath).toBe(adapter.DEFAULT_ROOT_PATH);
|
||||
expect(adapter.rootFolderId).toBe(adapter.DEFAULT_ROOT_ID);
|
||||
|
||||
documentList.rootPath = '-shared-';
|
||||
expect(adapter.rootPath).toBe('-shared-');
|
||||
documentList.rootFolderId = '-shared-';
|
||||
expect(adapter.rootFolderId).toBe('-shared-');
|
||||
});
|
||||
|
||||
it('should setup default columns', () => {
|
||||
@@ -163,7 +163,7 @@ describe('DocumentList', () => {
|
||||
let node = new FolderNode('<display name>');
|
||||
|
||||
spyOn(documentList, 'getNodePath').and.returnValue(path);
|
||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.resolve(true));
|
||||
|
||||
documentList.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||
documentList.onNodeClick(node);
|
||||
@@ -173,31 +173,31 @@ describe('DocumentList', () => {
|
||||
|
||||
it('should not display folder content when no target node provided', () => {
|
||||
expect(documentList.navigate).toBe(true);
|
||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||
spyOn(documentList, 'loadFolderByPath').and.stub();
|
||||
|
||||
documentList.onNodeClick(null);
|
||||
expect(documentList.displayFolderContent).not.toHaveBeenCalled();
|
||||
expect(documentList.loadFolderByPath).not.toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it('should display folder content only on folder node click', () => {
|
||||
expect(documentList.navigate).toBe(true);
|
||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||
spyOn(documentList, 'loadFolderByPath').and.stub();
|
||||
|
||||
let node = new FileNode();
|
||||
documentList.onNodeClick(node);
|
||||
|
||||
expect(documentList.displayFolderContent).not.toHaveBeenCalled();
|
||||
expect(documentList.loadFolderByPath).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not display folder content on click when navigation is off', () => {
|
||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||
spyOn(documentList, 'loadFolderByPath').and.stub();
|
||||
|
||||
let node = new FolderNode('<display name>');
|
||||
documentList.navigate = false;
|
||||
documentList.onNodeClick(node);
|
||||
|
||||
expect(documentList.displayFolderContent).not.toHaveBeenCalled();
|
||||
expect(documentList.loadFolderByPath).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should require node to get path', () => {
|
||||
@@ -205,31 +205,35 @@ describe('DocumentList', () => {
|
||||
});
|
||||
|
||||
it('should display folder content for new folder path', () => {
|
||||
spyOn(documentList, 'displayFolderContent').and.returnValue(Promise.resolve());
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.resolve());
|
||||
let newPath = '/some/new/path';
|
||||
documentList.currentFolderPath = newPath;
|
||||
expect(documentList.displayFolderContent).toHaveBeenCalledWith(newPath);
|
||||
documentList.ngOnChanges({currentFolderPath: new SimpleChange(null, newPath)});
|
||||
expect(documentList.loadFolderByPath).toHaveBeenCalledWith(newPath);
|
||||
});
|
||||
|
||||
it('should reset to default path', () => {
|
||||
spyOn(documentList, 'displayFolderContent').and.returnValue(Promise.resolve());
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.resolve());
|
||||
documentList.currentFolderPath = null;
|
||||
documentList.ngOnChanges({currentFolderPath: new SimpleChange('', null)});
|
||||
|
||||
expect(documentList.currentFolderPath).toBe(documentList.DEFAULT_ROOT_FOLDER);
|
||||
expect(documentList.displayFolderContent).toHaveBeenCalledWith(documentList.DEFAULT_ROOT_FOLDER);
|
||||
expect(documentList.currentFolderPath).toBe(documentList.DEFAULT_FOLDER_PATH);
|
||||
expect(documentList.loadFolderByPath).toHaveBeenCalledWith(documentList.DEFAULT_FOLDER_PATH);
|
||||
});
|
||||
|
||||
it('should emit folder changed event', (done) => {
|
||||
spyOn(documentList, 'displayFolderContent').and.returnValue(Promise.resolve());
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.resolve());
|
||||
documentList.folderChange.subscribe(e => {
|
||||
done();
|
||||
});
|
||||
|
||||
documentList.currentFolderPath = '/some/new/path';
|
||||
let newPath = '/some/new/path';
|
||||
documentList.currentFolderPath = newPath;
|
||||
documentList.ngOnChanges({currentFolderPath: new SimpleChange(null, newPath)});
|
||||
});
|
||||
|
||||
it('should emit folder changed event with folder details', (done) => {
|
||||
spyOn(documentList, 'displayFolderContent').and.returnValue(Promise.resolve());
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.resolve());
|
||||
|
||||
let path = '/path';
|
||||
|
||||
@@ -239,6 +243,7 @@ describe('DocumentList', () => {
|
||||
});
|
||||
|
||||
documentList.currentFolderPath = path;
|
||||
documentList.ngOnChanges({currentFolderPath: new SimpleChange(null, path)});
|
||||
});
|
||||
|
||||
it('should execute context action on callback', () => {
|
||||
@@ -259,7 +264,7 @@ describe('DocumentList', () => {
|
||||
});
|
||||
|
||||
it('should subscribe to context action handler', () => {
|
||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.resolve(true));
|
||||
spyOn(documentList, 'contextActionCallback').and.stub();
|
||||
let value = {};
|
||||
documentList.ngOnInit();
|
||||
@@ -384,16 +389,16 @@ describe('DocumentList', () => {
|
||||
});
|
||||
|
||||
it('should display folder content on reload', () => {
|
||||
spyOn(documentList, 'displayFolderContent').and.callThrough();
|
||||
spyOn(documentList, 'loadFolderByPath').and.callThrough();
|
||||
documentList.reload();
|
||||
expect(documentList.displayFolderContent).toHaveBeenCalled();
|
||||
expect(documentList.loadFolderByPath).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should require path to display folder content', () => {
|
||||
spyOn(documentListService, 'getFolder').and.callThrough();
|
||||
|
||||
documentList.displayFolderContent(null);
|
||||
documentList.displayFolderContent('');
|
||||
documentList.loadFolderByPath(null);
|
||||
documentList.loadFolderByPath('');
|
||||
|
||||
expect(documentListService.getFolder).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -464,11 +469,11 @@ describe('DocumentList', () => {
|
||||
});
|
||||
expect(documentList.currentFolderPath).toBeNull();
|
||||
|
||||
spyOn(documentList, 'displayFolderContent').and.stub();
|
||||
spyOn(documentList, 'loadFolderByPath').and.stub();
|
||||
|
||||
documentList.reload();
|
||||
|
||||
expect(documentList.displayFolderContent).not.toHaveBeenCalled();
|
||||
expect(documentList.loadFolderByPath).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should enforce single-click on mobile browser', () => {
|
||||
@@ -482,9 +487,10 @@ describe('DocumentList', () => {
|
||||
it('should emit error on wrong path', (done) => {
|
||||
let raised = false;
|
||||
documentList.error.subscribe(err => raised = true);
|
||||
spyOn(documentList, 'displayFolderContent').and.returnValue(Promise.reject(false));
|
||||
spyOn(documentList, 'loadFolderByPath').and.returnValue(Promise.reject(false));
|
||||
|
||||
documentList.currentFolderPath = 'wrong-path';
|
||||
documentList.ngOnChanges({currentFolderPath: new SimpleChange(null, documentList.currentFolderPath)});
|
||||
setTimeout(() => {
|
||||
expect(raised).toBeTruthy();
|
||||
done();
|
||||
@@ -506,24 +512,24 @@ describe('DocumentList', () => {
|
||||
expect(documentList.isEmptyTemplateDefined()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should set root path for underlying adapter', () => {
|
||||
documentList.rootPath = 'test';
|
||||
expect(documentList.data.rootPath).toBe('test');
|
||||
it('should set root folder ID for underlying adapter', () => {
|
||||
documentList.rootFolderId = 'test';
|
||||
expect(documentList.data.rootFolderId).toBe('test');
|
||||
});
|
||||
|
||||
it('should set default root path for underlying adapter', () => {
|
||||
documentList.rootPath = null;
|
||||
expect(documentList.data.rootPath).toBe(documentList.data.DEFAULT_ROOT_PATH);
|
||||
it('should set default root folder ID for underlying adapter', () => {
|
||||
documentList.rootFolderId = null;
|
||||
expect(documentList.data.rootFolderId).toBe(documentList.data.DEFAULT_ROOT_ID);
|
||||
});
|
||||
|
||||
it('should fetch root path from underlying adapter', () => {
|
||||
documentList.data.rootPath = 'test';
|
||||
expect(documentList.rootPath).toBe('test');
|
||||
it('should fetch root folder ID from underlying adapter', () => {
|
||||
documentList.data.rootFolderId = 'test';
|
||||
expect(documentList.rootFolderId).toBe('test');
|
||||
});
|
||||
|
||||
it('should not fetch root path when adapter missing', () => {
|
||||
it('should not fetch root folder ID when adapter missing', () => {
|
||||
documentList.data = null;
|
||||
expect(documentList.rootPath).toBeNull();
|
||||
expect(documentList.rootFolderId).toBeNull();
|
||||
});
|
||||
|
||||
it('should set row filter for underlying adapter', () => {
|
||||
@@ -561,4 +567,49 @@ describe('DocumentList', () => {
|
||||
documentList.onRowDblClick(event);
|
||||
expect(documentList.onNodeDblClick).toHaveBeenCalledWith(node);
|
||||
});
|
||||
|
||||
describe('navigate by folder ID', () => {
|
||||
|
||||
it('should load folder by ID on init', () => {
|
||||
|
||||
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
|
||||
|
||||
let loadbyIdSpy: jasmine.Spy = spyOn(documentList.data, 'loadById').and.returnValue(Promise.resolve());
|
||||
|
||||
documentList.ngOnInit();
|
||||
expect(loadbyIdSpy).toHaveBeenCalled();
|
||||
expect(documentList.currentFolderPath).toBe('/');
|
||||
});
|
||||
|
||||
it('should load folder by ID on changes', () => {
|
||||
|
||||
let newNodeId = '1d26e465-dea3-42f3-b415-faa8364b9692';
|
||||
|
||||
documentList.ngOnChanges({currentFolderId: new SimpleChange(null, newNodeId)});
|
||||
|
||||
let loadbyPathSpy: jasmine.Spy = spyOn(documentList.data, 'loadPath').and.returnValue(Promise.resolve());
|
||||
|
||||
documentList.ngOnInit();
|
||||
expect(loadbyPathSpy).toHaveBeenCalled();
|
||||
expect(documentList.currentFolderPath).toBe('/');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('configure root folder', () => {
|
||||
|
||||
it('should re-load folder when rootFolderId changed', () => {
|
||||
|
||||
let newRootFolder = '-new-';
|
||||
|
||||
documentList.ngOnChanges({rootFolderId: new SimpleChange(null, newRootFolder)});
|
||||
|
||||
let loadbyPathSpy: jasmine.Spy = spyOn(documentList.data, 'loadPath').and.returnValue(Promise.resolve());
|
||||
|
||||
documentList.ngOnInit();
|
||||
expect(loadbyPathSpy).toHaveBeenCalled();
|
||||
expect(documentList.currentFolderPath).toBe('/');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@@ -19,7 +19,9 @@ import {
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
EventEmitter,
|
||||
AfterContentInit,
|
||||
TemplateRef,
|
||||
@@ -48,22 +50,25 @@ declare var module: any;
|
||||
styleUrls: ['./document-list.css'],
|
||||
templateUrl: './document-list.html'
|
||||
})
|
||||
export class DocumentList implements OnInit, AfterContentInit {
|
||||
export class DocumentList implements OnInit, OnChanges, AfterContentInit {
|
||||
|
||||
static SINGLE_CLICK_NAVIGATION: string = 'click';
|
||||
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
|
||||
static DEFAULT_PAGE_SIZE: number = 20;
|
||||
|
||||
DEFAULT_ROOT_FOLDER: string = '/';
|
||||
DEFAULT_FOLDER_PATH: string = '/';
|
||||
|
||||
@Input()
|
||||
set rootPath(value: string) {
|
||||
this.data.rootPath = value || this.data.DEFAULT_ROOT_PATH;
|
||||
set rootFolderId(value: string) {
|
||||
this.data.rootFolderId = value || this.data.DEFAULT_ROOT_ID;
|
||||
}
|
||||
|
||||
get rootPath(): string {
|
||||
@Input()
|
||||
currentFolderId: string = null;
|
||||
|
||||
get rootFolderId(): string {
|
||||
if (this.data) {
|
||||
return this.data.rootPath;
|
||||
return this.data.rootFolderId;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -127,21 +132,11 @@ export class DocumentList implements OnInit, AfterContentInit {
|
||||
@ViewChild(DataTableComponent)
|
||||
dataTable: DataTableComponent;
|
||||
|
||||
private _path = this.DEFAULT_ROOT_FOLDER;
|
||||
private _path = this.DEFAULT_FOLDER_PATH;
|
||||
|
||||
@Input()
|
||||
set currentFolderPath(value: string) {
|
||||
if (value !== this._path) {
|
||||
const path = value || this.DEFAULT_ROOT_FOLDER;
|
||||
this.displayFolderContent(path)
|
||||
.then(() => {
|
||||
this._path = path;
|
||||
this.folderChange.emit({ path: path });
|
||||
})
|
||||
.catch(err => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
this._path = value;
|
||||
}
|
||||
|
||||
get currentFolderPath(): string {
|
||||
@@ -220,6 +215,8 @@ export class DocumentList implements OnInit, AfterContentInit {
|
||||
if (this.isMobile()) {
|
||||
this.navigationMode = DocumentList.SINGLE_CLICK_NAVIGATION;
|
||||
}
|
||||
|
||||
this.loadFolder();
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
@@ -229,6 +226,40 @@ export class DocumentList implements OnInit, AfterContentInit {
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['currentFolderId'] && changes['currentFolderId'].currentValue) {
|
||||
let folderId = changes['currentFolderId'].currentValue;
|
||||
this.loadFolderById(folderId)
|
||||
.then(() => {
|
||||
this._path = null;
|
||||
})
|
||||
.catch(err => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
} else if (changes['currentFolderPath']) {
|
||||
const path = changes['currentFolderPath'].currentValue || this.DEFAULT_FOLDER_PATH;
|
||||
this.currentFolderPath = path;
|
||||
this.loadFolderByPath(path)
|
||||
.then(() => {
|
||||
this._path = path;
|
||||
this.folderChange.emit({ path: path });
|
||||
})
|
||||
.catch(err => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
} else if (changes['rootFolderId']) {
|
||||
// this.currentFolderPath = this.DEFAULT_FOLDER_PATH;
|
||||
this.loadFolderByPath(this.currentFolderPath)
|
||||
.then(() => {
|
||||
this._path = this.currentFolderPath;
|
||||
this.folderChange.emit({ path: this.currentFolderPath });
|
||||
})
|
||||
.catch(err => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isEmptyTemplateDefined() {
|
||||
if (this.dataTable) {
|
||||
if (this.emptyFolderTemplate) {
|
||||
@@ -277,6 +308,9 @@ export class DocumentList implements OnInit, AfterContentInit {
|
||||
performNavigation(node: MinimalNodeEntity): boolean {
|
||||
if (node && node.entry && node.entry.isFolder) {
|
||||
this.currentFolderPath = this.getNodePath(node);
|
||||
this.currentFolderId = null;
|
||||
this.loadFolder();
|
||||
this.folderChange.emit({ path: this.currentFolderPath });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -293,19 +327,32 @@ export class DocumentList implements OnInit, AfterContentInit {
|
||||
}
|
||||
}
|
||||
|
||||
displayFolderContent(path: string): Promise<any> {
|
||||
loadFolderByPath(path: string): Promise<any> {
|
||||
return this.data.loadPath(path);
|
||||
}
|
||||
|
||||
loadFolderById(id: string): Promise<any> {
|
||||
return this.data.loadById(id);
|
||||
}
|
||||
|
||||
reload() {
|
||||
this.ngZone.run(() => {
|
||||
if (this.currentFolderPath) {
|
||||
this.displayFolderContent(this.currentFolderPath)
|
||||
this.loadFolder();
|
||||
});
|
||||
}
|
||||
|
||||
public loadFolder() {
|
||||
if (this.currentFolderId) {
|
||||
this.loadFolderById(this.currentFolderId)
|
||||
.catch(err => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
} else if (this.currentFolderPath) {
|
||||
this.loadFolderByPath(this.currentFolderPath)
|
||||
.catch(err => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -31,7 +31,7 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid
|
||||
ERR_ROW_NOT_FOUND: string = 'Row not found';
|
||||
ERR_COL_NOT_FOUND: string = 'Column not found';
|
||||
|
||||
DEFAULT_ROOT_PATH: string = '-root-';
|
||||
DEFAULT_ROOT_ID: string = '-root-';
|
||||
DEFAULT_DATE_FORMAT: string = 'medium';
|
||||
DEFAULT_PAGE_SIZE: number = 20;
|
||||
MIN_PAGE_SIZE: number = 5;
|
||||
@@ -53,7 +53,7 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid
|
||||
|
||||
thumbnails: boolean = false;
|
||||
dataLoaded: DataLoadedEventEmitter;
|
||||
rootPath: string = this.DEFAULT_ROOT_PATH;
|
||||
rootFolderId: string = this.DEFAULT_ROOT_ID;
|
||||
|
||||
constructor(private documentListService: DocumentListService,
|
||||
private basePath: string,
|
||||
@@ -210,7 +210,7 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid
|
||||
.getFolder(path, {
|
||||
maxItems: this._maxItems,
|
||||
skipCount: this._skipCount,
|
||||
rootPath: this.rootPath
|
||||
rootFolderId: this.rootFolderId
|
||||
})
|
||||
.subscribe(val => {
|
||||
this.currentPath = path;
|
||||
@@ -228,6 +228,30 @@ export class ShareDataTableAdapter implements DataTableAdapter, PaginationProvid
|
||||
|
||||
}
|
||||
|
||||
loadById(id: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (id && this.documentListService) {
|
||||
this.documentListService
|
||||
.getFolder(null, {
|
||||
maxItems: this._maxItems,
|
||||
skipCount: this._skipCount,
|
||||
rootFolderId: id
|
||||
})
|
||||
.subscribe(val => {
|
||||
this.loadPage(<NodePaging>val);
|
||||
this.dataLoaded.emit(null);
|
||||
resolve(true);
|
||||
},
|
||||
error => {
|
||||
reject(error);
|
||||
});
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
setFilter(filter: RowFilter) {
|
||||
this.filter = filter;
|
||||
|
||||
|
@@ -30,6 +30,8 @@ export class DocumentListService {
|
||||
|
||||
static DEFAULT_MIME_TYPE_ICON: string = 'ft_ic_miscellaneous.svg';
|
||||
|
||||
static ROOT_ID = '-root-';
|
||||
|
||||
mimeTypeIcons: any = {
|
||||
'image/png': 'ft_ic_raster_image.svg',
|
||||
'image/jpeg': 'ft_ic_raster_image.svg',
|
||||
@@ -63,17 +65,21 @@ export class DocumentListService {
|
||||
}
|
||||
|
||||
private getNodesPromise(folder: string, opts?: any): Promise<NodePaging> {
|
||||
let rootPath = '-root-';
|
||||
|
||||
if (opts && opts.rootPath) {
|
||||
rootPath = opts.rootPath;
|
||||
let rootNodeId = DocumentListService.ROOT_ID;
|
||||
if (opts && opts.rootFolderId) {
|
||||
rootNodeId = opts.rootFolderId;
|
||||
}
|
||||
|
||||
let params: any = {
|
||||
relativePath: folder,
|
||||
includeSource: true,
|
||||
include: ['path', 'properties']
|
||||
};
|
||||
|
||||
if (folder) {
|
||||
params.relativePath = folder;
|
||||
}
|
||||
|
||||
if (opts) {
|
||||
if (opts.maxItems) {
|
||||
params.maxItems = opts.maxItems;
|
||||
@@ -83,7 +89,7 @@ export class DocumentListService {
|
||||
}
|
||||
}
|
||||
|
||||
return this.apiService.getInstance().nodes.getNodeChildren(rootPath, params);
|
||||
return this.apiService.getInstance().nodes.getNodeChildren(rootNodeId, params);
|
||||
}
|
||||
|
||||
deleteNode(nodeId: string): Observable<any> {
|
||||
@@ -105,7 +111,7 @@ export class DocumentListService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the folder node with the content.
|
||||
* Gets the folder node with the specified relative name path below the root node.
|
||||
* @param folder Path to folder.
|
||||
* @param opts Options.
|
||||
* @returns {Observable<NodePaging>} Folder entity.
|
||||
|
@@ -225,7 +225,7 @@ platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
|
||||
| Name | Description |
|
||||
| --- | --- |
|
||||
| `preview` | Emitted when a file result is clicked/selected |
|
||||
| `navigate` | Emitted when a search result is clicked or double-clicked |
|
||||
| `resultsLoad` | Emitted when search results have fully loaded |
|
||||
|
||||
#### Options
|
||||
@@ -237,6 +237,7 @@ platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
| `resultType` | {boolean} | (optional) | (none) | Node type to filter search results by, e.g. 'cm:content'. |
|
||||
| `maxResults` | {boolean} | (optional) | 20 | Maximum number of results to show in the search. |
|
||||
| `resultSort` | {boolean} | (optional) | (none) | Criteria to sort search results by, must be one of "name" , "modifiedAt" or "createdAt" |
|
||||
| `navigationMode` | {string} | (optional) | "dblclick" | Event used to initiate a navigation action to a specific result, one of "click" or "dblclick" |
|
||||
|
||||
### Build from sources
|
||||
|
||||
|
@@ -214,7 +214,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
|
||||
searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||
});
|
||||
|
||||
it('should emit file select when file item clicked', (done) => {
|
||||
it('should emit fileSelect event when file item clicked', (done) => {
|
||||
|
||||
spyOn(searchService, 'getQueryNodesPromise')
|
||||
.and.returnValue(Promise.resolve(result));
|
||||
@@ -231,7 +231,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not emit preview if a non-file item is clicked', (done) => {
|
||||
it('should emit fileSelect event if when folder item clicked', (done) => {
|
||||
|
||||
spyOn(searchService, 'getQueryNodesPromise')
|
||||
.and.returnValue(Promise.resolve(folderResult));
|
||||
@@ -240,7 +240,7 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
|
||||
component.resultsLoad.subscribe(() => {
|
||||
fixture.detectChanges();
|
||||
(<any> element.querySelector('#result_row_0')).click();
|
||||
expect(component.fileSelect.emit).not.toHaveBeenCalled();
|
||||
expect(component.fileSelect.emit).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
|
||||
|
@@ -19,6 +19,7 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, OnChanges, Output,
|
||||
import { AlfrescoSearchService, SearchOptions } from './../services/alfresco-search.service';
|
||||
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
@@ -121,10 +122,12 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
|
||||
* @param node Node to get URL for.
|
||||
* @returns {string} URL address.
|
||||
*/
|
||||
getMimeTypeIcon(node: any): string {
|
||||
getMimeTypeIcon(node: MinimalNodeEntity): string {
|
||||
if (node.entry.content && node.entry.content.mimeType) {
|
||||
let icon = this.alfrescoThumbnailService.getMimeTypeIcon(node.entry.content.mimeType);
|
||||
return this.resolveIconPath(icon);
|
||||
} else if (node.entry.isFolder) {
|
||||
return 'ft_ic_folder.svg';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +151,7 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
|
||||
* @param node Node to get URL for.
|
||||
* @returns {string} URL address.
|
||||
*/
|
||||
getMimeTypeKey(node: any): string {
|
||||
getMimeTypeKey(node: MinimalNodeEntity): string {
|
||||
if (node.entry.content && node.entry.content.mimeType) {
|
||||
return 'SEARCH.ICONS.' + this.alfrescoThumbnailService.getMimeTypeKey(node.entry.content.mimeType);
|
||||
} else {
|
||||
@@ -161,13 +164,9 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
|
||||
firstResult.focus();
|
||||
}
|
||||
|
||||
onItemClick(node): void {
|
||||
onItemClick(node: MinimalNodeEntity): void {
|
||||
if (node && node.entry) {
|
||||
if (node.entry.isFile) {
|
||||
this.fileSelect.emit({
|
||||
value: node
|
||||
});
|
||||
}
|
||||
this.fileSelect.emit(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,12 +178,10 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
|
||||
this.searchFocus.emit($event);
|
||||
}
|
||||
|
||||
onRowEnter(node): void {
|
||||
onRowEnter(node: MinimalNodeEntity): void {
|
||||
if (node && node.entry) {
|
||||
if (node.entry.isFile) {
|
||||
this.fileSelect.emit({
|
||||
value: node
|
||||
});
|
||||
this.fileSelect.emit(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -72,7 +72,7 @@ export class AlfrescoSearchControlComponent implements OnInit, OnDestroy {
|
||||
liveSearchRoot: string = '-root-';
|
||||
|
||||
@Input()
|
||||
liveSearchResultType: string = 'cm:content';
|
||||
liveSearchResultType: string = null;
|
||||
|
||||
@Input()
|
||||
liveSearchResultSort: string = null;
|
||||
@@ -171,9 +171,7 @@ export class AlfrescoSearchControlComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
onFileClicked(event): void {
|
||||
this.fileSelect.emit({
|
||||
value: event.value
|
||||
});
|
||||
this.fileSelect.emit(event);
|
||||
}
|
||||
|
||||
onSearchFocus($event): void {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr id="result_row_{{idx}}" tabindex="0" *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)" (keyup.enter)="onItemClick(result, $event)">
|
||||
<tr id="result_row_{{idx}}" tabindex="0" *ngFor="let result of results; let idx = index" (click)="onItemClick(result, $event)" (dblclick)="onItemDblClick(result, $event)" (keyup.enter)="onItemClick(result, $event)">
|
||||
<td class="col-mimetype-icon"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}" /></td>
|
||||
<td id="result_name_{{idx}}" class="mdl-data-table__cell--non-numeric col-display-name"
|
||||
attr.data-automation-id=file_{{result.entry.name}} >{{result.entry.name}}</td>
|
||||
|
@@ -15,7 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ReflectiveInjector, SimpleChange } from '@angular/core';
|
||||
import { DebugElement, ReflectiveInjector, SimpleChange } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
@@ -256,38 +257,83 @@ describe('AlfrescoSearchComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('search result actions', () => {
|
||||
describe('search result interactions', () => {
|
||||
|
||||
it('should emit preview when file item clicked', (done) => {
|
||||
let debugElement: DebugElement;
|
||||
let searchService: AlfrescoSearchService;
|
||||
let querySpy: jasmine.Spy;
|
||||
let emitSpy: jasmine.Spy;
|
||||
const rowSelector = '[data-automation-id="search_result_table"] tbody tr';
|
||||
|
||||
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||
spyOn(searchService, 'getQueryNodesPromise')
|
||||
.and.returnValue(Promise.resolve(result));
|
||||
beforeEach(() => {
|
||||
debugElement = fixture.debugElement;
|
||||
searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||
querySpy = spyOn(searchService, 'getQueryNodesPromise').and.returnValue(Promise.resolve(result));
|
||||
emitSpy = spyOn(component.navigate, 'emit');
|
||||
});
|
||||
|
||||
describe('click results', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.navigationMode = AlfrescoSearchComponent.SINGLE_CLICK_NAVIGATION;
|
||||
});
|
||||
|
||||
it('should emit navigation event when file item clicked', (done) => {
|
||||
|
||||
component.resultsLoad.subscribe(() => {
|
||||
fixture.detectChanges();
|
||||
(<HTMLTableRowElement> element.querySelector('#result_row_0')).click();
|
||||
debugElement.query(By.css(rowSelector)).triggerEventHandler('click', {});
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
|
||||
component.searchTerm = 'searchTerm';
|
||||
component.ngOnInit();
|
||||
|
||||
component.preview.subscribe(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not emit preview when non-file item is clicked', (done) => {
|
||||
it('should emit navigation event when non-file item is clicked', (done) => {
|
||||
|
||||
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||
spyOn(searchService, 'getQueryNodesPromise')
|
||||
.and.returnValue(Promise.resolve(folderResult));
|
||||
querySpy.and.returnValue(Promise.resolve(folderResult));
|
||||
|
||||
spyOn(component.preview, 'emit');
|
||||
component.resultsLoad.subscribe(() => {
|
||||
fixture.detectChanges();
|
||||
(<HTMLTableRowElement> element.querySelector('#result_row_0')).click();
|
||||
expect(component.preview.emit).not.toHaveBeenCalled();
|
||||
debugElement.query(By.css(rowSelector)).triggerEventHandler('click', {});
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
|
||||
component.searchTerm = 'searchTerm';
|
||||
component.ngOnInit();
|
||||
});
|
||||
});
|
||||
|
||||
describe('double click results', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.navigationMode = AlfrescoSearchComponent.DOUBLE_CLICK_NAVIGATION;
|
||||
});
|
||||
|
||||
it('should emit navigation event when file item clicked', (done) => {
|
||||
|
||||
component.resultsLoad.subscribe(() => {
|
||||
fixture.detectChanges();
|
||||
debugElement.query(By.css(rowSelector)).triggerEventHandler('dblclick', {});
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
|
||||
component.searchTerm = 'searchTerm';
|
||||
component.ngOnInit();
|
||||
});
|
||||
|
||||
it('should emit navigation event when non-file item is clicked', (done) => {
|
||||
|
||||
querySpy.and.returnValue(Promise.resolve(folderResult));
|
||||
|
||||
component.resultsLoad.subscribe(() => {
|
||||
fixture.detectChanges();
|
||||
debugElement.query(By.css(rowSelector)).triggerEventHandler('dblclick', {});
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -297,3 +343,5 @@ describe('AlfrescoSearchComponent', () => {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@@ -20,6 +20,7 @@ import { ActivatedRoute, Params } from '@angular/router';
|
||||
import { AlfrescoSearchService, SearchOptions } from './../services/alfresco-search.service';
|
||||
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
@@ -29,6 +30,9 @@ import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
})
|
||||
export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
||||
|
||||
static SINGLE_CLICK_NAVIGATION: string = 'click';
|
||||
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
|
||||
|
||||
@Input()
|
||||
searchTerm: string = '';
|
||||
|
||||
@@ -44,8 +48,11 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
||||
@Input()
|
||||
resultType: string = null;
|
||||
|
||||
@Input()
|
||||
navigationMode: string = AlfrescoSearchComponent.DOUBLE_CLICK_NAVIGATION; // click|dblclick
|
||||
|
||||
@Output()
|
||||
preview: EventEmitter<any> = new EventEmitter();
|
||||
navigate: EventEmitter<MinimalNodeEntity> = new EventEmitter<MinimalNodeEntity>();
|
||||
|
||||
@Output()
|
||||
resultsLoad = new EventEmitter();
|
||||
@@ -92,6 +99,8 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
||||
if (node.entry.content && node.entry.content.mimeType) {
|
||||
let icon = this._alfrescoThumbnailService.getMimeTypeIcon(node.entry.content.mimeType);
|
||||
return this.resolveIconPath(icon);
|
||||
} else if (node.entry.isFolder) {
|
||||
return 'ft_ic_folder.svg';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,14 +163,17 @@ export class AlfrescoSearchComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
onItemClick(node, event?: Event): void {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (this.navigate && this.navigationMode === AlfrescoSearchComponent.SINGLE_CLICK_NAVIGATION) {
|
||||
if (node && node.entry) {
|
||||
if (node.entry.isFile) {
|
||||
this.preview.emit({
|
||||
value: node
|
||||
});
|
||||
this.navigate.emit(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onItemDblClick(node: MinimalNodeEntity) {
|
||||
if (this.navigate && this.navigationMode === AlfrescoSearchComponent.DOUBLE_CLICK_NAVIGATION) {
|
||||
if (node && node.entry) {
|
||||
this.navigate.emit(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user