[ARVADOS-WORKBENCH2] created: 1.2.0-266-g5c6e7a1
Git user
git at public.curoverse.com
Tue Sep 4 05:55:22 EDT 2018
at 5c6e7a1fcb3e951c09e4a794f92a80a35f4db2ee (commit)
commit 5c6e7a1fcb3e951c09e4a794f92a80a35f4db2ee
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date: Tue Sep 4 11:54:48 2018 +0200
Update process statuses, update process status rendering in tables, disable process status table filters
Feature #13776
Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
diff --git a/src/components/data-table/data-column.ts b/src/components/data-table/data-column.ts
index 90e87a8..8dbdf0c 100644
--- a/src/components/data-table/data-column.ts
+++ b/src/components/data-table/data-column.ts
@@ -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>;
diff --git a/src/store/favorite-panel/favorite-panel-middleware-service.ts b/src/store/favorite-panel/favorite-panel-middleware-service.ts
index f808b97..c385309 100644
--- a/src/store/favorite-panel/favorite-panel-middleware-service.ts
+++ b/src/store/favorite-panel/favorite-panel-middleware-service.ts
@@ -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
+ }));
+ }
}
}
}
diff --git a/src/store/processes/process.ts b/src/store/processes/process.ts
index 467fc8a..c9e62f9 100644
--- a/src/store/processes/process.ts
+++ b/src/store/processes/process.ts
@@ -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;
-
diff --git a/src/store/project-panel/project-panel-middleware-service.ts b/src/store/project-panel/project-panel-middleware-service.ts
index aade417..4b4ec26 100644
--- a/src/store/project-panel/project-panel-middleware-service.ts
+++ b/src/store/project-panel/project-panel-middleware-service.ts
@@ -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)
diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index c96813d..72644f9 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -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>;
+ });
diff --git a/src/views/favorite-panel/favorite-panel.tsx b/src/views/favorite-panel/favorite-panel.tsx
index 2cb3019..803d800 100644
--- a/src/views/favorite-panel/favorite-panel.tsx
+++ b/src/views/favorite-panel/favorite-panel.tsx
@@ -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"
diff --git a/src/views/project-panel/project-panel.tsx b/src/views/project-panel/project-panel.tsx
index 1cb72a9..b75b37a 100644
--- a/src/views/project-panel/project-panel.tsx
+++ b/src/views/project-panel/project-panel.tsx
@@ -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"
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list