1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { Dispatch } from 'redux';
6 import { RootState } from 'store/store';
7 import { ServiceRepository } from 'services/services';
8 import { bindDataExplorerActions } from 'store/data-explorer/data-explorer-action';
9 import { FilterBuilder } from 'services/api/filter-builder';
10 import { ProgressBarData } from 'components/subprocess-progress-bar/subprocess-progress-bar';
11 import { ProcessStatusFilter, buildProcessStatusFilters } from 'store/resource-type-filters/resource-type-filters';
12 export const SUBPROCESS_PANEL_ID = "subprocessPanel";
13 export const SUBPROCESS_ATTRIBUTES_DIALOG = 'subprocessAttributesDialog';
14 export const subprocessPanelActions = bindDataExplorerActions(SUBPROCESS_PANEL_ID);
16 export const loadSubprocessPanel = () =>
17 (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
18 dispatch(subprocessPanelActions.REQUEST_ITEMS());
22 * Holds a ProgressBarData status type and process count result
24 type ProcessStatusBarCount = {
25 status: keyof ProgressBarData;
30 * Associates each of the limited progress bar segment types with an array of
31 * ProcessStatusFilterTypes to be combined when displayed
33 type ProcessStatusMap = Record<keyof ProgressBarData, ProcessStatusFilter[]>;
35 const statusMap: ProcessStatusMap = {
36 [ProcessStatusFilter.COMPLETED]: [ProcessStatusFilter.COMPLETED],
37 [ProcessStatusFilter.RUNNING]: [ProcessStatusFilter.RUNNING],
38 [ProcessStatusFilter.FAILED]: [ProcessStatusFilter.FAILED, ProcessStatusFilter.CANCELLED],
39 [ProcessStatusFilter.QUEUED]: [ProcessStatusFilter.QUEUED, ProcessStatusFilter.ONHOLD],
43 * Utility type to hold a pair of associated progress bar status and process status
45 type ProgressBarStatusPair = {
46 barStatus: keyof ProcessStatusMap;
47 processStatus: ProcessStatusFilter;
50 export const fetchSubprocessProgress = (requestingContainerUuid: string) =>
51 async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<ProgressBarData | undefined> => {
53 const requestContainerStatusCount = async (fb: FilterBuilder) => {
54 return await services.containerRequestService.list({
57 filters: fb.getFilters(),
61 if (requestingContainerUuid) {
63 const baseFilter = new FilterBuilder().addEqual('requesting_container_uuid', requestingContainerUuid).getFilters();
65 // Create return object
66 let result: ProgressBarData = {
67 [ProcessStatusFilter.COMPLETED]: 0,
68 [ProcessStatusFilter.RUNNING]: 0,
69 [ProcessStatusFilter.FAILED]: 0,
70 [ProcessStatusFilter.QUEUED]: 0,
73 // Create array of promises that returns the status associated with the item count
74 // Helps to make the requests simultaneously while preserving the association with the status key as a typed key
75 const promises = (Object.keys(statusMap) as Array<keyof ProcessStatusMap>)
76 // Split statusMap into pairs of progress bar status and process status
77 .reduce((acc, curr) => [...acc, ...statusMap[curr].map(processStatus => ({barStatus: curr, processStatus}))], [] as ProgressBarStatusPair[])
78 .map(async (statusPair: ProgressBarStatusPair): Promise<ProcessStatusBarCount> => {
79 // For each status pair, request count and return bar status and count
80 const { barStatus, processStatus } = statusPair;
81 const filter = buildProcessStatusFilters(new FilterBuilder(baseFilter), processStatus);
82 const count = (await requestContainerStatusCount(filter)).itemsAvailable;
83 return {status: barStatus, count};
86 // Simultaneously requests each status count and apply them to the return object
87 (await Promise.all(promises)).forEach((singleResult) => {
88 result[singleResult.status] += singleResult.count;