mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-31 17:38:28 +00:00
[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:
@@ -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",
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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();
|
||||
})
|
||||
);
|
||||
|
@@ -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));
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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) {}
|
||||
}
|
||||
|
@@ -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('/'));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user