mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-24 17:31:52 +00:00
unified selection state (#433)
* selection state * use unified selection state * cleanup tests * remove "console.log" * remove old selection property * remove coma
This commit is contained in:
@@ -3,14 +3,14 @@
|
||||
<adf-breadcrumb root="APP.BROWSE.FAVORITES.TITLE">
|
||||
</adf-breadcrumb>
|
||||
|
||||
<adf-toolbar class="inline" *ngIf="hasSelection">
|
||||
<adf-toolbar class="inline" *ngIf="!selection.isEmpty">
|
||||
|
||||
<button
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
*ngIf="selectedFile"
|
||||
*ngIf="selection.file"
|
||||
title="{{ 'APP.ACTIONS.VIEW' | translate }}"
|
||||
(click)="showPreview(selectedFile)">
|
||||
(click)="showPreview(selection.file)">
|
||||
<mat-icon>open_in_browser</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -18,16 +18,16 @@
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}"
|
||||
[adfNodeDownload]="selectedNodes">
|
||||
[adfNodeDownload]="selection.nodes">
|
||||
<mat-icon>get_app</mat-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
*ngIf="selectedFolder"
|
||||
*ngIf="selection.folder"
|
||||
title="{{ 'APP.ACTIONS.EDIT' | translate }}"
|
||||
[acaEditFolder]="selectedFolder">
|
||||
[acaEditFolder]="selection.folder">
|
||||
<mat-icon>create</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -49,39 +49,39 @@
|
||||
[overlapTrigger]="false">
|
||||
<button
|
||||
mat-menu-item
|
||||
#selection="adfFavorite"
|
||||
#favorites="adfFavorite"
|
||||
(toggle)="reload()"
|
||||
[adf-node-favorite]="selectedNodes">
|
||||
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
|
||||
[adf-node-favorite]="selection.nodes">
|
||||
<mat-icon color="primary" *ngIf="favorites.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!favorites.hasFavorites()">star_border</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[acaCopyNode]="selectedNodes">
|
||||
[acaCopyNode]="selection.nodes">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.COPY' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[acaMoveNode]="selectedNodes">
|
||||
[acaMoveNode]="selection.nodes">
|
||||
<mat-icon>library_books</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.MOVE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[acaDeleteNode]="selectedNodes">
|
||||
[acaDeleteNode]="selection.nodes">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.DELETE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="selectedFile"
|
||||
[acaNodeVersions]="selectedFile">
|
||||
*ngIf="selection.file"
|
||||
[acaNodeVersions]="selection.file">
|
||||
<mat-icon>history</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.VERSIONS' | translate }}</span>
|
||||
</button>
|
||||
@@ -169,7 +169,7 @@
|
||||
</div>
|
||||
|
||||
<div class="inner-layout__side-panel" *ngIf="infoDrawerOpened">
|
||||
<aca-info-drawer [node]="lastSelectedNode"></aca-info-drawer>
|
||||
<aca-info-drawer [node]="selection.last"></aca-info-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -6,13 +6,13 @@
|
||||
(navigate)="onBreadcrumbNavigate($event)">
|
||||
</adf-breadcrumb>
|
||||
|
||||
<adf-toolbar class="inline" *ngIf="hasSelection">
|
||||
<adf-toolbar class="inline" *ngIf="!selection.isEmpty">
|
||||
<button
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
*ngIf="selectedFile"
|
||||
*ngIf="selection.file"
|
||||
title="{{ 'APP.ACTIONS.VIEW' | translate }}"
|
||||
(click)="showPreview(selectedFile)">
|
||||
(click)="showPreview(selection.file)">
|
||||
<mat-icon>open_in_browser</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -20,16 +20,16 @@
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}"
|
||||
[adfNodeDownload]="selectedNodes">
|
||||
[adfNodeDownload]="selection.nodes">
|
||||
<mat-icon>get_app</mat-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
*ngIf="selectedFolder && permission.check(selectedFolder, ['update'])"
|
||||
*ngIf="selection.folder && permission.check(selection.folder, ['update'])"
|
||||
title="{{ 'APP.ACTIONS.EDIT' | translate }}"
|
||||
[acaEditFolder]="selectedFolder">
|
||||
[acaEditFolder]="selection.folder">
|
||||
<mat-icon>create</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -52,40 +52,40 @@
|
||||
[overlapTrigger]="false">
|
||||
<button
|
||||
mat-menu-item
|
||||
#selection="adfFavorite"
|
||||
[adf-node-favorite]="selectedNodes">
|
||||
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
|
||||
#favorites="adfFavorite"
|
||||
[adf-node-favorite]="selection.nodes">
|
||||
<mat-icon color="primary" *ngIf="favorites.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!favorites.hasFavorites()">star_border</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[acaCopyNode]="selectedNodes">
|
||||
[acaCopyNode]="selection.nodes">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.COPY' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="permission.check(selectedNodes, ['delete'])"
|
||||
[acaMoveNode]="selectedNodes">
|
||||
*ngIf="permission.check(selection.nodes, ['delete'])"
|
||||
[acaMoveNode]="selection.nodes">
|
||||
<mat-icon>library_books</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.MOVE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="permission.check(selectedNodes, ['delete'])"
|
||||
[acaDeleteNode]="selectedNodes">
|
||||
*ngIf="permission.check(selection.nodes, ['delete'])"
|
||||
[acaDeleteNode]="selection.nodes">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.DELETE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="selectedFile"
|
||||
[acaNodeVersions]="selectedFile">
|
||||
*ngIf="selection.file"
|
||||
[acaNodeVersions]="selection.file">
|
||||
<mat-icon>history</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.VERSIONS' | translate }}</span>
|
||||
</button>
|
||||
@@ -167,7 +167,7 @@
|
||||
</div>
|
||||
|
||||
<div class="inner-layout__side-panel" *ngIf="infoDrawerOpened">
|
||||
<aca-info-drawer [node]="lastSelectedNode"></aca-info-drawer>
|
||||
<aca-info-drawer [node]="selection.last"></aca-info-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -24,15 +24,10 @@
|
||||
*/
|
||||
|
||||
import { PageComponent } from './page.component';
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
|
||||
class TestClass extends PageComponent {
|
||||
node: any;
|
||||
|
||||
setSelection(selection: MinimalNodeEntity[] = []) {
|
||||
this.onSelectionChanged(selection);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super(null, null, null);
|
||||
}
|
||||
@@ -58,47 +53,4 @@ describe('PageComponent', () => {
|
||||
expect(component.getParentNodeId()).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasSelection()', () => {
|
||||
it('returns true when it has nodes selected', () => {
|
||||
component.setSelection([
|
||||
{ entry: { isFile: true } },
|
||||
{ entry: { isFile: true } }
|
||||
]);
|
||||
expect(component.hasSelection).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when it has no selections', () => {
|
||||
component.setSelection([]);
|
||||
expect(component.hasSelection).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectedFile', () => {
|
||||
it('returns true if selected node is file', () => {
|
||||
const selection = [ { entry: { isFile: true } } ];
|
||||
component.setSelection(selection);
|
||||
expect(component.selectedFile).toBe(selection[0]);
|
||||
});
|
||||
|
||||
it('returns false if selected node is folder', () => {
|
||||
const selection = [ { entry: { isFile: false, isFolder: true } } ];
|
||||
component.setSelection(selection);
|
||||
expect(component.selectedFile).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectedFolder', () => {
|
||||
it('returns true if selected node is folder', () => {
|
||||
const selection = [ { entry: { isFile: false, isFolder: true } } ];
|
||||
component.setSelection(selection);
|
||||
expect(component.selectedFolder).toBe(selection[0]);
|
||||
});
|
||||
|
||||
it('returns false if selected node is file', () => {
|
||||
const selection = [ { entry: { isFile: true, isFolder: false } } ];
|
||||
component.setSelection(selection);
|
||||
expect(component.selectedFolder).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -32,12 +32,13 @@ import { MinimalNodeEntity, MinimalNodeEntryEntity, Pagination } from 'alfresco-
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject, Subscription } from 'rxjs/Rx';
|
||||
import { SnackbarErrorAction, ViewNodeAction, SetSelectedNodesAction } from '../store/actions';
|
||||
import { selectedNodes } from '../store/selectors/app.selectors';
|
||||
import { appSelection } from '../store/selectors/app.selectors';
|
||||
import { AppStore } from '../store/states/app.state';
|
||||
import { SelectionState } from '../store/states/selection.state';
|
||||
|
||||
export abstract class PageComponent implements OnInit, OnDestroy {
|
||||
|
||||
onDestroy$: Subject<void> = new Subject<void>();
|
||||
onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||
|
||||
@ViewChild(DocumentListComponent)
|
||||
documentList: DocumentListComponent;
|
||||
@@ -45,13 +46,7 @@ export abstract class PageComponent implements OnInit, OnDestroy {
|
||||
title = 'Page';
|
||||
infoDrawerOpened = false;
|
||||
node: MinimalNodeEntryEntity;
|
||||
|
||||
selectedFolder: MinimalNodeEntity;
|
||||
selectedFile: MinimalNodeEntity;
|
||||
|
||||
hasSelection = false;
|
||||
lastSelectedNode: MinimalNodeEntity;
|
||||
selectedNodes: MinimalNodeEntity[];
|
||||
selection: SelectionState;
|
||||
|
||||
protected subscriptions: Subscription[] = [];
|
||||
|
||||
@@ -70,35 +65,24 @@ export abstract class PageComponent implements OnInit, OnDestroy {
|
||||
|
||||
ngOnInit() {
|
||||
this.store
|
||||
.select(selectedNodes)
|
||||
.select(appSelection)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(selection => this.onSelectionChanged(selection));
|
||||
.subscribe(selection => {
|
||||
this.selection = selection;
|
||||
if (selection.isEmpty) {
|
||||
this.infoDrawerOpened = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach(subscription => subscription.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
// Precalculates all the "static state" flags so that UI does not re-evaluate that on every tick
|
||||
protected onSelectionChanged(selection: MinimalNodeEntity[] = []) {
|
||||
this.selectedNodes = selection;
|
||||
this.hasSelection = selection.length > 0;
|
||||
this.selectedFolder = null;
|
||||
this.selectedFile = null;
|
||||
|
||||
if (selection.length > 0) {
|
||||
if (selection.length === 1) {
|
||||
this.selectedFile = selection.find(entity => entity.entry.isFile);
|
||||
this.selectedFolder = selection.find(entity => entity.entry.isFolder);
|
||||
}
|
||||
} else {
|
||||
this.lastSelectedNode = null;
|
||||
this.infoDrawerOpened = false;
|
||||
}
|
||||
}
|
||||
|
||||
showPreview(node: MinimalNodeEntity) {
|
||||
if (node && node.entry) {
|
||||
const { id, nodeId, name, isFile, isFolder } = node.entry;
|
||||
@@ -130,7 +114,6 @@ export abstract class PageComponent implements OnInit, OnDestroy {
|
||||
this.unSelectLockedNodes(documentList);
|
||||
}
|
||||
|
||||
this.lastSelectedNode = event.detail.node;
|
||||
this.store.dispatch(new SetSelectedNodesAction(documentList.selection));
|
||||
}
|
||||
}
|
||||
|
@@ -35,10 +35,10 @@
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
#selection="adfFavorite"
|
||||
#favorites="adfFavorite"
|
||||
[adf-node-favorite]="selectedEntities">
|
||||
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
|
||||
<mat-icon color="primary" *ngIf="favorites.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!favorites.hasFavorites()">star_border</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
|
@@ -3,14 +3,14 @@
|
||||
<adf-breadcrumb root="APP.BROWSE.RECENT.TITLE">
|
||||
</adf-breadcrumb>
|
||||
|
||||
<adf-toolbar class="inline" *ngIf="hasSelection">
|
||||
<adf-toolbar class="inline" *ngIf="!selection.isEmpty">
|
||||
|
||||
<button
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
*ngIf="selectedFile"
|
||||
*ngIf="selection.file"
|
||||
title="{{ 'APP.ACTIONS.VIEW' | translate }}"
|
||||
(click)="showPreview(selectedFile)">
|
||||
(click)="showPreview(selection.file)">
|
||||
<mat-icon>open_in_browser</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}"
|
||||
[adfNodeDownload]="selectedNodes">
|
||||
[adfNodeDownload]="selection.nodes">
|
||||
<mat-icon>get_app</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -41,40 +41,40 @@
|
||||
[overlapTrigger]="false">
|
||||
<button
|
||||
mat-menu-item
|
||||
#selection="adfFavorite"
|
||||
[adf-node-favorite]="selectedNodes">
|
||||
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
|
||||
#favorites="adfFavorite"
|
||||
[adf-node-favorite]="selection.nodes">
|
||||
<mat-icon color="primary" *ngIf="favorites.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!favorites.hasFavorites()">star_border</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[acaCopyNode]="selectedNodes">
|
||||
[acaCopyNode]="selection.nodes">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.COPY' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="permission.check(selectedNodes, ['delete'])"
|
||||
[acaMoveNode]="selectedNodes">
|
||||
*ngIf="permission.check(selection.nodes, ['delete'])"
|
||||
[acaMoveNode]="selection.nodes">
|
||||
<mat-icon>library_books</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.MOVE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="permission.check(selectedNodes, ['delete'])"
|
||||
[acaDeleteNode]="selectedNodes">
|
||||
*ngIf="permission.check(selection.nodes, ['delete'])"
|
||||
[acaDeleteNode]="selection.nodes">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.DELETE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="selectedFile"
|
||||
[acaNodeVersions]="selectedFile">
|
||||
*ngIf="selection.file"
|
||||
[acaNodeVersions]="selection.file">
|
||||
<mat-icon>history</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.VERSIONS' | translate }}</span>
|
||||
</button>
|
||||
@@ -157,7 +157,7 @@
|
||||
</div>
|
||||
|
||||
<div class="inner-layout__side-panel" *ngIf="infoDrawerOpened">
|
||||
<aca-info-drawer [node]="lastSelectedNode"></aca-info-drawer>
|
||||
<aca-info-drawer [node]="selection.last"></aca-info-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -2,13 +2,13 @@
|
||||
<div class="inner-layout__header">
|
||||
<adf-breadcrumb root="APP.BROWSE.SEARCH.TITLE">
|
||||
</adf-breadcrumb>
|
||||
<adf-toolbar class="inline" *ngIf="hasSelection">
|
||||
<adf-toolbar class="inline" *ngIf="!selection.isEmpty">
|
||||
<button
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
*ngIf="selectedFile"
|
||||
*ngIf="selection.file"
|
||||
title="{{ 'APP.ACTIONS.VIEW' | translate }}"
|
||||
(click)="showPreview(selectedFile)">
|
||||
(click)="showPreview(selection.file)">
|
||||
<mat-icon>open_in_browser</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}"
|
||||
[acaDownloadNodes]="selectedNodes">
|
||||
[acaDownloadNodes]="selection.nodes">
|
||||
<mat-icon>get_app</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -38,24 +38,24 @@
|
||||
<mat-menu #actionsMenu="matMenu" [overlapTrigger]="false">
|
||||
<button
|
||||
mat-menu-item
|
||||
#selection="adfFavorite"
|
||||
[adf-node-favorite]="selectedNodes">
|
||||
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
|
||||
#favorites="adfFavorite"
|
||||
[adf-node-favorite]="selection.nodes">
|
||||
<mat-icon color="primary" *ngIf="favorites.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!favorites.hasFavorites()">star_border</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[acaCopyNode]="selectedNodes">
|
||||
[acaCopyNode]="selection.nodes">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.COPY' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="selectedFile"
|
||||
[acaNodeVersions]="selectedFile">
|
||||
*ngIf="selection.file"
|
||||
[acaNodeVersions]="selection.file">
|
||||
<mat-icon>history</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.VERSIONS' | translate }}</span>
|
||||
</button>
|
||||
@@ -128,7 +128,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="inner-layout__side-panel" *ngIf="infoDrawerOpened">
|
||||
<aca-info-drawer [node]="lastSelectedNode"></aca-info-drawer>
|
||||
<aca-info-drawer [node]="selection.last"></aca-info-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -3,13 +3,13 @@
|
||||
<adf-breadcrumb root="APP.BROWSE.SHARED.TITLE">
|
||||
</adf-breadcrumb>
|
||||
|
||||
<adf-toolbar class="inline" *ngIf="hasSelection">
|
||||
<adf-toolbar class="inline" *ngIf="!selection.isEmpty">
|
||||
<button
|
||||
*ngIf="selectedNodes.length === 1"
|
||||
*ngIf="selection.count === 1"
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
title="{{ 'APP.ACTIONS.VIEW' | translate }}"
|
||||
(click)="showPreview(selectedNodes[0])">
|
||||
(click)="showPreview(selection.nodes[0])">
|
||||
<mat-icon>open_in_browser</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
title="{{ 'APP.ACTIONS.DOWNLOAD' | translate }}"
|
||||
[adfNodeDownload]="selectedNodes">
|
||||
[adfNodeDownload]="selection.nodes">
|
||||
<mat-icon>get_app</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -40,32 +40,32 @@
|
||||
[overlapTrigger]="false">
|
||||
<button
|
||||
mat-menu-item
|
||||
#selection="adfFavorite"
|
||||
[adf-node-favorite]="selectedNodes">
|
||||
<mat-icon color="primary" *ngIf="selection.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!selection.hasFavorites()">star_border</mat-icon>
|
||||
#favorites="adfFavorite"
|
||||
[adf-node-favorite]="selection.nodes">
|
||||
<mat-icon color="primary" *ngIf="favorites.hasFavorites()">star</mat-icon>
|
||||
<mat-icon *ngIf="!favorites.hasFavorites()">star_border</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.FAVORITE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
[acaCopyNode]="selectedNodes">
|
||||
[acaCopyNode]="selection.nodes">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.COPY' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="permission.check(selectedNodes, ['delete'], { target: 'allowableOperationsOnTarget' })"
|
||||
[acaMoveNode]="selectedNodes">
|
||||
*ngIf="permission.check(selection.nodes, ['delete'], { target: 'allowableOperationsOnTarget' })"
|
||||
[acaMoveNode]="selection.nodes">
|
||||
<mat-icon>library_books</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.MOVE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="permission.check(selectedNodes, ['delete'])"
|
||||
[acaUnshareNode]="selectedNodes"
|
||||
*ngIf="permission.check(selection.nodes, ['delete'])"
|
||||
[acaUnshareNode]="selection.nodes"
|
||||
(links-unshared)="reload()">
|
||||
<mat-icon>stop_screen_share</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.UNSHARE' | translate }}</span>
|
||||
@@ -73,16 +73,16 @@
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="permission.check(selectedNodes, ['delete'], { target: 'allowableOperationsOnTarget' })"
|
||||
[acaDeleteNode]="selectedNodes">
|
||||
*ngIf="permission.check(selection.nodes, ['delete'], { target: 'allowableOperationsOnTarget' })"
|
||||
[acaDeleteNode]="selection.nodes">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.DELETE' | translate }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
mat-menu-item
|
||||
*ngIf="selectedNodes.length === 1 && permission.check(selectedNodes, ['update'], { target: 'allowableOperationsOnTarget' })"
|
||||
[acaNodeVersions]="selectedNodes">
|
||||
*ngIf="selection.count === 1 && permission.check(selection.nodes, ['update'], { target: 'allowableOperationsOnTarget' })"
|
||||
[acaNodeVersions]="selection.nodes">
|
||||
<mat-icon>history</mat-icon>
|
||||
<span>{{ 'APP.ACTIONS.VERSIONS' | translate }}</span>
|
||||
</button>
|
||||
@@ -175,7 +175,7 @@
|
||||
</div>
|
||||
|
||||
<div class="inner-layout__side-panel" *ngIf="infoDrawerOpened">
|
||||
<aca-info-drawer [node]="lastSelectedNode"></aca-info-drawer>
|
||||
<aca-info-drawer [node]="selection.last"></aca-info-drawer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -3,11 +3,11 @@
|
||||
<adf-breadcrumb root="APP.BROWSE.TRASHCAN.TITLE">
|
||||
</adf-breadcrumb>
|
||||
|
||||
<adf-toolbar class="inline" *ngIf="hasSelection">
|
||||
<adf-toolbar class="inline" *ngIf="!selection.isEmpty">
|
||||
<button
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
[acaPermanentDelete]="selectedNodes"
|
||||
[acaPermanentDelete]="selection.nodes"
|
||||
title="{{ 'APP.ACTIONS.DELETE_PERMANENT' | translate }}">
|
||||
<mat-icon>delete_forever</mat-icon>
|
||||
</button>
|
||||
@@ -15,7 +15,7 @@
|
||||
<button
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
[acaRestoreNode]="selectedNodes"
|
||||
[acaRestoreNode]="selection.nodes"
|
||||
title="{{ 'APP.ACTIONS.RESTORE' | translate }}">
|
||||
<mat-icon>restore</mat-icon>
|
||||
</button>
|
||||
|
@@ -90,6 +90,33 @@ function updateSelectedNodes(
|
||||
action: SetSelectedNodesAction
|
||||
): AppState {
|
||||
const newState = Object.assign({}, state);
|
||||
newState.selectedNodes = [...action.payload];
|
||||
const nodes = [...action.payload];
|
||||
const count = nodes.length;
|
||||
const isEmpty = nodes.length === 0;
|
||||
|
||||
let first = null;
|
||||
let last = null;
|
||||
let file = null;
|
||||
let folder = null;
|
||||
|
||||
if (nodes.length > 0) {
|
||||
first = nodes[0];
|
||||
last = nodes[nodes.length - 1];
|
||||
|
||||
if (nodes.length === 1) {
|
||||
file = nodes.find(entity => entity.entry.isFile);
|
||||
folder = nodes.find(entity => entity.entry.isFolder);
|
||||
}
|
||||
}
|
||||
|
||||
newState.selection = {
|
||||
count,
|
||||
nodes,
|
||||
isEmpty,
|
||||
first,
|
||||
last,
|
||||
file,
|
||||
folder
|
||||
};
|
||||
return newState;
|
||||
}
|
||||
|
@@ -30,4 +30,4 @@ export const selectApp = (state: AppStore) => state.app;
|
||||
export const selectHeaderColor = createSelector(selectApp, (state: AppState) => state.headerColor);
|
||||
export const selectAppName = createSelector(selectApp, (state: AppState) => state.appName);
|
||||
export const selectLogoPath = createSelector(selectApp, (state: AppState) => state.logoPath);
|
||||
export const selectedNodes = createSelector(selectApp, (state: AppState) => state.selectedNodes);
|
||||
export const appSelection = createSelector(selectApp, (state: AppState) => state.selection);
|
||||
|
@@ -23,20 +23,24 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
import { SelectionState } from './selection.state';
|
||||
|
||||
export interface AppState {
|
||||
appName: string;
|
||||
headerColor: string;
|
||||
logoPath: string;
|
||||
selectedNodes: MinimalNodeEntity[];
|
||||
selection: SelectionState;
|
||||
}
|
||||
|
||||
export const INITIAL_APP_STATE: AppState = {
|
||||
appName: 'Alfresco Example Content Application',
|
||||
headerColor: '#2196F3',
|
||||
logoPath: 'assets/images/alfresco-logo-white.svg',
|
||||
selectedNodes: []
|
||||
selection: {
|
||||
nodes: [],
|
||||
isEmpty: true,
|
||||
count: 0
|
||||
}
|
||||
};
|
||||
|
||||
export interface AppStore {
|
||||
|
36
src/app/store/states/selection.state.ts
Normal file
36
src/app/store/states/selection.state.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
*
|
||||
* This file is part of the Alfresco Example Content Application.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { MinimalNodeEntity } from 'alfresco-js-api';
|
||||
|
||||
export interface SelectionState {
|
||||
count: number;
|
||||
nodes: MinimalNodeEntity[];
|
||||
isEmpty: boolean;
|
||||
first?: MinimalNodeEntity;
|
||||
last?: MinimalNodeEntity;
|
||||
folder?: MinimalNodeEntity;
|
||||
file?: MinimalNodeEntity;
|
||||
}
|
Reference in New Issue
Block a user