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:
Denys Vuika
2018-06-19 08:16:53 +01:00
committed by GitHub
parent abd63ba0a4
commit 1a53f8d2aa
13 changed files with 171 additions and 169 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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();
});
});
});

View File

@@ -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));
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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 {

View 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;
}