20609: Change subprocess progress bar to combine relevant process statuses
[arvados-workbench2.git] / src / store / subprocess-panel / subprocess-panel-actions.ts
index 68ed453f1a587e5a0c75127fa2e69b18f08f3700..a67dd1f436441fa1cbf9d7ec4abc46c06910adc1 100644 (file)
@@ -18,11 +18,35 @@ export const loadSubprocessPanel = () =>
         dispatch(subprocessPanelActions.REQUEST_ITEMS());
     };
 
-type ProcessStatusCount = {
+/**
+ * Holds a ProgressBarData status type and process count result
+ */
+type ProcessStatusBarCount = {
     status: keyof ProgressBarData;
     count: number;
 };
 
+/**
+ * Associates each of the limited progress bar segment types with an array of
+ * ProcessStatusFilterTypes to be combined when displayed
+ */
+type ProcessStatusMap = Record<keyof ProgressBarData, ProcessStatusFilter[]>;
+
+const statusMap: ProcessStatusMap = {
+        [ProcessStatusFilter.COMPLETED]: [ProcessStatusFilter.COMPLETED],
+        [ProcessStatusFilter.RUNNING]: [ProcessStatusFilter.RUNNING],
+        [ProcessStatusFilter.FAILED]: [ProcessStatusFilter.FAILED, ProcessStatusFilter.CANCELLED],
+        [ProcessStatusFilter.QUEUED]: [ProcessStatusFilter.QUEUED, ProcessStatusFilter.ONHOLD],
+};
+
+/**
+ * Utility type to hold a pair of associated progress bar status and process status
+ */
+type ProgressBarStatusPair = {
+    barStatus: keyof ProcessStatusMap;
+    processStatus: ProcessStatusFilter;
+};
+
 export const fetchSubprocessProgress = (requestingContainerUuid: string) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<ProgressBarData | undefined> => {
 
@@ -48,15 +72,20 @@ export const fetchSubprocessProgress = (requestingContainerUuid: string) =>
 
                 // Create array of promises that returns the status associated with the item count
                 // Helps to make the requests simultaneously while preserving the association with the status key as a typed key
-                const promises = Object.keys(result).map(async (status: keyof ProgressBarData): Promise<ProcessStatusCount> => {
-                    const filter = buildProcessStatusFilters(new FilterBuilder(baseFilter), status);
-                    const count = (await requestContainerStatusCount(filter)).itemsAvailable;
-                    return {status, count};
-                });
+                const promises = (Object.keys(statusMap) as Array<keyof ProcessStatusMap>)
+                    // Split statusMap into pairs of progress bar status and process status
+                    .reduce((acc, curr) => [...acc, ...statusMap[curr].map(processStatus => ({barStatus: curr, processStatus}))], [] as ProgressBarStatusPair[])
+                    .map(async (statusPair: ProgressBarStatusPair): Promise<ProcessStatusBarCount> => {
+                        // For each status pair, request count and return bar status and count
+                        const { barStatus, processStatus } = statusPair;
+                        const filter = buildProcessStatusFilters(new FilterBuilder(baseFilter), processStatus);
+                        const count = (await requestContainerStatusCount(filter)).itemsAvailable;
+                        return {status: barStatus, count};
+                    });
 
                 // Simultaneously requests each status count and apply them to the return object
                 (await Promise.all(promises)).forEach((singleResult) => {
-                    result[singleResult.status] = singleResult.count;
+                    result[singleResult.status] += singleResult.count;
                 });
                 return result;
             } catch (e) {