[ACA-1532] make Preview command available to extensions (#502)

* view file action and effect

* integrate view action with search input/row

* deprecate old ViewNode action/effect

* preview file command as extension

* reorder commands
This commit is contained in:
Denys Vuika
2018-07-09 15:56:33 +01:00
committed by GitHub
parent 7a95485a05
commit 382b459ac8
7 changed files with 104 additions and 59 deletions

View File

@@ -70,6 +70,11 @@
"type": "DOWNLOAD_NODES",
"payload": null
},
{
"id": "aca:actions/preview",
"type": "VIEW_FILE",
"payload": null
},
{
"id": "aca:actions/info",
@@ -206,6 +211,18 @@
"action": "aca:actions/create-folder"
}
},
{
"disabled": false,
"id": "aca:toolbar/preview",
"order": 15,
"title": "APP.ACTIONS.VIEW",
"icon": "open_in_browser",
"target": {
"types": ["file"],
"permissions": [],
"action": "aca:actions/preview"
}
},
{
"disabled": false,
"id": "aca:toolbar/download",

View File

@@ -30,7 +30,7 @@ import { Store } from '@ngrx/store';
import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
import { takeUntil } from 'rxjs/operators';
import { Subject, Subscription } from 'rxjs/Rx';
import { ViewNodeAction, SetSelectedNodesAction, DownloadNodesAction } from '../store/actions';
import { SetSelectedNodesAction, DownloadNodesAction, ViewFileAction } from '../store/actions';
import { appSelection, sharedUrl, currentFolder } from '../store/selectors/app.selectors';
import { AppStore } from '../store/states/app.state';
import { SelectionState } from '../store/states/selection.state';
@@ -109,16 +109,8 @@ export abstract class PageComponent implements OnInit, OnDestroy {
showPreview(node: MinimalNodeEntity) {
if (node && node.entry) {
const { id, nodeId, name, isFile, isFolder } = node.entry;
const parentId = this.node ? this.node.id : null;
this.store.dispatch(new ViewNodeAction({
parentId,
id: nodeId || id,
name,
isFile,
isFolder
}));
this.store.dispatch(new ViewFileAction(node, parentId));
}
}

View File

@@ -29,7 +29,7 @@ import { TestBed, async, ComponentFixture, fakeAsync, tick } from '@angular/core
import { SearchInputComponent } from './search-input.component';
import { AppTestingModule } from '../../../testing/app-testing.module';
import { Actions, ofType } from '@ngrx/effects';
import { ViewNodeAction, VIEW_NODE, NAVIGATE_FOLDER, NavigateToFolder } from '../../../store/actions';
import { NAVIGATE_FOLDER, NavigateToFolder, VIEW_FILE, ViewFileAction } from '../../../store/actions';
import { map } from 'rxjs/operators';
describe('SearchInputComponent', () => {
@@ -59,9 +59,9 @@ describe('SearchInputComponent', () => {
describe('onItemClicked()', () => {
it('opens preview if node is file', fakeAsync(done => {
actions$.pipe(
ofType<ViewNodeAction>(VIEW_NODE),
ofType<ViewFileAction>(VIEW_FILE),
map(action => {
expect(action.payload.id).toBe('node-id');
expect(action.payload.entry.id).toBe('node-id');
done();
})
);

View File

@@ -32,7 +32,7 @@ import { MinimalNodeEntity } from 'alfresco-js-api';
import { SearchInputControlComponent } from '../search-input-control/search-input-control.component';
import { Store } from '@ngrx/store';
import { AppStore } from '../../../store/states/app.state';
import { SearchByTermAction, ViewNodeAction, NavigateToFolder } from '../../../store/actions';
import { SearchByTermAction, NavigateToFolder, ViewFileAction } from '../../../store/actions';
@Component({
selector: 'aca-search-input',
@@ -90,15 +90,9 @@ export class SearchInputComponent implements OnInit {
onItemClicked(node: MinimalNodeEntity) {
if (node && node.entry) {
const { id, nodeId, name, isFile, isFolder, parentId } = node.entry;
const { isFile, isFolder } = node.entry;
if (isFile) {
this.store.dispatch(new ViewNodeAction({
parentId,
id: nodeId || id,
name,
isFile,
isFolder
}));
this.store.dispatch(new ViewFileAction(node));
} else if (isFolder) {
this.store.dispatch(new NavigateToFolder(node));
}

View File

@@ -24,8 +24,8 @@
*/
import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core';
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
import { ViewNodeAction } from '../../../store/actions/viewer.actions';
import { MinimalNodeEntity } from 'alfresco-js-api';
import { ViewFileAction } from '../../../store/actions';
import { Store } from '@ngrx/store';
import { AppStore } from '../../../store/states/app.state';
@@ -38,14 +38,14 @@ import { AppStore } from '../../../store/states/app.state';
host: { class: 'aca-search-results-row' }
})
export class SearchResultsRowComponent implements OnInit {
private node: MinimalNodeEntryEntity;
private node: MinimalNodeEntity;
@Input() context: any;
constructor(private store: Store<AppStore>) {}
ngOnInit() {
this.node = this.context.row.node.entry;
this.node = this.context.row.node;
}
get name() {
@@ -89,13 +89,8 @@ export class SearchResultsRowComponent implements OnInit {
}
showPreview() {
const { id, name } = this.node;
this.store.dispatch(
new ViewNodeAction({
id,
name
})
new ViewFileAction(this.node)
);
}
@@ -106,6 +101,6 @@ export class SearchResultsRowComponent implements OnInit {
.replace('[', '.')
.replace(']', '')
.split('.')
.reduce((acc, part) => (acc ? acc[part] : null), this.node);
.reduce((acc, part) => (acc ? acc[part] : null), this.node.entry);
}
}

View File

@@ -24,11 +24,11 @@
*/
import { Action } from '@ngrx/store';
import { NodeInfo } from '../models';
import { MinimalNodeEntity } from 'alfresco-js-api';
export const VIEW_NODE = 'VIEW_NODE';
export const VIEW_FILE = 'VIEW_FILE';
export class ViewNodeAction implements Action {
readonly type = VIEW_NODE;
constructor(public payload: NodeInfo) {}
export class ViewFileAction implements Action {
readonly type = VIEW_FILE;
constructor(public payload: MinimalNodeEntity, public parentId?: string) {}
}

View File

@@ -26,19 +26,67 @@
import { Effect, Actions, ofType } from '@ngrx/effects';
import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { ViewNodeAction, VIEW_NODE } from '../actions/viewer.actions';
import { VIEW_FILE, ViewFileAction } from '../actions';
import { Router } from '@angular/router';
import { Store, createSelector } from '@ngrx/store';
import { AppStore } from '../states';
import { appSelection, currentFolder } from '../selectors/app.selectors';
export const fileToPreview = createSelector(
appSelection,
currentFolder,
(selection, folder) => {
return {
selection,
folder
};
}
);
@Injectable()
export class ViewerEffects {
constructor(private actions$: Actions, private router: Router) {}
constructor(
private store: Store<AppStore>,
private actions$: Actions,
private router: Router
) {}
@Effect({ dispatch: false })
viewNode$ = this.actions$.pipe(
ofType<ViewNodeAction>(VIEW_NODE),
viewFile$ = this.actions$.pipe(
ofType<ViewFileAction>(VIEW_FILE),
map(action => {
const node = action.payload;
if (!node) {
if (action.payload && action.payload.entry) {
const { id, nodeId, isFile } = action.payload.entry;
if (isFile || nodeId) {
this.displayPreview(nodeId || id, action.parentId);
}
} else {
this.store
.select(fileToPreview)
.take(1)
.subscribe(result => {
if (result.selection && result.selection.file) {
const {
id,
nodeId,
isFile
} = result.selection.file.entry;
if (isFile || nodeId) {
const parentId = result.folder
? result.folder.id
: null;
this.displayPreview(nodeId || id, parentId);
}
}
});
}
})
);
private displayPreview(nodeId: string, parentId: string) {
if (!nodeId) {
return;
}
@@ -52,11 +100,10 @@ export class ViewerEffects {
previewLocation = previewLocation.replace(/\//g, '');
const path = [previewLocation];
if (node.parentId) {
path.push(node.parentId);
if (parentId) {
path.push(parentId);
}
path.push('preview', node.id);
path.push('preview', nodeId);
this.router.navigateByUrl(path.join('/'));
})
);
}
}