From edf1e52e9415053fb316fdaa3790a69f7aa54635 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan <pionnegru@users.noreply.github.com> Date: Fri, 6 Sep 2019 14:17:29 +0300 Subject: [PATCH] [ACA-2745] Viewer - return to location on close (#1196) * use viewNodeExtras when calling action * open viewer based on ViewNodeExtras data * resolve closing destination based on ViewNodeExtras query params * remove unused param * call ViewNodeAction with correct params * update tests * update docs --- docs/extending/application-actions.md | 96 +++++++++---------- docs/features/file-viewer.md | 63 ++++++++++++ .../store/src/actions/viewer.actions.ts | 7 +- .../favorites/favorites.component.spec.ts | 7 +- .../favorites/favorites.component.ts | 2 +- src/app/components/files/files.component.ts | 2 +- src/app/components/page.component.ts | 7 +- .../recent-files.component.spec.ts | 4 +- .../recent-files/recent-files.component.ts | 2 +- .../search-results-row.component.ts | 2 +- .../search-results.component.spec.ts | 4 +- .../search-results.component.ts | 2 +- .../shared-files.component.spec.ts | 4 +- .../shared-files/shared-files.component.ts | 2 +- .../toolbar/view-node/view-node.component.ts | 4 +- .../components/viewer/viewer.component.html | 2 +- src/app/components/viewer/viewer.component.ts | 12 ++- src/app/store/effects/viewer.effects.spec.ts | 17 +++- src/app/store/effects/viewer.effects.ts | 29 ++++-- 19 files changed, 186 insertions(+), 82 deletions(-) diff --git a/docs/extending/application-actions.md b/docs/extending/application-actions.md index e9b543147..cd48959b2 100644 --- a/docs/extending/application-actions.md +++ b/docs/extending/application-actions.md @@ -76,51 +76,51 @@ and perform document list reload if needed. Below is the list of public actions types you can use in the plugin definitions as a reference to the action: -| Version | Name | Payload | Description | -| ------- | ---------------------- | ------------------- | ----------------------------------------------------------------------------------------------- | -| 1.7.0 | SET_CURRENT_FOLDER | Node | Notify components about currently opened folder. | -| 1.7.0 | SET_CURRENT_URL | string | Notify components about current browser URL. | -| 1.7.0 | SET_USER_PROFILE | Person | Assign current user profile. | -| 1.7.0 | TOGGLE_INFO_DRAWER | n/a | Toggle info drawer for the selected node. | -| 1.7.0 | ADD_FAVORITE | MinimalNodeEntity[] | Add nodes (or selection) to favorites. | -| 1.7.0 | REMOVE_FAVORITE | MinimalNodeEntity[] | Removes nodes (or selection) from favorites. | -| 1.7.0 | DELETE_LIBRARY | string | Delete a Library by id. Takes selected node if payload not provided. | -| 1.7.0 | CREATE_LIBRARY | n/a | Invoke a "Create Library" dialog. | -| 1.7.0 | SET_SELECTED_NODES | MinimalNodeEntity[] | Notify components about selected nodes. | -| 1.7.0 | DELETE_NODES | MinimalNodeEntity[] | Delete the nodes (or selection). Supports undo actions. | -| 1.7.0 | UNDO_DELETE_NODES | any[] | Reverts deletion of nodes (or selection). | -| 1.7.0 | RESTORE_DELETED_NODES | MinimalNodeEntity[] | Restores deleted nodes (or selection). Typically used with Trashcan. | -| 1.7.0 | PURGE_DELETED_NODES | MinimalNodeEntity[] | Permanently delete nodes (or selection). Typically used with Trashcan. | -| 1.7.0 | DOWNLOAD_NODES | MinimalNodeEntity[] | Download nodes (or selections). Creates a ZIP archive for folders or multiple items. | -| 1.7.0 | CREATE_FOLDER | string | Invoke a "Create Folder" dialog for the opened folder (or the parent folder id in the payload). | -| 1.7.0 | EDIT_FOLDER | MinimalNodeEntity | Invoke an "Edit Folder" dialog for the node (or selection). | -| 1.7.0 | SHARE_NODE | MinimalNodeEntity | Invoke a "Share" dialog for the node (or selection). | -| 1.7.0 | UNSHARE_NODES | MinimalNodeEntity[] | Remove nodes (or selection) from the shared nodes (does not remove content). | -| 1.7.0 | COPY_NODES | MinimalNodeEntity[] | Invoke a "Copy" dialog for the nodes (or selection). Supports undo actions. | -| 1.7.0 | MOVE_NODES | MinimalNodeEntity[] | Invoke a "Move" dialog for the nodes (or selection). Supports undo actions. | -| 1.7.0 | MANAGE_PERMISSIONS | MinimalNodeEntity | Invoke a "Manage Permissions" dialog for the node (or selection). | -| 1.7.0 | MANAGE_VERSIONS | MinimalNodeEntity | Invoke a "Manage Versions" dialog for the node (or selection). | -| 1.7.0 | NAVIGATE_URL | string | Navigate to a given route URL within the application. | -| 1.7.0 | NAVIGATE_ROUTE | any[] | Navigate to a particular Route (supports parameters). | -| 1.7.0 | NAVIGATE_FOLDER | MinimalNodeEntity | Navigate to a folder based on the Node properties. | -| 1.7.0 | NAVIGATE_PARENT_FOLDER | MinimalNodeEntity | Navigate to a containing folder based on the Node properties. | -| 1.7.0 | NAVIGATE_LIBRARY | string | Navigate to library. | -| 1.7.0 | SEARCH_BY_TERM | string | Perform a simple search by the term and navigate to Search results. | -| 1.7.0 | SNACKBAR_INFO | string | Show information snackbar with the message provided. | -| 1.7.0 | SNACKBAR_WARNING | string | Show warning snackbar with the message provided. | -| 1.7.0 | SNACKBAR_ERROR | string | Show error snackbar with the message provided. | -| 1.7.0 | UPLOAD_FILES | n/a | Invoke "Upload Files" dialog and upload files to the currently opened folder. | -| 1.7.0 | UPLOAD_FOLDER | n/a | Invoke "Upload Folder" dialog and upload selected folder to the currently opened one. | -| 1.7.0 | UPLOAD_FILE_VERSION | n/a | Invoke "New File Version" dialog. | -| 1.7.0 | VIEW_FILE | MinimalNodeEntity | Preview the file (or selection) in the Viewer. | -| 1.7.0 | UNLOCK_WRITE | NodeEntry | Unlock file from read only mode | -| 1.7.0 | PRINT_FILE | MinimalNodeEntity | Print the file opened in the Viewer (or selected). | -| 1.7.0 | FULLSCREEN_VIEWER | n/a | Enters fullscreen mode to view the file opened in the Viewer. | -| 1.7.0 | LOGOUT | n/a | Log out and redirect to Login screen. | -| 1.7.0 | RELOAD_DOCUMENT_LIST | n/a | Reload active document list | -| 1.7.0 | TOGGLE_SEARCH_FILTER | n/a | Toggle Filter component visibility in Search Results. | -| 1.7.0 | SHOW_SEARCH_FILTER | n/a | Show Filter component in Search Results. | -| 1.7.0 | HIDE_SEARCH_FILTER | n/a | Hide Filter component in Search Results | -| 1.8.0 | VIEW_NODE | string | Lightweight preview of a node by id. Can be invoked from extensions. | -| 1.8.0 | CLOSE_PREVIEW | n/a | Closes the viewer ( preview of the item ) | -| 1.9.0 | RESET_SELECTION | n/a | Resets active document list selection | +| Version | Name | Payload | Description | +| ------- | ---------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | +| 1.7.0 | SET_CURRENT_FOLDER | Node | Notify components about currently opened folder. | +| 1.7.0 | SET_CURRENT_URL | string | Notify components about current browser URL. | +| 1.7.0 | SET_USER_PROFILE | Person | Assign current user profile. | +| 1.7.0 | TOGGLE_INFO_DRAWER | n/a | Toggle info drawer for the selected node. | +| 1.7.0 | ADD_FAVORITE | MinimalNodeEntity[] | Add nodes (or selection) to favorites. | +| 1.7.0 | REMOVE_FAVORITE | MinimalNodeEntity[] | Removes nodes (or selection) from favorites. | +| 1.7.0 | DELETE_LIBRARY | string | Delete a Library by id. Takes selected node if payload not provided. | +| 1.7.0 | CREATE_LIBRARY | n/a | Invoke a "Create Library" dialog. | +| 1.7.0 | SET_SELECTED_NODES | MinimalNodeEntity[] | Notify components about selected nodes. | +| 1.7.0 | DELETE_NODES | MinimalNodeEntity[] | Delete the nodes (or selection). Supports undo actions. | +| 1.7.0 | UNDO_DELETE_NODES | any[] | Reverts deletion of nodes (or selection). | +| 1.7.0 | RESTORE_DELETED_NODES | MinimalNodeEntity[] | Restores deleted nodes (or selection). Typically used with Trashcan. | +| 1.7.0 | PURGE_DELETED_NODES | MinimalNodeEntity[] | Permanently delete nodes (or selection). Typically used with Trashcan. | +| 1.7.0 | DOWNLOAD_NODES | MinimalNodeEntity[] | Download nodes (or selections). Creates a ZIP archive for folders or multiple items. | +| 1.7.0 | CREATE_FOLDER | string | Invoke a "Create Folder" dialog for the opened folder (or the parent folder id in the payload). | +| 1.7.0 | EDIT_FOLDER | MinimalNodeEntity | Invoke an "Edit Folder" dialog for the node (or selection). | +| 1.7.0 | SHARE_NODE | MinimalNodeEntity | Invoke a "Share" dialog for the node (or selection). | +| 1.7.0 | UNSHARE_NODES | MinimalNodeEntity[] | Remove nodes (or selection) from the shared nodes (does not remove content). | +| 1.7.0 | COPY_NODES | MinimalNodeEntity[] | Invoke a "Copy" dialog for the nodes (or selection). Supports undo actions. | +| 1.7.0 | MOVE_NODES | MinimalNodeEntity[] | Invoke a "Move" dialog for the nodes (or selection). Supports undo actions. | +| 1.7.0 | MANAGE_PERMISSIONS | MinimalNodeEntity | Invoke a "Manage Permissions" dialog for the node (or selection). | +| 1.7.0 | MANAGE_VERSIONS | MinimalNodeEntity | Invoke a "Manage Versions" dialog for the node (or selection). | +| 1.7.0 | NAVIGATE_URL | string | Navigate to a given route URL within the application. | +| 1.7.0 | NAVIGATE_ROUTE | any[] | Navigate to a particular Route (supports parameters). | +| 1.7.0 | NAVIGATE_FOLDER | MinimalNodeEntity | Navigate to a folder based on the Node properties. | +| 1.7.0 | NAVIGATE_PARENT_FOLDER | MinimalNodeEntity | Navigate to a containing folder based on the Node properties. | +| 1.7.0 | NAVIGATE_LIBRARY | string | Navigate to library. | +| 1.7.0 | SEARCH_BY_TERM | string | Perform a simple search by the term and navigate to Search results. | +| 1.7.0 | SNACKBAR_INFO | string | Show information snackbar with the message provided. | +| 1.7.0 | SNACKBAR_WARNING | string | Show warning snackbar with the message provided. | +| 1.7.0 | SNACKBAR_ERROR | string | Show error snackbar with the message provided. | +| 1.7.0 | UPLOAD_FILES | n/a | Invoke "Upload Files" dialog and upload files to the currently opened folder. | +| 1.7.0 | UPLOAD_FOLDER | n/a | Invoke "Upload Folder" dialog and upload selected folder to the currently opened one. | +| 1.7.0 | UPLOAD_FILE_VERSION | n/a | Invoke "New File Version" dialog. | +| 1.7.0 | VIEW_FILE | MinimalNodeEntity | Preview the file (or selection) in the Viewer. | +| 1.7.0 | UNLOCK_WRITE | NodeEntry | Unlock file from read only mode | +| 1.7.0 | PRINT_FILE | MinimalNodeEntity | Print the file opened in the Viewer (or selected). | +| 1.7.0 | FULLSCREEN_VIEWER | n/a | Enters fullscreen mode to view the file opened in the Viewer. | +| 1.7.0 | LOGOUT | n/a | Log out and redirect to Login screen. | +| 1.7.0 | RELOAD_DOCUMENT_LIST | n/a | Reload active document list | +| 1.7.0 | TOGGLE_SEARCH_FILTER | n/a | Toggle Filter component visibility in Search Results. | +| 1.7.0 | SHOW_SEARCH_FILTER | n/a | Show Filter component in Search Results. | +| 1.7.0 | HIDE_SEARCH_FILTER | n/a | Hide Filter component in Search Results | +| 1.8.0 | VIEW_NODE | NodeId<`string`> , [ViewNodeExtras](../features/file-viewer.md#details)<`any`> | Lightweight preview of a node by id. Can be invoked from extensions. For details also see [File Viewer](../features/file-viewer.md#details) | +| 1.8.0 | CLOSE_PREVIEW | n/a | Closes the viewer ( preview of the item ) | +| 1.9.0 | RESET_SELECTION | n/a | Resets active document list selection | diff --git a/docs/features/file-viewer.md b/docs/features/file-viewer.md index 2f62e76fb..057acf9d0 100644 --- a/docs/features/file-viewer.md +++ b/docs/features/file-viewer.md @@ -59,3 +59,66 @@ At the bottom of the content the Viewer Controls allow users to interact with th - Toggle audio - Audio volume - Full screen + +## Details + +The viewer can be invoked by calling [ViewNodeAction](../extending/application-actions). This method supports a second parameter `ViewNodeExtras` which affects the behaviour on opening and closing hte viewer as detailed bellow. + +```typescript +// ViewNodeExtras + +export interface ViewNodeExtras { + location?: string; + path?: string; +} +``` + +```typescript +// app.routes.ts +... +{ + path: 'custom-path', + children: [ + { + path: '', + component: CustomComponent + }, + { + path: 'view/:nodeId', + outlet: 'viewer', + children: [ + { + path: '', + loadChildren: './components/viewer/viewer.module#AppViewerModule' + } + ] + } + ] +} +... +``` + +```typescript +// custom-component.component.ts + +import { ViewNodeAction } from '@alfresco/aca-shared/store'; +import { Router } from '@angular/router'; + +@Component({...}) +export class CustomComponent { + constructor(private store: Store<AppStore>, private router: Router) + + viewNode(nodeId: string) { + this.store.dispatch(new ViewNodeAction(nodeId, { location: this.router.url })); + } +} +``` + +In the above example, passing `location` when calling `ViewNodeAction` will open the viewer relative to current activated route _/custom-path/(viewer:view/nodeId)_. + +If no location is passed, the viewer will default to open on a [predefined route](https://github.com/Alfresco/alfresco-content-app/blob/development/src/app/app.routes.ts#L58). In this case, in order to get back to original location from where the viewer was invoked, `ViewNodeAction` should be called by passing a `path`. + +```typescript +// when invoked from an extension +this.store.dispatch(new ViewNodeAction(nodeId, { path: this.router.url })); +``` diff --git a/projects/aca-shared/store/src/actions/viewer.actions.ts b/projects/aca-shared/store/src/actions/viewer.actions.ts index a2df908f6..6b97ee3ed 100644 --- a/projects/aca-shared/store/src/actions/viewer.actions.ts +++ b/projects/aca-shared/store/src/actions/viewer.actions.ts @@ -33,6 +33,11 @@ export enum ViewerActionTypes { ClosePreview = 'CLOSE_PREVIEW' } +export interface ViewNodeExtras { + location?: string; + path?: string; +} + export class ViewFileAction implements Action { readonly type = ViewerActionTypes.ViewFile; @@ -42,7 +47,7 @@ export class ViewFileAction implements Action { export class ViewNodeAction implements Action { readonly type = ViewerActionTypes.ViewNode; - constructor(public nodeId: string, public location?: string) {} + constructor(public nodeId: string, public viewNodeExtras?: ViewNodeExtras) {} } export class FullscreenViewerAction implements Action { diff --git a/src/app/components/favorites/favorites.component.spec.ts b/src/app/components/favorites/favorites.component.spec.ts index 0f4ba3f96..20298cbe5 100644 --- a/src/app/components/favorites/favorites.component.spec.ts +++ b/src/app/components/favorites/favorites.component.spec.ts @@ -185,9 +185,8 @@ describe('FavoritesComponent', () => { fixture.detectChanges(); component.onNodeDoubleClick(nodeEntity); - expect(component.showPreview).toHaveBeenCalledWith( - nodeEntity, - mockRouter.url - ); + expect(component.showPreview).toHaveBeenCalledWith(nodeEntity, { + location: mockRouter.url + }); }); }); diff --git a/src/app/components/favorites/favorites.component.ts b/src/app/components/favorites/favorites.component.ts index 7fb7b06ed..591f6e4b4 100644 --- a/src/app/components/favorites/favorites.component.ts +++ b/src/app/components/favorites/favorites.component.ts @@ -112,7 +112,7 @@ export class FavoritesComponent extends PageComponent implements OnInit { } if (node.entry.isFile) { - this.showPreview(node, this.router.url); + this.showPreview(node, { location: this.router.url }); } } } diff --git a/src/app/components/files/files.component.ts b/src/app/components/files/files.component.ts index 7ae66abf5..1e9424175 100644 --- a/src/app/components/files/files.component.ts +++ b/src/app/components/files/files.component.ts @@ -151,7 +151,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { return; } - this.showPreview(node, this.router.url); + this.showPreview(node, { location: this.router.url }); } } diff --git a/src/app/components/page.component.ts b/src/app/components/page.component.ts index 4cff08bb9..505c5f5f0 100644 --- a/src/app/components/page.component.ts +++ b/src/app/components/page.component.ts @@ -43,7 +43,8 @@ import { getDocumentDisplayMode, isInfoDrawerOpened, getSharedUrl, - ViewNodeAction + ViewNodeAction, + ViewNodeExtras } from '@alfresco/aca-shared/store'; import { isLocked, isLibrary } from '../utils/node.utils'; @@ -105,12 +106,12 @@ export abstract class PageComponent implements OnInit, OnDestroy { this.onDestroy$.complete(); } - showPreview(node: MinimalNodeEntity, location?: string) { + showPreview(node: MinimalNodeEntity, extras?: ViewNodeExtras) { if (node && node.entry) { const id = (<any>node).entry.nodeId || (<any>node).entry.guid || node.entry.id; - this.store.dispatch(new ViewNodeAction(id, location)); + this.store.dispatch(new ViewNodeAction(id, extras)); } } diff --git a/src/app/components/recent-files/recent-files.component.spec.ts b/src/app/components/recent-files/recent-files.component.spec.ts index 51cb5ecd1..71ae7ad17 100644 --- a/src/app/components/recent-files/recent-files.component.spec.ts +++ b/src/app/components/recent-files/recent-files.component.spec.ts @@ -124,6 +124,8 @@ describe('RecentFilesComponent', () => { fixture.detectChanges(); component.onNodeDoubleClick(node); - expect(component.showPreview).toHaveBeenCalledWith(node, mockRouter.url); + expect(component.showPreview).toHaveBeenCalledWith(node, { + location: mockRouter.url + }); }); }); diff --git a/src/app/components/recent-files/recent-files.component.ts b/src/app/components/recent-files/recent-files.component.ts index 12c017edd..9033c053e 100644 --- a/src/app/components/recent-files/recent-files.component.ts +++ b/src/app/components/recent-files/recent-files.component.ts @@ -77,7 +77,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit { onNodeDoubleClick(node: MinimalNodeEntity) { if (node && node.entry) { - this.showPreview(node, this.router.url); + this.showPreview(node, { location: this.router.url }); } } diff --git a/src/app/components/search/search-results-row/search-results-row.component.ts b/src/app/components/search/search-results-row/search-results-row.component.ts index ee11f7ff5..4a9612ce6 100644 --- a/src/app/components/search/search-results-row/search-results-row.component.ts +++ b/src/app/components/search/search-results-row/search-results-row.component.ts @@ -126,7 +126,7 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy { showPreview(event: MouseEvent) { event.stopPropagation(); this.store.dispatch( - new ViewNodeAction(this.node.entry.id, this.router.url) + new ViewNodeAction(this.node.entry.id, { location: this.router.url }) ); } diff --git a/src/app/components/search/search-results/search-results.component.spec.ts b/src/app/components/search/search-results/search-results.component.spec.ts index e69839643..209a63886 100644 --- a/src/app/components/search/search-results/search-results.component.spec.ts +++ b/src/app/components/search/search-results/search-results.component.spec.ts @@ -305,7 +305,9 @@ describe('SearchComponent', () => { component.onNodeDoubleClick(node); - expect(component.showPreview).toHaveBeenCalledWith(node, router.url); + expect(component.showPreview).toHaveBeenCalledWith(node, { + location: router.url + }); }); it('should re-run search on pagination change', () => { diff --git a/src/app/components/search/search-results/search-results.component.ts b/src/app/components/search/search-results/search-results.component.ts index 2ab713bb2..d0674e5f9 100644 --- a/src/app/components/search/search-results/search-results.component.ts +++ b/src/app/components/search/search-results/search-results.component.ts @@ -253,7 +253,7 @@ export class SearchResultsComponent extends PageComponent implements OnInit { return; } - this.showPreview(node, this.router.url); + this.showPreview(node, { location: this.router.url }); } } diff --git a/src/app/components/shared-files/shared-files.component.spec.ts b/src/app/components/shared-files/shared-files.component.spec.ts index 2f7d21124..fc9857006 100644 --- a/src/app/components/shared-files/shared-files.component.spec.ts +++ b/src/app/components/shared-files/shared-files.component.spec.ts @@ -131,6 +131,8 @@ describe('SharedFilesComponent', () => { fixture.detectChanges(); component.preview(node); - expect(component.showPreview).toHaveBeenCalledWith(node, mockRouter.url); + expect(component.showPreview).toHaveBeenCalledWith(node, { + location: mockRouter.url + }); }); }); diff --git a/src/app/components/shared-files/shared-files.component.ts b/src/app/components/shared-files/shared-files.component.ts index be71ab616..668a64c72 100644 --- a/src/app/components/shared-files/shared-files.component.ts +++ b/src/app/components/shared-files/shared-files.component.ts @@ -79,6 +79,6 @@ export class SharedFilesComponent extends PageComponent implements OnInit { } preview(node: MinimalNodeEntity) { - this.showPreview(node, this.router.url); + this.showPreview(node, { location: this.router.url }); } } diff --git a/src/app/components/toolbar/view-node/view-node.component.ts b/src/app/components/toolbar/view-node/view-node.component.ts index a6fb5cc1d..c00f27646 100644 --- a/src/app/components/toolbar/view-node/view-node.component.ts +++ b/src/app/components/toolbar/view-node/view-node.component.ts @@ -69,7 +69,9 @@ export class ViewNodeComponent { (<any>selection.file).entry.guid || selection.file.entry.id; - this.store.dispatch(new ViewNodeAction(id, this.router.url)); + this.store.dispatch( + new ViewNodeAction(id, { location: this.router.url }) + ); }); } } diff --git a/src/app/components/viewer/viewer.component.html b/src/app/components/viewer/viewer.component.html index c95ec7a5b..0fb7c3bbd 100644 --- a/src/app/components/viewer/viewer.component.html +++ b/src/app/components/viewer/viewer.component.html @@ -11,7 +11,7 @@ [allowDownload]="false" [allowFullScreen]="false" [overlayMode]="true" - (showViewerChange)="onViewerVisibilityChanged($event)" + (showViewerChange)="onViewerVisibilityChanged()" [canNavigateBefore]="previousNodeId" [canNavigateNext]="nextNodeId" (navigateBefore)="onNavigateBefore()" diff --git a/src/app/components/viewer/viewer.component.ts b/src/app/components/viewer/viewer.component.ts index a548364c5..237869b90 100644 --- a/src/app/components/viewer/viewer.component.ts +++ b/src/app/components/viewer/viewer.component.ts @@ -59,6 +59,8 @@ import { ReloadDocumentListAction } from '@alfresco/aca-shared/store'; host: { class: 'app-viewer' } }) export class AppViewerComponent implements OnInit, OnDestroy { + private navigationPath: string; + onDestroy$ = new Subject<boolean>(); folderId: string = null; @@ -149,6 +151,10 @@ export class AppViewerComponent implements OnInit, OnDestroy { } }); + this.route.queryParams.subscribe(params => { + this.navigationPath = params.path; + }); + if (this.route.snapshot.data && this.route.snapshot.data.navigateSource) { const source = this.route.snapshot.data.navigateSource.toLowerCase(); if (this.navigationSources.includes(source)) { @@ -231,12 +237,12 @@ export class AppViewerComponent implements OnInit, OnDestroy { onNavigateBefore(): void { const location = this.getFileLocation(); - this.store.dispatch(new ViewNodeAction(this.previousNodeId, location)); + this.store.dispatch(new ViewNodeAction(this.previousNodeId, { location })); } onNavigateNext(): void { const location = this.getFileLocation(); - this.store.dispatch(new ViewNodeAction(this.nextNodeId, location)); + this.store.dispatch(new ViewNodeAction(this.nextNodeId, { location })); } /** @@ -425,7 +431,7 @@ export class AppViewerComponent implements OnInit, OnDestroy { private getFileLocation(): string { return this.router - .parseUrl(this.router.url) + .parseUrl(this.navigationPath || this.router.url) .root.children[PRIMARY_OUTLET].toString(); } } diff --git a/src/app/store/effects/viewer.effects.spec.ts b/src/app/store/effects/viewer.effects.spec.ts index da0c9f42a..72f890ec6 100644 --- a/src/app/store/effects/viewer.effects.spec.ts +++ b/src/app/store/effects/viewer.effects.spec.ts @@ -74,12 +74,14 @@ describe('ViewerEffects', () => { }); describe('ViewNode', () => { - it('should open viewer from file location', fakeAsync(() => { - store.dispatch(new ViewNodeAction('nodeId', 'some-location')); + it('should open viewer from file location if', fakeAsync(() => { + store.dispatch( + new ViewNodeAction('nodeId', { location: 'some-location' }) + ); tick(100); expect(router.navigateByUrl['calls'].argsFor(0)[0].toString()).toEqual( - '/some-location/(viewer:view/nodeId)?source=some-location' + '/some-location/(viewer:view/nodeId)?location=some-location' ); })); @@ -91,5 +93,14 @@ describe('ViewerEffects', () => { '/view/(viewer:nodeId)' ); })); + + it('should navigate to viewer route with query param if path is passed', fakeAsync(() => { + store.dispatch(new ViewNodeAction('nodeId', { path: 'absolute-path' })); + tick(100); + + expect(router.navigateByUrl['calls'].argsFor(0)[0].toString()).toEqual( + '/view/(viewer:nodeId)?path=absolute-path' + ); + })); }); }); diff --git a/src/app/store/effects/viewer.effects.ts b/src/app/store/effects/viewer.effects.ts index c65155d51..192b327d5 100644 --- a/src/app/store/effects/viewer.effects.ts +++ b/src/app/store/effects/viewer.effects.ts @@ -77,17 +77,28 @@ export class ViewerEffects { viewNode$ = this.actions$.pipe( ofType<ViewNodeAction>(ViewerActionTypes.ViewNode), map(action => { - if (action.location) { - const location = this.getNavigationCommands(action.location); + if (action.viewNodeExtras) { + const { location, path } = action.viewNodeExtras; - this.router.navigate( - [...location, { outlets: { viewer: ['view', action.nodeId] } }], - { - queryParams: { - source: action.location + if (location) { + const navigation = this.getNavigationCommands(location); + + this.router.navigate( + [...navigation, { outlets: { viewer: ['view', action.nodeId] } }], + { + queryParams: { location } } - } - ); + ); + } + + if (path) { + this.router.navigate( + ['view', { outlets: { viewer: [action.nodeId] } }], + { + queryParams: { path } + } + ); + } } else { this.router.navigate([ 'view',