[ARVADOS-WORKBENCH2] updated: 1.2.0-265-gc276ce4

Git user git at public.curoverse.com
Tue Sep 4 03:49:19 EDT 2018


Summary of changes:
 src/common/formatters.ts                           |  11 +-
 .../data-explorer/data-explorer.test.tsx           |   1 +
 src/components/data-explorer/data-explorer.tsx     |   5 +-
 src/components/icon/icon.tsx                       |   2 +
 src/index.tsx                                      |   2 +
 src/models/collection.ts                           |   9 +-
 src/models/group.ts                                |   9 +-
 src/models/project.ts                              |   2 +-
 src/models/resource.ts                             |   9 +-
 src/models/test-utils.ts                           |   4 +-
 src/routes/routes.ts                               |  17 +-
 .../ancestors-service/ancestors-service.ts         |   6 +-
 .../api/filter-builder.test.ts                     |   0
 src/{common => services}/api/filter-builder.ts     |   0
 src/{common => services}/api/order-builder.test.ts |   0
 src/{common => services}/api/order-builder.ts      |   2 +-
 src/{common => services}/api/url-builder.ts        |   0
 .../collection-files-service.ts                    |   2 +-
 .../collection-service/collection-service.ts       |   5 +-
 .../common-resource-service.test.ts                |   2 +-
 .../common-service}/common-resource-service.ts     |   2 +-
 .../common-service/trashable-resource-service.ts   |  32 ++++
 .../container-request-service.ts                   |   2 +-
 .../container-service/container-service.ts         |   2 +-
 .../favorite-service/favorite-service.test.ts      |   4 +-
 src/services/favorite-service/favorite-service.ts  |   4 +-
 src/services/groups-service/groups-service.test.ts |   2 +-
 src/services/groups-service/groups-service.ts      |  10 +-
 src/services/keep-service/keep-service.ts          |   2 +-
 src/services/link-service/link-service.ts          |   2 +-
 src/services/log-service/log-service.ts            |   2 +-
 .../project-service/project-service.test.ts        |   2 +-
 src/services/project-service/project-service.ts    |   4 +-
 src/services/tag-service/tag-service.ts            |   4 +-
 src/services/user-service/user-service.ts          |   4 +-
 .../collection-panel-files-actions.ts              |   2 +-
 src/store/collections/collection-copy-actions.ts   |   4 +-
 src/store/collections/collection-create-actions.ts |   2 +-
 src/store/collections/collection-move-actions.ts   |   2 +-
 .../collections/collection-partial-copy-actions.ts |   4 +-
 src/store/collections/collection-update-actions.ts |  10 +-
 src/store/context-menu/context-menu-actions.ts     |  49 +++--
 src/store/context-menu/context-menu-reducer.ts     |   9 +-
 .../data-explorer-middleware-service.ts            |   4 +-
 .../favorite-panel-middleware-service.ts           |   4 +-
 src/store/navigation/navigation-action.ts          |   2 +
 .../process-logs-panel-actions.ts                  |   6 +-
 src/store/processes/processes-actions.ts           |   2 +-
 .../project-panel-middleware-service.ts            |   6 +-
 src/store/projects/project-create-actions.ts       |   2 +-
 src/store/projects/project-move-actions.ts         |   2 +-
 src/store/projects/project-update-actions.ts       |   6 +-
 .../side-panel-tree/side-panel-tree-actions.ts     |   2 +-
 src/store/side-panel/side-panel-action.ts          |   6 +-
 src/store/store.ts                                 |   8 +-
 src/store/trash-panel/trash-panel-action.ts        |  11 ++
 .../trash-panel/trash-panel-middleware-service.ts  |  84 +++++++++
 src/store/trash/trash-actions.ts                   |  66 +++++++
 src/store/workbench/workbench-actions.ts           |  13 +-
 .../collection-panel-files.ts                      |  20 ++-
 .../action-sets/collection-action-set.ts           |   8 +
 .../action-sets/collection-resource-action-set.ts  |   8 +
 .../context-menu/action-sets/project-action-set.ts |   8 +
 .../context-menu/action-sets/trash-action-set.ts   |  16 ++
 .../{favorite-action.tsx => trash-action.tsx}      |  19 +-
 .../context-menu/context-menu-action-set.ts        |   2 +-
 src/views-components/context-menu/context-menu.tsx |   6 +-
 src/views-components/data-explorer/renderers.tsx   |  30 +++-
 .../project-tree-picker/project-tree-picker.tsx    |   2 +-
 src/views/collection-panel/collection-panel.tsx    |  10 +-
 src/views/favorite-panel/favorite-panel.tsx        |  29 ++-
 src/views/project-panel/project-panel.tsx          |  21 ++-
 src/views/trash-panel/trash-panel.tsx              | 199 +++++++++++++++++++++
 src/views/workbench/workbench.tsx                  |   3 +
 src/websocket/websocket-service.ts                 |   2 +-
 src/websocket/websocket.ts                         |   6 +-
 76 files changed, 688 insertions(+), 173 deletions(-)
 rename src/{common => services}/api/filter-builder.test.ts (100%)
 rename src/{common => services}/api/filter-builder.ts (100%)
 rename src/{common => services}/api/order-builder.test.ts (100%)
 rename src/{common => services}/api/order-builder.ts (94%)
 rename src/{common => services}/api/url-builder.ts (100%)
 rename src/{common/api => services/common-service}/common-resource-service.test.ts (98%)
 rename src/{common/api => services/common-service}/common-resource-service.ts (98%)
 create mode 100644 src/services/common-service/trashable-resource-service.ts
 create mode 100644 src/store/trash-panel/trash-panel-action.ts
 create mode 100644 src/store/trash-panel/trash-panel-middleware-service.ts
 create mode 100644 src/store/trash/trash-actions.ts
 create mode 100644 src/views-components/context-menu/action-sets/trash-action-set.ts
 copy src/views-components/context-menu/actions/{favorite-action.tsx => trash-action.tsx} (50%)
 create mode 100644 src/views/trash-panel/trash-panel.tsx

       via  c276ce4c8dd3cf27ad6d17eca9af473f353fda55 (commit)
       via  e53e6f1efe7b156934514b51fd5f956262f6f9af (commit)
       via  88ce683068f65862b3b5e753e55989902be5f1a9 (commit)
       via  ec00e13345fd6731287124ee776e0e4892c1cf13 (commit)
       via  59ee572e791985a36bdd2015c9b494145109e8ed (commit)
       via  7792c5200c3144fcc75e102f2aeaf4862252ec8e (commit)
       via  46f597da5c34d80250cc7efd87d2ce087528ed5f (commit)
       via  3eeb63ce55c9156f96f933a0cff5eab3dab86392 (commit)
       via  9cb78f72cfe7da0fd3e04609f13d5f930a76a2f1 (commit)
       via  1baec2d74e64375ce1b410f6a66fc8c8c9848307 (commit)
       via  25691034b44b9323cae96c8db002826880ccfd7e (commit)
       via  f63f3a5360ae6381d4b332bf86ef52b4e22107fb (commit)
       via  f1065fb7260dd562ea2e826e9cbc508d7932ecca (commit)
       via  efe0283919eb18e60ad876eaf6edef03c6cf04b3 (commit)
      from  cf9e11013710478809fe44b5cad7d3b77f6d5a1f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit c276ce4c8dd3cf27ad6d17eca9af473f353fda55
Merge: cf9e110 e53e6f1
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Tue Sep 4 09:41:44 2018 +0200

    refs #13828 Merge branch 'origin/13828-trash-view'
    
    # Conflicts:
    #       src/index.tsx
    #       src/routes/routes.ts
    #       src/store/context-menu/context-menu-actions.ts
    #       src/store/store.ts
    #       src/store/workbench/workbench-actions.ts
    #       src/views/workbench/workbench.tsx
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --cc src/components/data-explorer/data-explorer.test.tsx
index 3e447b4,3e447b4..882c178
--- a/src/components/data-explorer/data-explorer.test.tsx
+++ b/src/components/data-explorer/data-explorer.test.tsx
@@@ -124,4 -124,4 +124,5 @@@ const mockDataExplorerProps = () => (
      defaultIcon: ProjectIcon,
      onSetColumns: jest.fn(),
      defaultMessages: ['testing'],
++    contextMenuColumn: true
  });
diff --cc src/index.tsx
index 20d2c1e,6137e26..4ce80d3
--- a/src/index.tsx
+++ b/src/index.tsx
@@@ -31,9 -31,7 +31,10 @@@ import { processActionSet } from './vie
  import { addRouteChangeHandlers } from './routes/routes';
  import { loadWorkbench } from './store/workbench/workbench-actions';
  import { Routes } from '~/routes/routes';
+ import { trashActionSet } from "~/views-components/context-menu/action-sets/trash-action-set";
 +import { ServiceRepository } from '~/services/services';
 +import { initWebSocket } from '~/websocket/websocket';
 +import { Config } from '~/common/config';
  
  const getBuildNumber = () => "BN-" + (process.env.REACT_APP_BUILD_NUMBER || "dev");
  const getGitCommit = () => "GIT-" + (process.env.REACT_APP_GIT_COMMIT || "latest").substr(0, 7);
diff --cc src/routes/routes.ts
index 6901d87,d119321..05a8ab0
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@@ -6,9 -6,9 +6,9 @@@ import { History, Location } from 'hist
  import { RootStore } from '~/store/store';
  import { matchPath } from 'react-router';
  import { ResourceKind, RESOURCE_UUID_PATTERN, extractUuidKind } from '~/models/resource';
- import { getProjectUrl } from '../models/project';
+ import { getProjectUrl } from '~/models/project';
  import { getCollectionUrl } from '~/models/collection';
- import { loadProject, loadFavorites, loadCollection, loadProcessLog } from '~/store/workbench/workbench-actions';
 -import { loadProject, loadFavorites, loadCollection, loadTrash } from '~/store/workbench/workbench-actions';
++import { loadProject, loadFavorites, loadCollection, loadTrash, loadProcessLog } from '~/store/workbench/workbench-actions';
  import { loadProcess } from '~/store/processes/processes-actions';
  
  export const Routes = {
@@@ -18,7 -18,7 +18,8 @@@
      COLLECTIONS: `/collections/:id(${RESOURCE_UUID_PATTERN})`,
      PROCESSES: `/processes/:id(${RESOURCE_UUID_PATTERN})`,
      FAVORITES: '/favorites',
 -    TRASH: '/trash'
++    TRASH: '/trash',
 +    PROCESS_LOGS: `/process-logs/:id(${RESOURCE_UUID_PATTERN})`
  };
  
  export const getResourceUrl = (uuid: string) => {
@@@ -69,18 -68,17 +73,21 @@@ const handleLocationChange = (store: Ro
      const projectMatch = matchProjectRoute(pathname);
      const collectionMatch = matchCollectionRoute(pathname);
      const favoriteMatch = matchFavoritesRoute(pathname);
+     const trashMatch = matchTrashRoute(pathname);
      const processMatch = matchProcessRoute(pathname);
 +    const processLogMatch = matchProcessLogRoute(pathname);
 +    
      if (projectMatch) {
          store.dispatch(loadProject(projectMatch.params.id));
      } else if (collectionMatch) {
          store.dispatch(loadCollection(collectionMatch.params.id));
      } else if (favoriteMatch) {
          store.dispatch(loadFavorites());
+     } else if (trashMatch) {
+         store.dispatch(loadTrash());
      } else if (processMatch) {
          store.dispatch(loadProcess(processMatch.params.id));
 +    } else if (processLogMatch) {
 +        store.dispatch(loadProcessLog(processLogMatch.params.id));
      }
  };
diff --cc src/services/groups-service/groups-service.test.ts
index c3be8bd,c3be8bd..e1157f4
--- a/src/services/groups-service/groups-service.test.ts
+++ b/src/services/groups-service/groups-service.test.ts
@@@ -16,7 -16,7 +16,7 @@@ describe("GroupsService", () => 
  
      it("#contents", async () => {
          axiosMock
--            .onGet("/groups/1/contents/")
++            .onGet("/groups/1/contents")
              .reply(200, {
                  kind: "kind",
                  offset: 2,
diff --cc src/services/log-service/log-service.ts
index c92475d,0000000..8f6c66c
mode 100644,000000..100644
--- a/src/services/log-service/log-service.ts
+++ b/src/services/log-service/log-service.ts
@@@ -1,13 -1,0 +1,13 @@@
 +// Copyright (C) The Arvados Authors. All rights reserved.
 +//
 +// SPDX-License-Identifier: AGPL-3.0
 +
- import { CommonResourceService } from "~/common/api/common-resource-service";
 +import { AxiosInstance } from "axios";
 +import { LogResource } from '~/models/log';
++import { CommonResourceService } from "~/services/common-service/common-resource-service";
 +
 +export class LogService extends CommonResourceService<LogResource> {
 +    constructor(serverApi: AxiosInstance) {
 +        super(serverApi, "logs");
 +    }
 +}
diff --cc src/store/context-menu/context-menu-actions.ts
index 3440a30,85e5761..2b0e6f8
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@@ -70,18 -85,13 +85,20 @@@ export const openSidePanelContextMenu 
  
  export const openProcessContextMenu = (event: React.MouseEvent<HTMLElement>) =>
      (dispatch: Dispatch, getState: () => RootState) => {
 +        const { location } = getState().router;
 +        const pathname = location ? location.pathname : '';
 +        // ToDo: We get error from matchProcessRoute
 +        // const match = matchProcessRoute(pathname); 
 +        // console.log('match: ', match);
 +        // const uuid = match ? match.params.id : '';
 +        const uuid = pathname.split('/').slice(-1)[0];
          const resource = {
-             uuid,
+             uuid: '',
+             ownerUuid: '',
+             kind: ResourceKind.PROCESS,
              name: '',
              description: '',
-             kind: ContextMenuKind.PROCESS
+             menuKind: ContextMenuKind.PROCESS
          };
          dispatch<any>(openContextMenu(event, resource));
      };
diff --cc src/store/process-logs-panel/process-logs-panel-actions.ts
index 62c9a25,0000000..79c6434
mode 100644,000000..100644
--- a/src/store/process-logs-panel/process-logs-panel-actions.ts
+++ b/src/store/process-logs-panel/process-logs-panel-actions.ts
@@@ -1,114 -1,0 +1,114 @@@
 +// Copyright (C) The Arvados Authors. All rights reserved.
 +//
 +// SPDX-License-Identifier: AGPL-3.0
 +
 +import { unionize, ofType, UnionOf } from "~/common/unionize";
 +import { ProcessLogs, getProcessLogsPanelCurrentUuid } from './process-logs-panel';
 +import { LogEventType } from '~/models/log';
 +import { RootState } from '~/store/store';
 +import { ServiceRepository } from '~/services/services';
 +import { Dispatch } from 'redux';
- import { FilterBuilder } from '~/common/api/filter-builder';
 +import { groupBy } from 'lodash';
 +import { loadProcess } from '~/store/processes/processes-actions';
- import { OrderBuilder } from '~/common/api/order-builder';
 +import { LogResource } from '~/models/log';
 +import { LogService } from '~/services/log-service/log-service';
- import { ResourceEventMessage } from '../../websocket/resource-event-message';
++import { ResourceEventMessage } from '~/websocket/resource-event-message';
 +import { getProcess } from '~/store/processes/process';
++import { FilterBuilder } from "~/services/api/filter-builder";
++import { OrderBuilder } from "~/services/api/order-builder";
 +
 +export const processLogsPanelActions = unionize({
 +    RESET_PROCESS_LOGS_PANEL: ofType<{}>(),
 +    INIT_PROCESS_LOGS_PANEL: ofType<{ filters: string[], logs: ProcessLogs }>(),
 +    SET_PROCESS_LOGS_PANEL_FILTER: ofType<string>(),
 +    ADD_PROCESS_LOGS_PANEL_ITEM: ofType<{ logType: string, log: string }>(),
 +});
 +
 +export type ProcessLogsPanelAction = UnionOf<typeof processLogsPanelActions>;
 +
 +export const setProcessLogsPanelFilter = (filter: string) =>
 +    processLogsPanelActions.SET_PROCESS_LOGS_PANEL_FILTER(filter);
 +
 +export const initProcessLogsPanel = (processUuid: string) =>
 +    async (dispatch: Dispatch, getState: () => RootState, { logService }: ServiceRepository) => {
 +        dispatch(processLogsPanelActions.RESET_PROCESS_LOGS_PANEL());
 +        const process = await dispatch<any>(loadProcess(processUuid));
 +        if (process.container) {
 +            const logResources = await loadContainerLogs(process.container.uuid, logService);
 +            const initialState = createInitialLogPanelState(logResources);
 +            dispatch(processLogsPanelActions.INIT_PROCESS_LOGS_PANEL(initialState));
 +        }
 +    };
 +
 +export const addProcessLogsPanelItem = (message: ResourceEventMessage<{ text: string }>) =>
 +    async (dispatch: Dispatch, getState: () => RootState, { logService }: ServiceRepository) => {
 +        if (PROCESS_PANEL_LOG_EVENT_TYPES.indexOf(message.eventType) > -1) {
 +            const uuid = getProcessLogsPanelCurrentUuid(getState());
 +            if (uuid) {
 +                const process = getProcess(uuid)(getState().resources);
 +                if (process) {
 +                    const { containerRequest, container } = process;
 +                    if (message.objectUuid === containerRequest.uuid
 +                        || container && message.objectUuid === container.uuid) {
 +                        dispatch(processLogsPanelActions.ADD_PROCESS_LOGS_PANEL_ITEM({
 +                            logType: SUMMARIZED_FILTER_TYPE,
 +                            log: message.properties.text
 +                        }));
 +                        dispatch(processLogsPanelActions.ADD_PROCESS_LOGS_PANEL_ITEM({
 +                            logType: message.eventType,
 +                            log: message.properties.text
 +                        }));
 +                    }
 +                }
 +            }
 +        }
 +    };
 +
 +const loadContainerLogs = async (containerUuid: string, logService: LogService) => {
 +    const requestFilters = new FilterBuilder()
 +        .addEqual('objectUuid', containerUuid)
 +        .addIn('eventType', PROCESS_PANEL_LOG_EVENT_TYPES)
 +        .getFilters();
 +    const requestOrder = new OrderBuilder<LogResource>()
 +        .addAsc('eventAt')
 +        .getOrder();
 +    const requestParams = {
 +        limit: MAX_AMOUNT_OF_LOGS,
 +        filters: requestFilters,
 +        order: requestOrder,
 +    };
 +    const { items } = await logService.list(requestParams);
 +    return items;
 +};
 +
 +const createInitialLogPanelState = (logResources: LogResource[]) => {
 +    const allLogs = logsToLines(logResources);
 +    const groupedLogResources = groupBy(logResources, log => log.eventType);
 +    const groupedLogs = Object
 +        .keys(groupedLogResources)
 +        .reduce((grouped, key) => ({
 +            ...grouped,
 +            [key]: logsToLines(groupedLogResources[key])
 +        }), {});
 +    const filters = [SUMMARIZED_FILTER_TYPE, ...Object.keys(groupedLogs)];
 +    const logs = { [SUMMARIZED_FILTER_TYPE]: allLogs, ...groupedLogs };
 +    return { filters, logs };
 +};
 +
 +const logsToLines = (logs: LogResource[]) =>
 +    logs.map(({ properties }) => properties.text);
 +
 +const MAX_AMOUNT_OF_LOGS = 10000;
 +
 +const SUMMARIZED_FILTER_TYPE = 'Summarized';
 +
 +const PROCESS_PANEL_LOG_EVENT_TYPES = [
 +    LogEventType.ARV_MOUNT,
 +    LogEventType.CRUNCH_RUN,
 +    LogEventType.CRUNCHSTAT,
 +    LogEventType.DISPATCH,
 +    LogEventType.HOSTSTAT,
 +    LogEventType.NODE_INFO,
 +    LogEventType.STDERR,
 +    LogEventType.STDOUT,
 +];
diff --cc src/store/processes/processes-actions.ts
index d94cc01,f026d37..031683a
--- a/src/store/processes/processes-actions.ts
+++ b/src/store/processes/processes-actions.ts
@@@ -6,13 -6,12 +6,13 @@@ import { Dispatch } from "redux"
  import { RootState } from '~/store/store';
  import { ServiceRepository } from '~/services/services';
  import { updateResources } from '~/store/resources/resources-actions';
- import { FilterBuilder } from '~/common/api/filter-builder';
+ import { FilterBuilder } from '~/services/api/filter-builder';
  import { ContainerRequestResource } from '../../models/container-request';
 +import { Process } from './process';
  
 -export const loadProcess = (uuid: string) =>
 -    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
 -        const containerRequest = await services.containerRequestService.get(uuid);
 +export const loadProcess = (containerRequestUuid: string) =>
 +    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<Process> => {
 +        const containerRequest = await services.containerRequestService.get(containerRequestUuid);
          dispatch<any>(updateResources([containerRequest]));
          if (containerRequest.containerUuid) {
              const container = await services.containerService.get(containerRequest.containerUuid);
diff --cc src/store/store.ts
index d0c0dd6,d2371e8..01aca59
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@@ -28,7 -28,8 +28,9 @@@ import { resourcesReducer } from '~/sto
  import { propertiesReducer } from './properties/properties-reducer';
  import { RootState } from './store';
  import { fileUploaderReducer } from './file-uploader/file-uploader-reducer';
+ import { TrashPanelMiddlewareService } from "~/store/trash-panel/trash-panel-middleware-service";
+ import { TRASH_PANEL_ID } from "~/store/trash-panel/trash-panel-action";
 +import { processLogsPanelReducer } from './process-logs-panel/process-logs-panel-reducer';
  
  const composeEnhancers =
      (process.env.NODE_ENV === 'development' &&
diff --cc src/store/workbench/workbench-actions.ts
index 8c7ec9a,1ff3a5b..80f50fe
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@@ -30,7 -30,8 +30,9 @@@ import * as collectionUpdateActions fro
  import * as collectionMoveActions from '~/store/collections/collection-move-actions';
  import * as processesActions from '../processes/processes-actions';
  import { getProcess } from '../processes/process';
+ import { trashPanelColumns } from "~/views/trash-panel/trash-panel";
+ import { loadTrashPanel, trashPanelActions } from "~/store/trash-panel/trash-panel-action";
 +import { initProcessLogsPanel } from '../process-logs-panel/process-logs-panel-actions';
  
  
  export const loadWorkbench = () =>
diff --cc src/views/workbench/workbench.tsx
index 21396d1,68bb970..3c28108
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@@ -167,7 -169,7 +169,8 @@@ export const Workbench = withStyles(sty
                                      <Route path={Routes.COLLECTIONS} component={CollectionPanel} />
                                      <Route path={Routes.FAVORITES} component={FavoritePanel} />
                                      <Route path={Routes.PROCESSES} component={ProcessPanel} />
+                                     <Route path={Routes.TRASH} component={TrashPanel} />
 +                                    <Route path={Routes.PROCESS_LOGS} component={ProcessLogPanel} />
                                  </Switch>
                              </div>
                              {user && <DetailsPanel />}
diff --cc src/websocket/websocket-service.ts
index 77c1fd3,0000000..a5ce13d
mode 100644,000000..100644
--- a/src/websocket/websocket-service.ts
+++ b/src/websocket/websocket-service.ts
@@@ -1,47 -1,0 +1,47 @@@
 +// Copyright (C) The Arvados Authors. All rights reserved.
 +//
 +// SPDX-License-Identifier: AGPL-3.0
 +
 +import { AuthService } from '~/services/auth-service/auth-service';
 +import { ResourceEventMessage } from './resource-event-message';
- import { CommonResourceService } from '~/common/api/common-resource-service';
 +import { camelCase } from 'lodash';
++import { CommonResourceService } from "~/services/common-service/common-resource-service";
 +
 +type MessageListener = (message: ResourceEventMessage) => void;
 +
 +export class WebSocketService {
 +    private ws: WebSocket;
 +    private messageListener: MessageListener;
 +
 +    constructor(private url: string, private authService: AuthService) { }
 +
 +    connect() {
 +        if (this.ws) {
 +            this.ws.close();
 +        }
 +        this.ws = new WebSocket(this.getUrl());
 +        this.ws.addEventListener('message', this.handleMessage);
 +        this.ws.addEventListener('open', this.handleOpen);
 +    }
 +
 +    setMessageListener = (listener: MessageListener) => {
 +        this.messageListener = listener;
 +    }
 +
 +    private getUrl() {
 +        return `${this.url}?api_token=${this.authService.getApiToken()}`;
 +    }
 +
 +    private handleMessage = (event: MessageEvent) => {
 +        if (this.messageListener) {
 +            const data = JSON.parse(event.data);
 +            const message = CommonResourceService.mapKeys(camelCase)(data);
 +            this.messageListener(message);
 +        }
 +    }
 +
 +    private handleOpen = () => {
 +        this.ws.send('{"method":"subscribe"}');
 +    }
 +
 +}
diff --cc src/websocket/websocket.ts
index 634fa8f,0000000..e3f1e19
mode 100644,000000..100644
--- a/src/websocket/websocket.ts
+++ b/src/websocket/websocket.ts
@@@ -1,38 -1,0 +1,38 @@@
 +// Copyright (C) The Arvados Authors. All rights reserved.
 +//
 +// SPDX-License-Identifier: AGPL-3.0
 +
 +import { RootStore } from '~/store/store';
 +import { AuthService } from '~/services/auth-service/auth-service';
 +import { Config } from '~/common/config';
 +import { WebSocketService } from './websocket-service';
 +import { ResourceEventMessage } from './resource-event-message';
 +import { ResourceKind } from '~/models/resource';
 +import { loadProcess } from '~/store/processes/processes-actions';
- import { loadContainers } from '../store/processes/processes-actions';
- import { FilterBuilder } from '~/common/api/filter-builder';
- import { LogEventType } from '../models/log';
++import { loadContainers } from '~/store/processes/processes-actions';
++import { LogEventType } from '~/models/log';
 +import { addProcessLogsPanelItem } from '../store/process-logs-panel/process-logs-panel-actions';
++import { FilterBuilder } from "~/services/api/filter-builder";
 +
 +export const initWebSocket = (config: Config, authService: AuthService, store: RootStore) => {
 +    const webSocketService = new WebSocketService(config.websocketUrl, authService);
 +    webSocketService.setMessageListener(messageListener(store));
 +    webSocketService.connect();
 +};
 +
 +const messageListener = (store: RootStore) => (message: ResourceEventMessage) => {
 +    if (message.eventType === LogEventType.CREATE || message.eventType === LogEventType.UPDATE) {
 +        switch (message.objectKind) {
 +            case ResourceKind.CONTAINER_REQUEST:
 +                return store.dispatch(loadProcess(message.objectUuid));
 +            case ResourceKind.CONTAINER:
 +                return store.dispatch(loadContainers(
 +                    new FilterBuilder().addIn('uuid', [message.objectUuid]).getFilters()
 +                ));
 +            default:
 +                return;
 +        }
 +    } else {
 +        return store.dispatch(addProcessLogsPanelItem(message as ResourceEventMessage<{text: string}>));
 +    }
 +};

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list