From dcf2e835b33e926073dad1f636cf92a95493ca0b Mon Sep 17 00:00:00 2001 From: Stephen Smith Date: Tue, 14 Nov 2023 09:07:08 -0500 Subject: [PATCH] 20609: Change subprocess progress bar to combine relevant process statuses eg. Queued segment = Queued + OnHold, Failed segment = Failed + Cancelled Arvados-DCO-1.1-Signed-off-by: Stephen Smith --- .../subprocess-progress-bar.test.tsx | 22 +++++++--- .../subprocess-panel-actions.ts | 43 ++++++++++++++++--- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/components/subprocess-progress-bar/subprocess-progress-bar.test.tsx b/src/components/subprocess-progress-bar/subprocess-progress-bar.test.tsx index 83737178..bd8603f9 100644 --- a/src/components/subprocess-progress-bar/subprocess-progress-bar.test.tsx +++ b/src/components/subprocess-progress-bar/subprocess-progress-bar.test.tsx @@ -73,8 +73,14 @@ describe("", () => { statusResponse = { [ProcessStatusFilter.COMPLETED]: 100, [ProcessStatusFilter.RUNNING]: 200, - [ProcessStatusFilter.FAILED]: 300, - [ProcessStatusFilter.QUEUED]: 400, + + // Combined into failed segment + [ProcessStatusFilter.FAILED]: 200, + [ProcessStatusFilter.CANCELLED]: 100, + + // Combined into queued segment + [ProcessStatusFilter.QUEUED]: 300, + [ProcessStatusFilter.ONHOLD]: 100, }; services.containerRequestService.list = createMockListFunc(process.containerRequest.containerUuid); @@ -88,12 +94,14 @@ describe("", () => { }); await progressBar.update(); - // expects 4 subprocess status list requests + // expects 6 subprocess status list requests const expectedFilters = [ ProcessStatusFilter.COMPLETED, ProcessStatusFilter.RUNNING, ProcessStatusFilter.FAILED, + ProcessStatusFilter.CANCELLED, ProcessStatusFilter.QUEUED, + ProcessStatusFilter.ONHOLD, ].map((state) => buildProcessStatusFilters( new FilterBuilder().addEqual( @@ -128,8 +136,12 @@ describe("", () => { statusResponse = { [ProcessStatusFilter.COMPLETED]: 50, [ProcessStatusFilter.RUNNING]: 55, - [ProcessStatusFilter.FAILED]: 60, - [ProcessStatusFilter.QUEUED]: 335, + + [ProcessStatusFilter.FAILED]: 30, + [ProcessStatusFilter.CANCELLED]: 30, + + [ProcessStatusFilter.QUEUED]: 235, + [ProcessStatusFilter.ONHOLD]: 100, }; services.containerRequestService.list = createMockListFunc(process.containerRequest.containerUuid); diff --git a/src/store/subprocess-panel/subprocess-panel-actions.ts b/src/store/subprocess-panel/subprocess-panel-actions.ts index 68ed453f..a67dd1f4 100644 --- a/src/store/subprocess-panel/subprocess-panel-actions.ts +++ b/src/store/subprocess-panel/subprocess-panel-actions.ts @@ -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; + +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 => { @@ -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 => { - const filter = buildProcessStatusFilters(new FilterBuilder(baseFilter), status); - const count = (await requestContainerStatusCount(filter)).itemsAvailable; - return {status, count}; - }); + const promises = (Object.keys(statusMap) as Array) + // 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 => { + // 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) { -- 2.30.2