Merge branch '13776-update-process-status-calculation'
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 4 Sep 2018 11:10:39 +0000 (13:10 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Tue, 4 Sep 2018 11:10:39 +0000 (13:10 +0200)
refs #13776

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

13 files changed:
src/components/data-table/data-column.ts
src/index.tsx
src/routes/route-change-handlers.ts [new file with mode: 0644]
src/routes/routes.ts
src/store/breadcrumbs/breadcrumbs-actions.ts
src/store/context-menu/context-menu-actions.ts
src/store/favorite-panel/favorite-panel-middleware-service.ts
src/store/processes/process.ts
src/store/project-panel/project-panel-middleware-service.ts
src/store/workbench/workbench-actions.ts
src/views-components/data-explorer/renderers.tsx
src/views/favorite-panel/favorite-panel.tsx
src/views/project-panel/project-panel.tsx

index 90e87a88b0a7225a9cbea0d7b842e5146a593d4c..8dbdf0cc7ad0a1f1d13d2d773a760bda3e289f7a 100644 (file)
@@ -10,7 +10,7 @@ export interface DataColumn<T, F extends DataTableFilterItem = DataTableFilterIt
     name: string;
     selected: boolean;
     configurable: boolean;
-    sortDirection: SortDirection;
+    sortDirection?: SortDirection;
     filters: F[];
     render: (item: T) => React.ReactElement<any>;
     renderHeader?: () => React.ReactElement<any>;
index 4ce80d31e9d0f0360e6dd7051b113f9dbfe4d40c..a921b471383dbc399521b9298ee7f80bd3cb8a00 100644 (file)
@@ -28,13 +28,13 @@ import { collectionFilesItemActionSet } from './views-components/context-menu/ac
 import { collectionActionSet } from './views-components/context-menu/action-sets/collection-action-set';
 import { collectionResourceActionSet } from './views-components/context-menu/action-sets/collection-resource-action-set';
 import { processActionSet } from './views-components/context-menu/action-sets/process-action-set';
-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';
+import { addRouteChangeHandlers } from './routes/route-change-handlers';
 
 const getBuildNumber = () => "BN-" + (process.env.REACT_APP_BUILD_NUMBER || "dev");
 const getGitCommit = () => "GIT-" + (process.env.REACT_APP_GIT_COMMIT || "latest").substr(0, 7);
diff --git a/src/routes/route-change-handlers.ts b/src/routes/route-change-handlers.ts
new file mode 100644 (file)
index 0000000..b29e5d1
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { History, Location } from 'history';
+import { RootStore } from '~/store/store';
+import {  matchProcessRoute, matchProcessLogRoute, matchProjectRoute, matchCollectionRoute, matchFavoritesRoute, matchTrashRoute } from './routes';
+import { loadProject, loadCollection, loadFavorites, loadTrash, loadProcess, loadProcessLog } from '~/store/workbench/workbench-actions';
+
+export const addRouteChangeHandlers = (history: History, store: RootStore) => {
+    const handler = handleLocationChange(store);
+    handler(history.location);
+    history.listen(handler);
+};
+
+const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
+    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));
+    }
+};
index 05a8ab099ce1db395fb42f67561f330f3adae289..f108e0b8be423592cb50578a8667e468c3251e55 100644 (file)
@@ -2,14 +2,10 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { History, Location } from 'history';
-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 { getCollectionUrl } from '~/models/collection';
-import { loadProject, loadFavorites, loadCollection, loadTrash, loadProcessLog } from '~/store/workbench/workbench-actions';
-import { loadProcess } from '~/store/processes/processes-actions';
 
 export const Routes = {
     ROOT: '/',
@@ -38,12 +34,6 @@ export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
 
 export const getProcessLogUrl = (uuid: string) => `/process-logs/${uuid}`;
 
-export const addRouteChangeHandlers = (history: History, store: RootStore) => {
-    const handler = handleLocationChange(store);
-    handler(history.location);
-    history.listen(handler);
-};
-
 export interface ResourceRouteParams {
     id: string;
 }
@@ -68,26 +58,3 @@ export const matchProcessRoute = (route: string) =>
 
 export const matchProcessLogRoute = (route: string) =>
     matchPath<ResourceRouteParams>(route, { path: Routes.PROCESS_LOGS });
-
-const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
-    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));
-    }
-};
index 254a8d3e16e93aa75d62657d4eecbde75dd587de..cc7bb1dd2d2d6f9237e448dfe0c1fbca4692a6f3 100644 (file)
@@ -9,6 +9,7 @@ import { getResource } from '~/store/resources/resources';
 import { TreePicker } from '../tree-picker/tree-picker';
 import { getSidePanelTreeBranch } from '../side-panel-tree/side-panel-tree-actions';
 import { propertiesActions } from '../properties/properties-actions';
+import { getProcess } from '~/store/processes/process';
 
 export const BREADCRUMBS = 'breadcrumbs';
 
@@ -44,3 +45,11 @@ export const setCollectionBreadcrumbs = (collectionUuid: string) =>
             dispatch<any>(setProjectBreadcrumbs(collection.ownerUuid));
         }
     };
+export const setProcessBreadcrumbs = (processUuid: string) =>
+    (dispatch: Dispatch, getState: () => RootState) => {
+        const { resources } = getState();
+        const process = getProcess(processUuid)(resources);
+        if (process) {
+            dispatch<any>(setProjectBreadcrumbs(process.containerRequest.ownerUuid));
+        }
+    };
index 2b0e6f8f8bd2aad4192397459c79927862264166..bb404b88963b9fbd358db6cdba1aa82a6e7bbf20 100644 (file)
@@ -11,7 +11,8 @@ import { getResource } from '../resources/resources';
 import { ProjectResource } from '~/models/project';
 import { UserResource } from '~/models/user';
 import { isSidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
-import { extractUuidKind, ResourceKind, TrashableResource } from '~/models/resource';
+import { extractUuidKind, ResourceKind } from '~/models/resource';
+import { matchProcessRoute } from '~/routes/routes';
 
 export const contextMenuActions = unionize({
     OPEN_CONTEXT_MENU: ofType<{ position: ContextMenuPosition, resource: ContextMenuResource }>(),
@@ -87,13 +88,10 @@ 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 match = matchProcessRoute(pathname); 
+        const uuid = match ? match.params.id : '';
         const resource = {
-            uuid: '',
+            uuid,
             ownerUuid: '',
             kind: ResourceKind.PROCESS,
             name: '',
index f808b97e8835882a682694799a0b52cdc63155f9..c385309f71f28d3295e23b718089fab3e334b7f2 100644 (file)
@@ -18,17 +18,18 @@ import { GroupContentsResource, GroupContentsResourcePrefix } from "~/services/g
 import { resourcesActions } from "~/store/resources/resources-actions";
 import { snackbarActions } from '~/store/snackbar/snackbar-actions';
 import { getDataExplorer } from "~/store/data-explorer/data-explorer-reducer";
+import { loadMissingProcessesInformation } from "~/store/project-panel/project-panel-middleware-service";
 
 export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
         super(id);
     }
 
-    requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
+    async requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
         const dataExplorer = getDataExplorer(api.getState().dataExplorer, this.getId());
         if (!dataExplorer) {
             api.dispatch(favoritesPanelDataExplorerIsNotSet());
-         } else {
+        } else {
 
             const columns = dataExplorer.columns as DataColumns<string, FavoritePanelFilter>;
             const sortColumn = dataExplorer.columns.find(c => c.sortDirection !== SortDirection.NONE);
@@ -48,36 +49,35 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic
                     .addOrder(direction, "name", GroupContentsResourcePrefix.PROCESS)
                     .addOrder(direction, "name", GroupContentsResourcePrefix.PROJECT);
             }
-
-            this.services.favoriteService
-                .list(this.services.authService.getUuid()!, {
-                    limit: dataExplorer.rowsPerPage,
-                    offset: dataExplorer.page * dataExplorer.rowsPerPage,
-                    linkOrder: linkOrder.getOrder(),
-                    contentOrder: contentOrder.getOrder(),
-                    filters: new FilterBuilder()
-                        .addIsA("headUuid", typeFilters.map(filter => filter.type))
-                        .addILike("name", dataExplorer.searchValue)
-                        .getFilters()
-                })
-                .then(response => {
-                    api.dispatch(resourcesActions.SET_RESOURCES(response.items));
-                    api.dispatch(favoritePanelActions.SET_ITEMS({
-                        items: response.items.map(resource => resource.uuid),
-                        itemsAvailable: response.itemsAvailable,
-                        page: Math.floor(response.offset / response.limit),
-                        rowsPerPage: response.limit
-                    }));
-                    api.dispatch<any>(updateFavorites(response.items.map(item => item.uuid)));
-                })
-                .catch(() => {
-                    api.dispatch(favoritePanelActions.SET_ITEMS({
-                        items: [],
-                        itemsAvailable: 0,
-                        page: 0,
-                        rowsPerPage: dataExplorer.rowsPerPage
-                    }));
-                });
+            try {
+                const response = await this.services.favoriteService
+                    .list(this.services.authService.getUuid()!, {
+                        limit: dataExplorer.rowsPerPage,
+                        offset: dataExplorer.page * dataExplorer.rowsPerPage,
+                        linkOrder: linkOrder.getOrder(),
+                        contentOrder: contentOrder.getOrder(),
+                        filters: new FilterBuilder()
+                            .addIsA("headUuid", typeFilters.map(filter => filter.type))
+                            .addILike("name", dataExplorer.searchValue)
+                            .getFilters()
+                    });
+                api.dispatch(resourcesActions.SET_RESOURCES(response.items));
+                await api.dispatch<any>(loadMissingProcessesInformation(response.items));
+                api.dispatch(favoritePanelActions.SET_ITEMS({
+                    items: response.items.map(resource => resource.uuid),
+                    itemsAvailable: response.itemsAvailable,
+                    page: Math.floor(response.offset / response.limit),
+                    rowsPerPage: response.limit
+                }));
+                api.dispatch<any>(updateFavorites(response.items.map(item => item.uuid)));
+            } catch (e) {
+                api.dispatch(favoritePanelActions.SET_ITEMS({
+                    items: [],
+                    itemsAvailable: 0,
+                    page: 0,
+                    rowsPerPage: dataExplorer.rowsPerPage
+                }));
+            }
         }
     }
 }
index 467fc8a92ef83a7c7dd3358ee3f9d860ff3e56fa..c9e62f943455a2ebaae9b8d8b45c16ff8084a62f 100644 (file)
@@ -2,13 +2,12 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { ContainerRequestResource } from '../../models/container-request';
-import { ContainerResource } from '../../models/container';
+import { ContainerRequestResource, ContainerRequestState } from '../../models/container-request';
+import { ContainerResource, ContainerState } from '../../models/container';
 import { ResourcesState, getResource } from '~/store/resources/resources';
 import { filterResources } from '../resources/resources';
-import { ResourceKind, Resource } from '~/models/resource';
+import { ResourceKind, Resource, extractUuidKind } from '~/models/resource';
 import { getTimeDiff } from '~/common/formatters';
-import { SubprocessesStatus } from '~/views/process-panel/process-subprocesses-card';
 import { ArvadosTheme } from '~/common/custom-theme';
 
 export interface Process {
@@ -16,16 +15,29 @@ export interface Process {
     container?: ContainerResource;
 }
 
+export enum ProcessStatus {
+    CANCELLED = 'Cancelled',
+    COMPLETED = 'Completed',
+    DRAFT = 'Draft',
+    FAILED = 'Failed',
+    LOCKED = 'Locked',
+    QUEUED = 'Queued',
+    RUNNING = 'Running',
+    UNKNOWN = 'Unknown',
+}
+
 export const getProcess = (uuid: string) => (resources: ResourcesState): Process | undefined => {
-    const containerRequest = getResource<ContainerRequestResource>(uuid)(resources);
-    if (containerRequest) {
-        if (containerRequest.containerUuid) {
-            const container = getResource<ContainerResource>(containerRequest.containerUuid)(resources);
-            if (container) {
-                return { containerRequest, container };
+    if (extractUuidKind(uuid) === ResourceKind.CONTAINER_REQUEST) {
+        const containerRequest = getResource<ContainerRequestResource>(uuid)(resources);
+        if (containerRequest) {
+            if (containerRequest.containerUuid) {
+                const container = getResource<ContainerResource>(containerRequest.containerUuid)(resources);
+                if (container) {
+                    return { containerRequest, container };
+                }
             }
+            return { containerRequest };
         }
-        return { containerRequest };
     }
     return;
 };
@@ -51,27 +63,47 @@ export const getProcessRuntime = ({ container }: Process) =>
 
 export const getProcessStatusColor = (status: string, { customs }: ArvadosTheme) => {
     switch (status) {
-        case SubprocessesStatus.COMPLETED:
+        case ProcessStatus.RUNNING:
+            return customs.colors.blue500;
+        case ProcessStatus.COMPLETED:
             return customs.colors.green700;
-        case SubprocessesStatus.CANCELED:
-            return customs.colors.red900;
-        case SubprocessesStatus.QUEUED:
-            return customs.colors.grey500;
-        case SubprocessesStatus.FAILED:
+        case ProcessStatus.CANCELLED:
+        case ProcessStatus.FAILED:
             return customs.colors.red900;
-        case SubprocessesStatus.ACTIVE:
-            return customs.colors.blue500;
         default:
             return customs.colors.grey500;
     }
 };
 
-export const getProcessStatus = (process: Process) =>
-    process.container
-        ? process.container.state
-        : process.containerRequest.state;
+export const getProcessStatus = ({ containerRequest, container }: Process): ProcessStatus => {
+    switch (true) {
+        case containerRequest.state === ContainerRequestState.UNCOMMITTED:
+            return ProcessStatus.DRAFT;
+
+        case containerRequest.priority === 0:
+        case container && container.state === ContainerState.CANCELLED:
+            return ProcessStatus.CANCELLED;
+
+        case container && container.state === ContainerState.QUEUED:
+            return ProcessStatus.QUEUED;
+
+        case container && container.state === ContainerState.LOCKED:
+            return ProcessStatus.LOCKED;
+
+        case container && container.state === ContainerState.RUNNING:
+            return ProcessStatus.RUNNING;
+
+        case container && container.state === ContainerState.COMPLETE && container.exitCode === 0:
+            return ProcessStatus.COMPLETED;
+
+        case container && container.state === ContainerState.COMPLETE && container.exitCode !== 0:
+            return ProcessStatus.FAILED;
+
+        default:
+            return ProcessStatus.UNKNOWN;
+    }
+};
 
 const isSubprocess = (containerUuid: string) => (resource: Resource) =>
     resource.kind === ResourceKind.CONTAINER_REQUEST
     && (resource as ContainerRequestResource).requestingContainerUuid === containerUuid;
-
index aade4172f99201cc10205109bd8740c37d9f72ee..4b4ec2697989831e734f963eb8c872b144b1ebee 100644 (file)
@@ -20,6 +20,8 @@ import { getProperty } from "~/store/properties/properties";
 import { snackbarActions } from '../snackbar/snackbar-actions';
 import { DataExplorer, getDataExplorer } from '../data-explorer/data-explorer-reducer';
 import { ListResults } from '~/services/common-service/common-resource-service';
+import { loadContainers } from '../processes/processes-actions';
+import { ResourceKind } from '~/models/resource';
 
 export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
@@ -39,6 +41,7 @@ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService
                 const response = await this.services.groupsService.contents(projectUuid, getParams(dataExplorer));
                 api.dispatch<any>(updateFavorites(response.items.map(item => item.uuid)));
                 api.dispatch(updateResources(response.items));
+                await api.dispatch<any>(loadMissingProcessesInformation(response.items));
                 api.dispatch(setItems(response));
             } catch (e) {
                 api.dispatch(couldNotFetchProjectContents());
@@ -47,6 +50,22 @@ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService
     }
 }
 
+export const loadMissingProcessesInformation = (resources: GroupContentsResource[]) =>
+    async (dispatch: Dispatch) => {
+        const containerUuids = resources.reduce((uuids, resource) => {
+            return resource.kind === ResourceKind.CONTAINER_REQUEST
+                ? resource.containerUuid
+                    ? [...uuids, resource.containerUuid]
+                    : uuids
+                : uuids;
+        }, []);
+        if (containerUuids.length > 0) {
+            await dispatch<any>(loadContainers(
+                new FilterBuilder().addIn('uuid', containerUuids).getFilters()
+            ));
+        }
+    };
+
 const setItems = (listResults: ListResults<GroupContentsResource>) =>
     projectPanelActions.SET_ITEMS({
         ...listResultsToDataExplorerItemsMeta(listResults),
@@ -65,7 +84,6 @@ const getFilters = (dataExplorer: DataExplorer) => {
     const statusFilters = getDataExplorerColumnFilters(columns, ProjectPanelColumnNames.STATUS);
     return new FilterBuilder()
         .addIsA("uuid", typeFilters.map(f => f.type))
-        .addIn("state", statusFilters.map(f => f.type), GroupContentsResourcePrefix.PROCESS)
         .addILike("name", dataExplorer.searchValue, GroupContentsResourcePrefix.COLLECTION)
         .addILike("name", dataExplorer.searchValue, GroupContentsResourcePrefix.PROCESS)
         .addILike("name", dataExplorer.searchValue, GroupContentsResourcePrefix.PROJECT)
index 80f50fe153744382832c81aa34d63f8976ea2869..effac1d14f4c77048278aac70bbc7c7cd50c1612 100644 (file)
@@ -15,7 +15,7 @@ import { favoritePanelActions } from '~/store/favorite-panel/favorite-panel-acti
 import { projectPanelColumns } from '~/views/project-panel/project-panel';
 import { favoritePanelColumns } from '~/views/favorite-panel/favorite-panel';
 import { matchRootRoute } from '~/routes/routes';
-import { setCollectionBreadcrumbs, setProjectBreadcrumbs, setSidePanelBreadcrumbs } from '../breadcrumbs/breadcrumbs-actions';
+import { setCollectionBreadcrumbs, setProjectBreadcrumbs, setSidePanelBreadcrumbs, setProcessBreadcrumbs } from '../breadcrumbs/breadcrumbs-actions';
 import { navigateToProject } from '../navigation/navigation-action';
 import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
 import { ServiceRepository } from '~/services/services';
@@ -29,7 +29,6 @@ import * as collectionCopyActions from '~/store/collections/collection-copy-acti
 import * as collectionUpdateActions from '~/store/collections/collection-update-actions';
 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';
@@ -186,17 +185,17 @@ export const moveCollection = (data: MoveToFormDialogData) =>
 
 export const loadProcess = (uuid: string) =>
     async (dispatch: Dispatch, getState: () => RootState) => {
-        await dispatch<any>(processesActions.loadProcess(uuid));
-        const process = getProcess(uuid)(getState().resources);
-        if (process) {
-            await dispatch<any>(activateSidePanelTreeItem(process.containerRequest.ownerUuid));
-            dispatch<any>(setCollectionBreadcrumbs(process.containerRequest.ownerUuid));
-            dispatch(loadDetailsPanel(uuid));
-        }
+        const process = await dispatch<any>(processesActions.loadProcess(uuid));
+        await dispatch<any>(activateSidePanelTreeItem(process.containerRequest.ownerUuid));
+        dispatch<any>(setProcessBreadcrumbs(uuid));
+        dispatch(loadDetailsPanel(uuid));
     };
 
 export const loadProcessLog = (uuid: string) =>
     async (dispatch: Dispatch) => {
+        const process = await dispatch<any>(processesActions.loadProcess(uuid));
+        await dispatch<any>(activateSidePanelTreeItem(process.containerRequest.ownerUuid));
+        dispatch<any>(setProcessBreadcrumbs(uuid));
         dispatch<any>(initProcessLogsPanel(uuid));
     };
 
index c96813df95bb25f8b4f773804ed6eda5df7255b2..72644f93af2e9cea7c5a93e965cff53793f8f026 100644 (file)
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { Grid, Typography } from '@material-ui/core';
+import { Grid, Typography, withStyles } from '@material-ui/core';
 import { FavoriteStar } from '../favorite-star/favorite-star';
 import { ResourceKind, TrashableResource } from '~/models/resource';
 import { ProjectIcon, CollectionIcon, ProcessIcon, DefaultIcon } from '~/components/icon/icon';
@@ -13,8 +13,9 @@ import { connect } from 'react-redux';
 import { RootState } from '~/store/store';
 import { getResource } from '~/store/resources/resources';
 import { GroupContentsResource } from '~/services/groups-service/groups-service';
-import { ProcessResource } from '~/models/process';
-
+import { getProcess, Process, getProcessStatus, getProcessStatusColor } from '~/store/processes/process';
+import { ArvadosTheme } from '~/common/custom-theme';
+import { compose } from 'redux';
 
 export const renderName = (item: { name: string; uuid: string, kind: string }) =>
     <Grid container alignItems="center" wrap="nowrap" spacing={16}>
@@ -107,13 +108,17 @@ export const ResourceType = connect(
         return { type: resource ? resource.kind : '' };
     })((props: { type: string }) => renderType(props.type));
 
-export const renderStatus = (item: { status?: string }) =>
-    <Typography noWrap align="center" >
-        {item.status || "-"}
-    </Typography>;
-
-export const ProcessStatus = connect(
-    (state: RootState, props: { uuid: string }) => {
-        const resource = getResource<ProcessResource>(props.uuid)(state.resources);
-        return { status: resource ? resource.state : '-' };
-    })((props: { status: string }) => renderType(props.status));
+export const ProcessStatus = compose(
+    connect((state: RootState, props: { uuid: string }) => {
+        return { process: getProcess(props.uuid)(state.resources) };
+    }),
+    withStyles({}, { withTheme: true }))
+    ((props: { process?: Process, theme: ArvadosTheme }) => {
+        const status = props.process ? getProcessStatus(props.process) : "-";
+        return <Typography
+            noWrap
+            align="center"
+            style={{ color: getProcessStatusColor(status, props.theme) }} >
+            {status}
+        </Typography>;
+    });
index 2cb30198e7242c54fca8020bdf5579dc57535a66..803d8002a365105c2691648e2a5f000cbd3be254 100644 (file)
@@ -68,24 +68,7 @@ export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
         name: "Status",
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
-        filters: [
-            {
-                name: ContainerRequestState.COMMITTED,
-                selected: true,
-                type: ContainerRequestState.COMMITTED
-            },
-            {
-                name: ContainerRequestState.FINAL,
-                selected: true,
-                type: ContainerRequestState.FINAL
-            },
-            {
-                name: ContainerRequestState.UNCOMMITTED,
-                selected: true,
-                type: ContainerRequestState.UNCOMMITTED
-            }
-        ],
+        filters: [],
         render: uuid => <ProcessStatus uuid={uuid} />,
         width: "75px"
     },
@@ -93,7 +76,6 @@ export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
         name: FavoritePanelColumnNames.TYPE,
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
         filters: [
             {
                 name: resourceLabel(ResourceKind.COLLECTION),
@@ -118,7 +100,6 @@ export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
         name: FavoritePanelColumnNames.OWNER,
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
         filters: [],
         render: uuid => <ResourceOwner uuid={uuid} />,
         width: "200px"
@@ -127,7 +108,6 @@ export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
         name: FavoritePanelColumnNames.FILE_SIZE,
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
         filters: [],
         render: uuid => <ResourceFileSize uuid={uuid} />,
         width: "50px"
index 1cb72a963b0ff709bff33203ad21859eda374c01..b75b37aab5e7fa99ac8c4bb2d738abb55d764b29 100644 (file)
@@ -72,24 +72,7 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         name: "Status",
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
-        filters: [
-            {
-                name: ContainerRequestState.COMMITTED,
-                selected: true,
-                type: ContainerRequestState.COMMITTED
-            },
-            {
-                name: ContainerRequestState.FINAL,
-                selected: true,
-                type: ContainerRequestState.FINAL
-            },
-            {
-                name: ContainerRequestState.UNCOMMITTED,
-                selected: true,
-                type: ContainerRequestState.UNCOMMITTED
-            }
-        ],
+        filters: [],
         render: uuid => <ProcessStatus uuid={uuid} />,
         width: "75px"
     },
@@ -97,7 +80,6 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         name: ProjectPanelColumnNames.TYPE,
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
         filters: [
             {
                 name: resourceLabel(ResourceKind.COLLECTION),
@@ -122,7 +104,6 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         name: ProjectPanelColumnNames.OWNER,
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
         filters: [],
         render: uuid => <ResourceOwner uuid={uuid} />,
         width: "200px"
@@ -131,7 +112,6 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         name: ProjectPanelColumnNames.FILE_SIZE,
         selected: true,
         configurable: true,
-        sortDirection: SortDirection.NONE,
         filters: [],
         render: uuid => <ResourceFileSize uuid={uuid} />,
         width: "50px"