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',