diff --git a/e2e/components/menu/menu.ts b/e2e/components/menu/menu.ts
index ba6796a8c..3e2cddf52 100755
--- a/e2e/components/menu/menu.ts
+++ b/e2e/components/menu/menu.ts
@@ -32,12 +32,12 @@ export class Menu extends Component {
root: '.mat-menu-panel',
item: '.mat-menu-item',
icon: '.mat-icon',
- uploadFiles: 'input[id="upload-multiple-files"]'
+ uploadFiles: 'app-upload-files'
};
items: ElementArrayFinder = this.component.all(by.css(Menu.selectors.item));
backdrop: ElementFinder = browser.element(by.css('.cdk-overlay-backdrop'));
- uploadFiles: ElementFinder = this.component.element(by.css(Menu.selectors.uploadFiles));
+ uploadFiles: ElementFinder = browser.element(by.id(Menu.selectors.uploadFiles));
constructor(ancestor?: ElementFinder) {
super(Menu.selectors.root, ancestor);
diff --git a/e2e/suites/actions/create-folder.test.ts b/e2e/suites/actions/create-folder.test.ts
index ae0ce261b..355b5c4e0 100755
--- a/e2e/suites/actions/create-folder.test.ts
+++ b/e2e/suites/actions/create-folder.test.ts
@@ -155,7 +155,7 @@ describe('Create folder', () => {
.then(() => menu))
.then(menu => {
const tooltip = menu.getItemTooltip('Create folder');
- expect(tooltip).toContain(`You can't create a folder here`);
+ expect(tooltip).toContain(`Folders cannot be created whilst viewing the current items.`);
});
});
diff --git a/extension.schema.json b/extension.schema.json
index 1523515da..3d3b31f8e 100644
--- a/extension.schema.json
+++ b/extension.schema.json
@@ -115,6 +115,14 @@
"description": "Element title",
"type": "string"
},
+ "description": {
+ "description": "Element description, used for the tooltips.",
+ "type": "string"
+ },
+ "description-disabled": {
+ "description": "Description to use when element is in the disabled state.",
+ "type": "string"
+ },
"order": {
"description": "Element order",
"type": "number"
@@ -283,6 +291,12 @@
"type": "array",
"items": { "$ref": "#/definitions/contentActionRef" },
"minItems": 1
+ },
+ "actions": {
+ "description": "Content actions (toolbar, context menus, etc.)",
+ "type": "array",
+ "items": { "$ref": "#/definitions/contentActionRef" },
+ "minItems": 1
}
}
},
diff --git a/src/app.config.json b/src/app.config.json
index a83db09e1..a49196e18 100644
--- a/src/app.config.json
+++ b/src/app.config.json
@@ -9,7 +9,6 @@
"© 2017 - 2018 Alfresco Software, Inc. All rights reserved."
},
"experimental": {
- "libraries": false,
"comments": false,
"cardview": false,
"permissions": false,
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index aa0953072..5c89f9ac5 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -73,6 +73,9 @@ import { ViewUtilService} from './services/view-util.service';
import { ExtensionService } from './extensions/extension.service';
import { AppInfoDrawerModule } from './components/info-drawer/info.drawer.module';
import { DirectivesModule } from './directives/directives.module';
+import { ToggleInfoDrawerComponent } from './components/toolbar/toggle-info-drawer/toggle-info-drawer.component';
+import { DocumentDisplayModeComponent } from './components/toolbar/document-display-mode/document-display-mode.component';
+import { ToggleFavoriteComponent } from './components/toolbar/toggle-favorite/toggle-favorite.component';
export function setupExtensionServiceFactory(service: ExtensionService): Function {
return () => service.load();
@@ -121,7 +124,10 @@ export function setupExtensionServiceFactory(service: ExtensionService): Functio
PermissionsManagerComponent,
SearchResultsComponent,
SettingsComponent,
- SharedLinkViewComponent
+ SharedLinkViewComponent,
+ ToggleInfoDrawerComponent,
+ DocumentDisplayModeComponent,
+ ToggleFavoriteComponent
],
providers: [
{ provide: RouteReuseStrategy, useClass: AppRouteReuseStrategy },
@@ -151,7 +157,10 @@ export function setupExtensionServiceFactory(service: ExtensionService): Functio
entryComponents: [
LibraryDialogComponent,
NodeVersionsDialogComponent,
- NodePermissionsDialogComponent
+ NodePermissionsDialogComponent,
+ ToggleInfoDrawerComponent,
+ DocumentDisplayModeComponent,
+ ToggleFavoriteComponent
],
bootstrap: [AppComponent]
})
diff --git a/src/app/components/favorites/favorites.component.html b/src/app/components/favorites/favorites.component.html
index 7730499f4..451045507 100644
--- a/src/app/components/favorites/favorites.component.html
+++ b/src/app/components/favorites/favorites.component.html
@@ -4,129 +4,17 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts
index da332aa3f..33da9d6d8 100644
--- a/src/app/components/favorites/favorites.component.ts
+++ b/src/app/components/favorites/favorites.component.ts
@@ -59,7 +59,8 @@ export class FavoritesComponent extends PageComponent implements OnInit {
this.content.nodesDeleted.subscribe(() => this.reload()),
this.content.nodesRestored.subscribe(() => this.reload()),
this.content.folderEdited.subscribe(() => this.reload()),
- this.content.nodesMoved.subscribe(() => this.reload())
+ this.content.nodesMoved.subscribe(() => this.reload()),
+ this.content.favoriteRemoved.subscribe(() => this.reload())
]);
}
diff --git a/src/app/components/files/files.component.html b/src/app/components/files/files.component.html
index e163ac382..8601d3d44 100644
--- a/src/app/components/files/files.component.html
+++ b/src/app/components/files/files.component.html
@@ -7,125 +7,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -141,6 +25,7 @@
[disabled]="!canUpload">
-
diff --git a/src/app/components/files/files.component.spec.ts b/src/app/components/files/files.component.spec.ts
index a8f706818..0788d3f39 100644
--- a/src/app/components/files/files.component.spec.ts
+++ b/src/app/components/files/files.component.spec.ts
@@ -29,7 +29,9 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import {
TimeAgoPipe, NodeNameTooltipPipe, FileSizePipe, NodeFavoriteDirective,
- DataTableComponent, UploadService, AppConfigPipe
+ DataTableComponent,
+ UploadService,
+ AppConfigPipe
} from '@alfresco/adf-core';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { ContentManagementService } from '../../services/content-management.service';
@@ -41,7 +43,6 @@ import { ExperimentalDirective } from '../../directives/experimental.directive';
describe('FilesComponent', () => {
let node;
- let page;
let fixture: ComponentFixture;
let component: FilesComponent;
let contentManagementService: ContentManagementService;
@@ -90,20 +91,12 @@ describe('FilesComponent', () => {
beforeEach(() => {
node = { id: 'node-id', isFolder: true };
- page = {
- list: {
- entries: ['a', 'b', 'c'],
- pagination: {}
- }
- };
-
spyOn(component.documentList, 'loadFolder').and.callFake(() => {});
});
describe('Current page is valid', () => {
it('should be a valid current page', fakeAsync(() => {
- spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
- spyOn(component, 'fetchNodes').and.returnValue(Observable.throw(null));
+ spyOn(contentApi, 'getNode').and.returnValue(Observable.throw(null));
component.ngOnInit();
fixture.detectChanges();
@@ -114,7 +107,6 @@ describe('FilesComponent', () => {
it('should set current page as invalid path', fakeAsync(() => {
spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
- spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
component.ngOnInit();
tick();
@@ -127,22 +119,10 @@ describe('FilesComponent', () => {
describe('OnInit', () => {
it('should set current node', () => {
spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
- spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
-
fixture.detectChanges();
-
expect(component.node).toBe(node);
});
- it('should get current node children', () => {
- spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
- spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
-
- fixture.detectChanges();
-
- expect(component.fetchNodes).toHaveBeenCalled();
- });
-
it('if should navigate to parent if node is not a folder', () => {
node.isFolder = false;
node.parentId = 'parent-id';
@@ -157,8 +137,7 @@ describe('FilesComponent', () => {
describe('refresh on events', () => {
beforeEach(() => {
- spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
- spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
+ spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(component.documentList, 'reload');
fixture.detectChanges();
@@ -170,9 +149,9 @@ describe('FilesComponent', () => {
{ entry: { parentId: '2' } }
];
- component.node = { id: '1' };
+ component.node = { id: '1' };
- nodeActionsService.contentCopied.next(nodes);
+ nodeActionsService.contentCopied.next(nodes);
expect(component.documentList.reload).toHaveBeenCalled();
});
@@ -183,9 +162,9 @@ describe('FilesComponent', () => {
{ entry: { parentId: '2' } }
];
- component.node = { id: '3' };
+ component.node = { id: '3' };
- nodeActionsService.contentCopied.next(nodes);
+ nodeActionsService.contentCopied.next(nodes);
expect(component.documentList.reload).not.toHaveBeenCalled();
});
@@ -222,7 +201,7 @@ describe('FilesComponent', () => {
it('should call refresh on fileUploadComplete event if parent node match', () => {
const file = { file: { options: { parentId: 'parentId' } } };
- component.node = { id: 'parentId' };
+ component.node = { id: 'parentId' };
uploadService.fileUploadComplete.next(file);
@@ -231,7 +210,7 @@ describe('FilesComponent', () => {
it('should not call refresh on fileUploadComplete event if parent mismatch', () => {
const file = { file: { options: { parentId: 'otherId' } } };
- component.node = { id: 'parentId' };
+ component.node = { id: 'parentId' };
uploadService.fileUploadComplete.next(file);
@@ -240,7 +219,7 @@ describe('FilesComponent', () => {
it('should call refresh on fileUploadDeleted event if parent node match', () => {
const file = { file: { options: { parentId: 'parentId' } } };
- component.node = { id: 'parentId' };
+ component.node = { id: 'parentId' };
uploadService.fileUploadDeleted.next(file);
@@ -248,40 +227,24 @@ describe('FilesComponent', () => {
});
it('should not call refresh on fileUploadDeleted event if parent mismatch', () => {
- const file = { file: { options: { parentId: 'otherId' } } };
- component.node = { id: 'parentId' };
+ const file: any = { file: { options: { parentId: 'otherId' } } };
+ component.node = { id: 'parentId' };
- uploadService.fileUploadDeleted.next(file);
+ uploadService.fileUploadDeleted.next(file);
expect(component.documentList.reload).not.toHaveBeenCalled();
});
});
- describe('fetchNodes()', () => {
- beforeEach(() => {
- spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
- spyOn(contentApi, 'getNodeChildren').and.returnValue(Observable.of(page));
-
- fixture.detectChanges();
- });
-
- it('should call getNode api with node id', () => {
- component.fetchNodes('nodeId');
-
- expect(contentApi.getNodeChildren).toHaveBeenCalledWith('nodeId');
- });
- });
describe('onBreadcrumbNavigate()', () => {
beforeEach(() => {
- spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
- spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
-
+ spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
fixture.detectChanges();
});
it('should navigates to node id', () => {
- const routeData = { id: 'some-where-over-the-rainbow' };
+ const routeData: any = { id: 'some-where-over-the-rainbow' };
spyOn(component, 'navigate');
component.onBreadcrumbNavigate(routeData);
@@ -292,8 +255,7 @@ describe('FilesComponent', () => {
describe('Node navigation', () => {
beforeEach(() => {
- spyOn(contentApi, 'getNode').and.returnValue(Observable.of(node));
- spyOn(component, 'fetchNodes').and.returnValue(Observable.of(page));
+ spyOn(contentApi, 'getNode').and.returnValue(Observable.of({ entry: node }));
spyOn(router, 'navigate');
fixture.detectChanges();
@@ -312,7 +274,7 @@ describe('FilesComponent', () => {
});
it('should navigate home if node is root', () => {
- (component).node = {
+ component.node = {
path: {
elements: [ {id: 'node-id'} ]
}
diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts
index cce77e058..98078cd80 100644
--- a/src/app/components/files/files.component.ts
+++ b/src/app/components/files/files.component.ts
@@ -27,8 +27,7 @@ import { FileUploadEvent, UploadService } from '@alfresco/adf-core';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { Store } from '@ngrx/store';
-import { MinimalNodeEntity, MinimalNodeEntryEntity, NodePaging, PathElement, PathElementEntity } from 'alfresco-js-api';
-import { Observable } from 'rxjs/Rx';
+import { MinimalNodeEntity, MinimalNodeEntryEntity, PathElement, PathElementEntity } from 'alfresco-js-api';
import { ContentManagementService } from '../../services/content-management.service';
import { NodeActionsService } from '../../services/node-actions.service';
import { AppStore } from '../../store/states/app.state';
@@ -68,19 +67,21 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
route.params.subscribe(({ folderId }: Params) => {
const nodeId = folderId || data.defaultNodeId;
- this.contentApi.getNode(nodeId)
- .map(node => node.entry)
- .do(node => {
- if (node.isFolder) {
- this.updateCurrentNode(node);
- } else {
- this.router.navigate(['/personal-files', node.parentId], { replaceUrl: true });
- }
- })
- .skipWhile(node => !node.isFolder)
- .flatMap(node => this.fetchNodes(node.id))
+ this.contentApi
+ .getNode(nodeId)
.subscribe(
- () => this.isValidPath = true,
+ node => {
+ this.isValidPath = true;
+
+ if (node.entry && node.entry.isFolder) {
+ this.updateCurrentNode(node.entry);
+ } else {
+ this.router.navigate(
+ ['/personal-files', node.entry.parentId],
+ { replaceUrl: true }
+ );
+ }
+ },
() => this.isValidPath = false
);
});
@@ -102,10 +103,6 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
this.store.dispatch(new SetCurrentFolderAction(null));
}
- fetchNodes(parentNodeId?: string): Observable {
- return this.contentApi.getNodeChildren(parentNodeId);
- }
-
navigate(nodeId: string = null) {
const commands = [ './' ];
diff --git a/src/app/components/libraries/libraries.component.html b/src/app/components/libraries/libraries.component.html
index c140731b4..69cb63d40 100644
--- a/src/app/components/libraries/libraries.component.html
+++ b/src/app/components/libraries/libraries.component.html
@@ -4,39 +4,11 @@
-
+
-
-
-
-
-
-
-
-
+
+
+
@@ -45,6 +17,7 @@
;
node: MinimalNodeEntryEntity;
selection: SelectionState;
- displayMode = DisplayMode.List;
+ documentDisplayMode$: Observable;
sharedPreviewUrl$: Observable;
actions: Array = [];
- canUpdateFile = false;
+ viewerActions: Array = [];
canUpdateNode = false;
- canDelete = false;
- canEditFolder = false;
canUpload = false;
- canDeleteShared = false;
- canUpdateShared = false;
protected subscriptions: Subscription[] = [];
@@ -74,22 +69,17 @@ export abstract class PageComponent implements OnInit, OnDestroy {
ngOnInit() {
this.sharedPreviewUrl$ = this.store.select(sharedUrl);
+ this.infoDrawerOpened$ = this.store.select(infoDrawerOpened);
+ this.documentDisplayMode$ = this.store.select(documentDisplayMode);
this.store
.select(appSelection)
.pipe(takeUntil(this.onDestroy$))
.subscribe(selection => {
this.selection = selection;
- if (selection.isEmpty) {
- this.infoDrawerOpened = false;
- }
this.actions = this.extensions.getAllowedContentActions();
- this.canUpdateFile = this.selection.file && this.content.canUpdateNode(selection.file);
+ this.viewerActions = this.extensions.getViewerActions();
this.canUpdateNode = this.selection.count === 1 && this.content.canUpdateNode(selection.first);
- this.canDelete = !this.selection.isEmpty && this.content.canDeleteNodes(selection.nodes);
- this.canEditFolder = selection.folder && this.content.canUpdateNode(selection.folder);
- this.canDeleteShared = !this.selection.isEmpty && this.content.canDeleteSharedNodes(selection.nodes);
- this.canUpdateShared = selection.file && this.content.canUpdateSharedNode(selection.file);
});
this.store.select(currentFolder)
@@ -127,14 +117,6 @@ export abstract class PageComponent implements OnInit, OnDestroy {
return null;
}
- toggleSidebar(event) {
- if (event) {
- return;
- }
-
- this.infoDrawerOpened = !this.infoDrawerOpened;
- }
-
reload(): void {
if (this.documentList) {
this.documentList.resetSelection();
@@ -143,22 +125,7 @@ export abstract class PageComponent implements OnInit, OnDestroy {
}
}
- toggleGalleryView(): void {
- this.displayMode = this.displayMode === DisplayMode.List ? DisplayMode.Gallery : DisplayMode.List;
- this.documentList.display = this.displayMode;
- }
-
- downloadSelection() {
- this.store.dispatch(new DownloadNodesAction());
- }
-
- // this is where each application decides how to treat an action and what to do
- // the ACA maps actions to the NgRx actions as an example
- runAction(actionId: string) {
- const context = {
- selection: this.selection
- };
-
- this.extensions.runActionById(actionId, context);
+ trackByActionId(index: number, action: ContentActionRef) {
+ return action.id;
}
}
diff --git a/src/app/components/preview/preview.component.html b/src/app/components/preview/preview.component.html
index f4500aa7a..fcb908865 100644
--- a/src/app/components/preview/preview.component.html
+++ b/src/app/components/preview/preview.component.html
@@ -8,7 +8,7 @@
[canNavigateBefore]="previousNodeId"
[canNavigateNext]="nextNodeId"
[overlayMode]="true"
- (print) = "printFile($event)"
+ (print)="printFile()"
(showViewerChange)="onVisibilityChanged($event)"
(navigateBefore)="onNavigateBefore()"
(navigateNext)="onNavigateNext()">
@@ -18,74 +18,14 @@
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/app/components/preview/preview.component.ts b/src/app/components/preview/preview.component.ts
index c007477f0..25cbe2b0e 100644
--- a/src/app/components/preview/preview.component.ts
+++ b/src/app/components/preview/preview.component.ts
@@ -28,7 +28,7 @@ import { ActivatedRoute, Router, UrlTree, UrlSegmentGroup, UrlSegment, PRIMARY_O
import { UserPreferencesService, ObjectUtils } from '@alfresco/adf-core';
import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state';
-import { DeleteNodesAction, SetSelectedNodesAction } from '../../store/actions';
+import { SetSelectedNodesAction } from '../../store/actions';
import { PageComponent } from '../page.component';
import { ContentApiService } from '../../services/content-api.service';
import { ExtensionService } from '../../extensions/extension.service';
@@ -335,17 +335,7 @@ export class PreviewComponent extends PageComponent implements OnInit {
return path;
}
- deleteFile() {
- this.store.dispatch(new DeleteNodesAction([
- {
- id: this.node.nodeId || this.node.id,
- name: this.node.name
- }
- ]));
- this.onVisibilityChanged(false);
- }
-
- printFile(event: any) {
+ printFile() {
this.viewUtils.printFileGeneric(this.nodeId, this.node.content.mimeType);
}
diff --git a/src/app/components/preview/preview.module.ts b/src/app/components/preview/preview.module.ts
index d718a0bc4..f43f3bcfe 100644
--- a/src/app/components/preview/preview.module.ts
+++ b/src/app/components/preview/preview.module.ts
@@ -27,7 +27,7 @@ import { CoreModule } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
-
+import { CoreExtensionsModule } from '../../extensions/core.extensions.module';
import { DirectivesModule } from '../../directives/directives.module';
import { AppInfoDrawerModule } from '../info-drawer/info.drawer.module';
import { PreviewComponent } from './preview.component';
@@ -51,7 +51,8 @@ const routes: Routes = [
CoreModule.forChild(),
ContentDirectiveModule,
DirectivesModule,
- AppInfoDrawerModule
+ AppInfoDrawerModule,
+ CoreExtensionsModule.forChild()
],
declarations: [
PreviewComponent,
diff --git a/src/app/components/recent-files/recent-files.component.html b/src/app/components/recent-files/recent-files.component.html
index f99f39e67..34090f592 100644
--- a/src/app/components/recent-files/recent-files.component.html
+++ b/src/app/components/recent-files/recent-files.component.html
@@ -4,116 +4,10 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -121,6 +15,7 @@
-
diff --git a/src/app/components/search/search-results/search-results.component.html b/src/app/components/search/search-results/search-results.component.html
index ca29db79e..760ee310c 100644
--- a/src/app/components/search/search-results/search-results.component.html
+++ b/src/app/components/search/search-results/search-results.component.html
@@ -3,80 +3,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -154,7 +82,7 @@
-
diff --git a/src/app/components/shared-files/shared-files.component.html b/src/app/components/shared-files/shared-files.component.html
index 1d9de2c10..45e047237 100644
--- a/src/app/components/shared-files/shared-files.component.html
+++ b/src/app/components/shared-files/shared-files.component.html
@@ -4,113 +4,10 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -118,6 +15,7 @@
-
diff --git a/src/app/components/sidenav/sidenav.component.html b/src/app/components/sidenav/sidenav.component.html
index 4a190d3c4..5ce534892 100644
--- a/src/app/components/sidenav/sidenav.component.html
+++ b/src/app/components/sidenav/sidenav.component.html
@@ -1,75 +1,39 @@
-