19462: Updating status colors
[arvados-workbench2.git] / src / store / processes / process.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { ContainerRequestResource, ContainerRequestState } from '../../models/container-request';
6 import { ContainerResource, ContainerState } from '../../models/container';
7 import { ResourcesState, getResource } from 'store/resources/resources';
8 import { filterResources } from '../resources/resources';
9 import { ResourceKind, Resource, extractUuidKind } from 'models/resource';
10 import { getTimeDiff } from 'common/formatters';
11 import { ArvadosTheme } from 'common/custom-theme';
12
13 export interface Process {
14     containerRequest: ContainerRequestResource;
15     container?: ContainerResource;
16 }
17
18 export enum ProcessStatus {
19     CANCELLED = 'Cancelled',
20     COMPLETED = 'Completed',
21     DRAFT = 'Draft',
22     FAILING = 'Failing',
23     FAILED = 'Failed',
24     ONHOLD = 'On hold',
25     QUEUED = 'Queued',
26     RUNNING = 'Running',
27     WARNING = 'Warning',
28     UNKNOWN = 'Unknown',
29 }
30
31 export const getProcess = (uuid: string) => (resources: ResourcesState): Process | undefined => {
32     if (extractUuidKind(uuid) === ResourceKind.CONTAINER_REQUEST) {
33         const containerRequest = getResource<ContainerRequestResource>(uuid)(resources);
34         if (containerRequest) {
35             if (containerRequest.containerUuid) {
36                 const container = getResource<ContainerResource>(containerRequest.containerUuid)(resources);
37                 if (container) {
38                     return { containerRequest, container };
39                 }
40             }
41             return { containerRequest };
42         }
43     }
44     return;
45 };
46
47 export const getSubprocesses = (uuid: string) => (resources: ResourcesState) => {
48     const process = getProcess(uuid)(resources);
49     if (process && process.container) {
50         const containerRequests = filterResources(isSubprocess(process.container.uuid))(resources) as ContainerRequestResource[];
51         return containerRequests.reduce((subprocesses, { uuid }) => {
52             const process = getProcess(uuid)(resources);
53             return process
54                 ? [...subprocesses, process]
55                 : subprocesses;
56         }, []);
57     }
58     return [];
59 };
60
61 export const getProcessRuntime = ({ container }: Process) => {
62     if (container) {
63         if (container.startedAt === null) {
64             return 0;
65         }
66         if (container.finishedAt === null) {
67             // Count it from now
68             return new Date().getTime() - new Date(container.startedAt).getTime();
69         }
70         return getTimeDiff(container.finishedAt, container.startedAt);
71     } else {
72         return 0;
73     }
74 };
75
76 export const getProcessStatusColor = (status: string, { customs }: ArvadosTheme) => {
77     switch (status) {
78         case ProcessStatus.RUNNING:
79             return customs.colors.green800;
80         case ProcessStatus.COMPLETED:
81         case ProcessStatus.WARNING:
82             return customs.colors.green800;
83         case ProcessStatus.FAILING:
84         case ProcessStatus.CANCELLED:
85         case ProcessStatus.FAILED:
86             return customs.colors.red900;
87         default:
88             return customs.colors.grey600;
89     }
90 };
91
92 export const getProcessStatus = ({ containerRequest, container }: Process): ProcessStatus => {
93     switch (true) {
94         case containerRequest.state === ContainerRequestState.FINAL &&
95             container?.state !== ContainerState.COMPLETE:
96             // Request was finalized before its container started (or the
97             // container was cancelled)
98             return ProcessStatus.CANCELLED;
99
100         case containerRequest.state === ContainerRequestState.UNCOMMITTED:
101             return ProcessStatus.DRAFT;
102
103         case container?.state === ContainerState.COMPLETE:
104             if (container?.exitCode === 0) {
105                 return ProcessStatus.COMPLETED;
106             }
107             return ProcessStatus.FAILED;
108
109         case container?.state === ContainerState.CANCELLED:
110             return ProcessStatus.CANCELLED;
111
112         case container?.state === ContainerState.QUEUED ||
113             container?.state === ContainerState.LOCKED:
114             if (containerRequest.priority === 0) {
115                 return ProcessStatus.ONHOLD;
116             }
117             return ProcessStatus.QUEUED;
118
119         case container?.state === ContainerState.RUNNING:
120             if (!!container?.runtimeStatus.error) {
121                 return ProcessStatus.FAILING;
122             }
123             if (!!container?.runtimeStatus.warning) {
124                 return ProcessStatus.WARNING;
125             }
126             return ProcessStatus.RUNNING;
127
128         default:
129             return ProcessStatus.UNKNOWN;
130     }
131 };
132
133 const isSubprocess = (containerUuid: string) => (resource: Resource) =>
134     resource.kind === ResourceKind.CONTAINER_REQUEST
135     && (resource as ContainerRequestResource).requestingContainerUuid === containerUuid;