19462: Updating color scheme
[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
77 export const getProcessStatusStyles = (status: string, theme: ArvadosTheme): React.CSSProperties => {
78     let color = theme.customs.colors.grey500;
79     let running = false;
80     switch (status) {
81         case ProcessStatus.RUNNING:
82             color = theme.customs.colors.green800;
83             running = true;
84             break;
85         case ProcessStatus.COMPLETED:
86             color = theme.customs.colors.green800;
87             break;
88         case ProcessStatus.WARNING:
89             color = theme.customs.colors.green800;
90             running = true;
91             break;
92         case ProcessStatus.FAILING:
93             color = theme.customs.colors.red900;
94             running = true;
95             break;
96         case ProcessStatus.CANCELLED:
97         case ProcessStatus.FAILED:
98             color = theme.customs.colors.red900;
99             break;
100         default:
101             color = theme.customs.colors.grey600;
102             break;
103     }
104
105     // Using color and running we build the text, border, and background style properties
106     return {
107         // Set background color when not running, otherwise use white
108         backgroundColor: running ? theme.palette.common.white : color,
109         // Set text color to status color when running, else use white text for solid button
110         color: running ? color : theme.palette.common.white,
111         // Set border color when running, else omit the style entirely
112         ...(running ? {border: `1px solid ${color}`} : {}),
113     };
114 };
115
116 export const getProcessStatus = ({ containerRequest, container }: Process): ProcessStatus => {
117     switch (true) {
118         case containerRequest.state === ContainerRequestState.FINAL &&
119             container?.state !== ContainerState.COMPLETE:
120             // Request was finalized before its container started (or the
121             // container was cancelled)
122             return ProcessStatus.CANCELLED;
123
124         case containerRequest.state === ContainerRequestState.UNCOMMITTED:
125             return ProcessStatus.DRAFT;
126
127         case container?.state === ContainerState.COMPLETE:
128             if (container?.exitCode === 0) {
129                 return ProcessStatus.COMPLETED;
130             }
131             return ProcessStatus.FAILED;
132
133         case container?.state === ContainerState.CANCELLED:
134             return ProcessStatus.CANCELLED;
135
136         case container?.state === ContainerState.QUEUED ||
137             container?.state === ContainerState.LOCKED:
138             if (containerRequest.priority === 0) {
139                 return ProcessStatus.ONHOLD;
140             }
141             return ProcessStatus.QUEUED;
142
143         case container?.state === ContainerState.RUNNING:
144             if (!!container?.runtimeStatus.error) {
145                 return ProcessStatus.FAILING;
146             }
147             if (!!container?.runtimeStatus.warning) {
148                 return ProcessStatus.WARNING;
149             }
150             return ProcessStatus.RUNNING;
151
152         default:
153             return ProcessStatus.UNKNOWN;
154     }
155 };
156
157 const isSubprocess = (containerUuid: string) => (resource: Resource) =>
158     resource.kind === ResourceKind.CONTAINER_REQUEST
159     && (resource as ContainerRequestResource).requestingContainerUuid === containerUuid;