From da1640eec9320b0a8289a5c093c109271c0a7627 Mon Sep 17 00:00:00 2001 From: Christina Jenks <christina.jenks@ess.eu> Date: Wed, 20 Sep 2023 12:18:09 +0000 Subject: [PATCH] CE-2068: replace useOperationsSearch & useOngoingCommand with common api --- src/api/SwaggerApi.js | 43 ------------- src/components/IOC/IOCManage/IOCManage.js | 2 +- .../common/User/UserOperationList.js | 25 +++++--- src/mocks/mockAPI.js | 18 +++++- .../views/IOC/IocDetailsView.stories.js | 12 +++- src/stories/views/Job/JobListView.stories.js | 15 +++++ src/views/IOC/IOCDetailsView.js | 63 ++++++++++++++----- src/views/jobs/JobListView.js | 25 +++++--- 8 files changed, 125 insertions(+), 78 deletions(-) create mode 100644 src/stories/views/Job/JobListView.stories.js diff --git a/src/api/SwaggerApi.js b/src/api/SwaggerApi.js index 7ab60b68..59444ee7 100644 --- a/src/api/SwaggerApi.js +++ b/src/api/SwaggerApi.js @@ -229,49 +229,6 @@ export function unpackOngoingOperations(input) { return output.totalCount > 0 ? output.operationsList[0] : null; } -export function useOngoingCommand(iocId) { - const api = useContext(apiContext); - const method = useCallAndUnpack( - api.apis.Deployments.listOperations, - unpackOngoingOperations - ); - const boundMethod = useCallback( - method.bind(null, { ioc_id: iocId, type: "COMMAND", status: "ONGOING" }), - [iocId] - ); - return useAsync({ - fcn: boundMethod, - call: false, - init: emptyOperationsListResponse - }); -} - -const emptyOperationsListResponse = { - totalCount: 0, - pageNumber: 0, - limit: 0, - operationsList: [] -}; - -export function unpackOperationsList(input) { - const { operations: operationsList, ...rest } = input; - const output = { ...rest, operationsList }; - return output; -} - -export function useOperationsSearch() { - const api = useContext(apiContext); - const method = useCallAndUnpack( - (params) => api.apis.Deployments.listOperations(params), - unpackOperationsList - ); - return useAsync({ - fcn: method, - call: false, - init: emptyOperationsListResponse - }); -} - export function unpackOperation(operation) { const d = { ...operation }; return d; diff --git a/src/components/IOC/IOCManage/IOCManage.js b/src/components/IOC/IOCManage/IOCManage.js index 9378005e..e1378e4d 100644 --- a/src/components/IOC/IOCManage/IOCManage.js +++ b/src/components/IOC/IOCManage/IOCManage.js @@ -215,7 +215,7 @@ export function IOCManage({ } > <JobTable - jobs={operations.operationsList} + jobs={operations} pagination={pagination} onPage={onPage} loading={operationsLoading} diff --git a/src/components/common/User/UserOperationList.js b/src/components/common/User/UserOperationList.js index c90c1957..75372ca2 100644 --- a/src/components/common/User/UserOperationList.js +++ b/src/components/common/User/UserOperationList.js @@ -1,13 +1,24 @@ -import React from "react"; +import React, { useContext } from "react"; import { Card, CardHeader } from "@mui/material"; import { initRequestParams } from "../Helper"; import { useEffect } from "react"; -import { useOperationsSearch } from "../../../api/SwaggerApi"; import { usePagination } from "../../../hooks/pagination"; import { JobTable } from "../../Job"; +import { apiContext } from "../../../api/DeployApi"; +import { useAPIMethod } from "@ess-ics/ce-ui-common"; export function UserOperationList({ userName }) { - const [operations, getOperations, , loading] = useOperationsSearch(); + const client = useContext(apiContext); + + const { + value: operations, + wrapper: getOperations, + loading, + dataReady + } = useAPIMethod({ + fcn: client.apis.Deployments.listOperations, + call: false + }); const rowsPerPage = [20, 50]; const { pagination, setPagination } = usePagination({ @@ -18,8 +29,8 @@ export function UserOperationList({ userName }) { // update pagination whenever search result total pages change useEffect(() => { - setPagination({ totalCount: operations.totalCount ?? 0 }); - }, [setPagination, operations.totalCount]); + setPagination({ totalCount: operations?.totalCount ?? 0 }); + }, [setPagination, operations?.totalCount]); useEffect(() => { let requestParams = initRequestParams(pagination); @@ -44,8 +55,8 @@ export function UserOperationList({ userName }) { }} /> <JobTable - jobs={operations.operationsList} - loading={loading} + jobs={operations?.operations} + loading={loading || !dataReady} pagination={pagination} onPage={onPage} rowType="userPageJobLog" diff --git a/src/mocks/mockAPI.js b/src/mocks/mockAPI.js index 7fa3a2cd..010a2cc1 100644 --- a/src/mocks/mockAPI.js +++ b/src/mocks/mockAPI.js @@ -156,6 +156,15 @@ function listOperations(req) { return { body }; } +function fetchOperation(req) { + const params = getParameters(req, "/deployments/operations/:id"); + const data = require("./fixtures/OperationList.json"); + + const body = data.operations.find((x) => x?.id === Number(params?.id)); + const status = body ? 200 : 404; + return { body, status }; +} + function getCommandList(req) { const body = require("./fixtures/PagedCommandResponse.json"); return { body }; @@ -262,7 +271,8 @@ const mockAPI = { getDeploymentJob, getDeploymentJobLog, getCommandList, - listOperations + listOperations, + fetchOperation }, hosts: { getCSEntryHostWithStatus @@ -350,6 +360,12 @@ export const apiHandlers = [ qRegExp(".*/deployments/[0-9]+"), mockAPI.deployments.getDeployment ), + makeHandler( + "GET", + qRegExp(".*/deployments/operations/[0-9]+"), + mockAPI.deployments.fetchOperation, + auth + ), makeHandler( "GET", qRegExp(".*/deployments/operations/job/[0-9]+"), diff --git a/src/stories/views/IOC/IocDetailsView.stories.js b/src/stories/views/IOC/IocDetailsView.stories.js index ea0221de..1b0a9315 100644 --- a/src/stories/views/IOC/IocDetailsView.stories.js +++ b/src/stories/views/IOC/IocDetailsView.stories.js @@ -6,10 +6,18 @@ export default { title: "Views/IOC/IOCDetailsView" }; -const Template = () => ( +const Template = (args) => ( <AppHarness> - <IOCDetailsContainer id={346} /> + <IOCDetailsContainer + id={346} + {...args} + /> </AppHarness> ); export const Default = () => <Template />; + +export const Deployable = (args) => <Template {...args} />; +Deployable.args = { + id: 2 +}; diff --git a/src/stories/views/Job/JobListView.stories.js b/src/stories/views/Job/JobListView.stories.js new file mode 100644 index 00000000..eb4d7960 --- /dev/null +++ b/src/stories/views/Job/JobListView.stories.js @@ -0,0 +1,15 @@ +import React from "react"; +import { AppHarness } from "../../../mocks/AppHarness"; +import { JobListView } from "../../../views/jobs/JobListView"; + +export default { + title: "Views/Job/JobListView" +}; + +const Template = () => ( + <AppHarness> + <JobListView /> + </AppHarness> +); + +export const Default = () => <Template />; diff --git a/src/views/IOC/IOCDetailsView.js b/src/views/IOC/IOCDetailsView.js index 7cbc136f..f6bc0574 100644 --- a/src/views/IOC/IOCDetailsView.js +++ b/src/views/IOC/IOCDetailsView.js @@ -7,7 +7,6 @@ import React, { useMemo, useState } from "react"; -import { useOngoingCommand, useOperationsSearch } from "../../api/SwaggerApi"; import { IOCLiveStatus } from "../../components/IOC/IOCLiveStatus"; import { IOCManage } from "../../components/IOC/IOCManage"; import { useNavigate } from "react-router-dom"; @@ -17,7 +16,7 @@ import { applicationTitle, initRequestParams } from "../../components/common/Helper"; -import { GlobalAppBarContext } from "@ess-ics/ce-ui-common"; +import { GlobalAppBarContext, useAPIMethod } from "@ess-ics/ce-ui-common"; import { useSafePolling } from "../../hooks/Polling"; import useUrlState from "@ahooksjs/use-url-state"; import { @@ -25,6 +24,7 @@ import { deserialize } from "../../components/common/URLState/URLState"; import { usePagination } from "../../hooks/pagination"; +import { apiContext } from "../../api/DeployApi"; const IOC_POLL_INTERVAL = 10000; export function IOCDetailsView({ ioc, getIOC, loading }) { @@ -39,14 +39,37 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { const [buttonDisabled, setButtonDisabled] = useState(false); const navigate = useNavigate(); - const [operations, getOperations /* reset*/, , operationsLoading] = - useOperationsSearch(); - const [ - ongoingCommand, - getOngoingCommand, - , - /* reset*/ ongoingCommandLoading - ] = useOngoingCommand(ioc.id); + + const client = useContext(apiContext); + const { + value: operations, + wrapper: getOperations, + loading: operationsLoading, + dataReady: operationsDataReady + } = useAPIMethod({ + fcn: client.apis.Deployments.listOperations, + call: false + }); + + const ongoingCommandParams = useMemo( + () => ({ + ioc_id: ioc.id, + type: "COMMAND", + status: "ONGOING" + }), + [ioc] + ); + + const { + value: ongoingCommand, + wrapper: getOngoingCommand, + loading: ongoingCommandLoading, + dataReady: ongoingCommandDataReady + } = useAPIMethod({ + fcn: client.apis.Deployments.listOperations, + params: ongoingCommandParams, + call: false + }); const jobUrlPagination = useMemo(() => { return { @@ -76,8 +99,8 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { // update pagination whenever search result total pages change useEffect(() => { - setJobPagination({ totalCount: operations.totalCount ?? 0 }); - }, [setJobPagination, operations.totalCount]); + setJobPagination({ totalCount: operations?.totalCount ?? 0 }); + }, [setJobPagination, operations?.totalCount]); // whenever url state changes, update pagination useEffect(() => { @@ -96,7 +119,11 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { }; useSafePolling(getIOC, loading, IOC_POLL_INTERVAL); - useSafePolling(getOngoingCommand, ongoingCommandLoading, IOC_POLL_INTERVAL); + useSafePolling( + getOngoingCommand, + ongoingCommandLoading || !ongoingCommandDataReady, + IOC_POLL_INTERVAL + ); useEffect(() => { setButtonDisabled(Boolean(ioc?.operationInProgress)); @@ -234,9 +261,13 @@ export function IOCDetailsView({ ioc, getIOC, loading }) { ioc={ioc} getIOC={getIOC} buttonDisabled={buttonDisabled} - currentCommand={ongoingCommand} - operations={operations} - operationsLoading={operationsLoading} + currentCommand={ + ongoingCommand?.operations?.length > 0 + ? ongoingCommand.operations[0] + : null + } + operations={operations?.operations} + operationsLoading={operationsLoading || !operationsDataReady} getOperations={getOperations} setButtonDisabled={setButtonDisabledAndUpdate} pagination={jobPagination} diff --git a/src/views/jobs/JobListView.js b/src/views/jobs/JobListView.js index 5fa2a77d..6a43a22e 100644 --- a/src/views/jobs/JobListView.js +++ b/src/views/jobs/JobListView.js @@ -10,8 +10,7 @@ import { } from "@mui/material"; import Tabs from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; -import { useOperationsSearch } from "../../api/SwaggerApi"; -import { userContext, RootPaper } from "@ess-ics/ce-ui-common"; +import { userContext, RootPaper, useAPIMethod } from "@ess-ics/ce-ui-common"; import { initRequestParams } from "../../components/common/Helper"; import { useEffect } from "react"; import { SearchBar } from "../../components/common/SearchBar/SearchBar"; @@ -23,10 +22,20 @@ import { } from "../../components/common/URLState/URLState"; import { usePagination } from "../../hooks/pagination"; import { JobTable } from "../../components/Job"; +import { apiContext } from "../../api/DeployApi"; export function JobListView() { - const [operations, getOperations /* reset*/, , loading] = - useOperationsSearch(); + const client = useContext(apiContext); + + const { + value: operations, + wrapper: getOperations, + loading, + dataReady + } = useAPIMethod({ + fcn: client.apis.Deployments.listOperations, + call: false + }); const [urlState, setUrlState] = useUrlState( { @@ -99,8 +108,8 @@ export function JobListView() { // update pagination whenever search result total pages change useEffect(() => { - setPagination({ totalCount: operations.totalCount ?? 0 }); - }, [setPagination, operations.totalCount]); + setPagination({ totalCount: operations?.totalCount ?? 0 }); + }, [setPagination, operations?.totalCount]); // whenever url state changes, update pagination useEffect(() => { @@ -163,10 +172,10 @@ export function JobListView() { placeholder="Search in IOC name or user" > <JobTable - jobs={operations.operationsList} + jobs={operations?.operations} pagination={pagination} onPage={onPage} - loading={loading} + loading={loading || !dataReady} /> </SearchBar> ); -- GitLab