From 7ad489ebb40a03664adad2c4d7ee7f7d326097e7 Mon Sep 17 00:00:00 2001 From: Raj Kamal Singh <1133322+rkssisodiya@users.noreply.github.com> Date: Tue, 8 Aug 2023 17:55:09 +0530 Subject: [PATCH] fix: pipeline change history: update config deployment status without having to reload (#3284) * fix: specify rowKey for pipeline ChangeHistory table * fix: pipeline change history: refetch pipelines until latest config deployment is finished * fix: typo: verison -> version * chore: some code clean up * fix: get tests passing * fix: use refetchInterval to specify pipeline data polling strategy --------- Co-authored-by: Palash Gupta --- .../Layouts/ChangeHistory/index.tsx | 7 ++-- .../Layouts/Pipeline/CreatePipelineButton.tsx | 8 ++--- .../PipelinePage/Layouts/Pipeline/index.tsx | 8 ++--- .../ModeAndConfiguration.tsx | 6 ++-- .../PipelinePage/PipelineListsView/index.tsx | 16 ++++----- .../container/PipelinePage/mocks/pipeline.ts | 2 +- .../tests/CreatePipelineButton.test.tsx | 2 +- .../tests/PipelinePageLayout.test.tsx | 2 +- frontend/src/pages/Pipelines/index.tsx | 33 +++++++++++++++---- 9 files changed, 52 insertions(+), 32 deletions(-) diff --git a/frontend/src/container/PipelinePage/Layouts/ChangeHistory/index.tsx b/frontend/src/container/PipelinePage/Layouts/ChangeHistory/index.tsx index ab70101ea3..326ea93e61 100644 --- a/frontend/src/container/PipelinePage/Layouts/ChangeHistory/index.tsx +++ b/frontend/src/container/PipelinePage/Layouts/ChangeHistory/index.tsx @@ -5,12 +5,13 @@ import { changeHistoryColumns } from '../../PipelineListsView/config'; import { HistoryTableWrapper } from '../../styles'; import { historyPagination } from '../config'; -function ChangeHistory({ piplineData }: ChangeHistoryProps): JSX.Element { +function ChangeHistory({ pipelineData }: ChangeHistoryProps): JSX.Element { return ( @@ -18,7 +19,7 @@ function ChangeHistory({ piplineData }: ChangeHistoryProps): JSX.Element { } interface ChangeHistoryProps { - piplineData: Pipeline; + pipelineData: Pipeline; } export default ChangeHistory; diff --git a/frontend/src/container/PipelinePage/Layouts/Pipeline/CreatePipelineButton.tsx b/frontend/src/container/PipelinePage/Layouts/Pipeline/CreatePipelineButton.tsx index 05151506df..68d12f066b 100644 --- a/frontend/src/container/PipelinePage/Layouts/Pipeline/CreatePipelineButton.tsx +++ b/frontend/src/container/PipelinePage/Layouts/Pipeline/CreatePipelineButton.tsx @@ -11,13 +11,13 @@ function CreatePipelineButton({ setActionType, isActionMode, setActionMode, - piplineData, + pipelineData, }: CreatePipelineButtonProps): JSX.Element { const { t } = useTranslation(['pipeline']); const isAddNewPipelineVisible = useMemo( - () => checkDataLength(piplineData?.pipelines), - [piplineData?.pipelines], + () => checkDataLength(pipelineData?.pipelines), + [pipelineData?.pipelines], ); const isDisabled = isActionMode === ActionMode.Editing; @@ -56,7 +56,7 @@ interface CreatePipelineButtonProps { setActionType: (actionType: string) => void; isActionMode: string; setActionMode: (actionMode: string) => void; - piplineData: Pipeline; + pipelineData: Pipeline; } export default CreatePipelineButton; diff --git a/frontend/src/container/PipelinePage/Layouts/Pipeline/index.tsx b/frontend/src/container/PipelinePage/Layouts/Pipeline/index.tsx index da17d90e95..963196cb2d 100644 --- a/frontend/src/container/PipelinePage/Layouts/Pipeline/index.tsx +++ b/frontend/src/container/PipelinePage/Layouts/Pipeline/index.tsx @@ -7,7 +7,7 @@ import PipelinesSearchSection from './PipelinesSearchSection'; function PipelinePageLayout({ refetchPipelineLists, - piplineData, + pipelineData, }: PipelinePageLayoutProps): JSX.Element { const [isActionType, setActionType] = useState(); const [isActionMode, setActionMode] = useState('viewing-mode'); @@ -19,7 +19,7 @@ function PipelinePageLayout({ setActionType={setActionType} setActionMode={setActionMode} isActionMode={isActionMode} - piplineData={piplineData} + pipelineData={pipelineData} /> @@ -37,7 +37,7 @@ function PipelinePageLayout({ interface PipelinePageLayoutProps { refetchPipelineLists: VoidFunction; - piplineData: Pipeline; + pipelineData: Pipeline; } export default PipelinePageLayout; diff --git a/frontend/src/container/PipelinePage/PipelineListsView/ModeAndConfiguration.tsx b/frontend/src/container/PipelinePage/PipelineListsView/ModeAndConfiguration.tsx index 9c6a0d6a17..3c72f1acaa 100644 --- a/frontend/src/container/PipelinePage/PipelineListsView/ModeAndConfiguration.tsx +++ b/frontend/src/container/PipelinePage/PipelineListsView/ModeAndConfiguration.tsx @@ -4,21 +4,21 @@ import { ModeAndConfigWrapper } from './styles'; function ModeAndConfiguration({ isActionMode, - verison, + version, }: ModeAndConfigurationType): JSX.Element { const actionMode = isActionMode === ActionMode.Editing; return ( Mode: {actionMode ? 'Editing' : 'Viewing'} -
Configuration Version: {verison}
+
Configuration Version: {version}
); } export interface ModeAndConfigurationType { isActionMode: string; - verison: string | number; + version: string | number; } export default ModeAndConfiguration; diff --git a/frontend/src/container/PipelinePage/PipelineListsView/index.tsx b/frontend/src/container/PipelinePage/PipelineListsView/index.tsx index 9ae3cf6ab9..703088ad22 100644 --- a/frontend/src/container/PipelinePage/PipelineListsView/index.tsx +++ b/frontend/src/container/PipelinePage/PipelineListsView/index.tsx @@ -47,7 +47,7 @@ function PipelineListsView({ setActionType, isActionMode, setActionMode, - piplineData, + pipelineData, refetchPipelineLists, pipelineSearchValue, }: PipelineListsViewProps): JSX.Element { @@ -55,10 +55,10 @@ function PipelineListsView({ const [modal, contextHolder] = Modal.useModal(); const { notifications } = useNotifications(); const [prevPipelineData, setPrevPipelineData] = useState>( - cloneDeep(piplineData?.pipelines), + cloneDeep(pipelineData?.pipelines), ); const [currPipelineData, setCurrPipelineData] = useState>( - cloneDeep(piplineData?.pipelines), + cloneDeep(pipelineData?.pipelines), ); const [ expandedPipelineData, @@ -77,14 +77,14 @@ function PipelineListsView({ const isEditingActionMode = isActionMode === ActionMode.Editing; useEffect(() => { - if (pipelineSearchValue === '') setCurrPipelineData(piplineData?.pipelines); + if (pipelineSearchValue === '') setCurrPipelineData(pipelineData?.pipelines); if (pipelineSearchValue !== '') { - const filterData = piplineData?.pipelines.filter((data: PipelineData) => + const filterData = pipelineData?.pipelines.filter((data: PipelineData) => getDataOnSearch(data as never, pipelineSearchValue), ); setCurrPipelineData(filterData); } - }, [pipelineSearchValue, piplineData?.pipelines]); + }, [pipelineSearchValue, pipelineData?.pipelines]); const handleAlert = useCallback( ({ title, descrition, buttontext, onCancel, onOk }: AlertMessage) => { @@ -414,7 +414,7 @@ function PipelineListsView({
void; isActionMode: string; setActionMode: (actionMode: ActionMode) => void; - piplineData: Pipeline; + pipelineData: Pipeline; refetchPipelineLists: VoidFunction; pipelineSearchValue: string; } diff --git a/frontend/src/container/PipelinePage/mocks/pipeline.ts b/frontend/src/container/PipelinePage/mocks/pipeline.ts index 580595d474..d91665ce03 100644 --- a/frontend/src/container/PipelinePage/mocks/pipeline.ts +++ b/frontend/src/container/PipelinePage/mocks/pipeline.ts @@ -1,6 +1,6 @@ import { Pipeline, PipelineData } from 'types/api/pipeline/def'; -export const configurationVerison = '1.0'; +export const configurationVersion = '1.0'; export const pipelineMockData: Array = [ { diff --git a/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx b/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx index 09d7f7439b..fd9d546db7 100644 --- a/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx +++ b/frontend/src/container/PipelinePage/tests/CreatePipelineButton.test.tsx @@ -18,7 +18,7 @@ describe('PipelinePage container test', () => { setActionType={jest.fn()} isActionMode="viewing-mode" setActionMode={jest.fn()} - piplineData={pipelineApiResponseMockData} + pipelineData={pipelineApiResponseMockData} /> diff --git a/frontend/src/container/PipelinePage/tests/PipelinePageLayout.test.tsx b/frontend/src/container/PipelinePage/tests/PipelinePageLayout.test.tsx index db8e850afb..91d5dfe244 100644 --- a/frontend/src/container/PipelinePage/tests/PipelinePageLayout.test.tsx +++ b/frontend/src/container/PipelinePage/tests/PipelinePageLayout.test.tsx @@ -49,7 +49,7 @@ describe('PipelinePage container test', () => { diff --git a/frontend/src/pages/Pipelines/index.tsx b/frontend/src/pages/Pipelines/index.tsx index 8828ad4ab7..dd9ea1d185 100644 --- a/frontend/src/pages/Pipelines/index.tsx +++ b/frontend/src/pages/Pipelines/index.tsx @@ -8,14 +8,30 @@ import { useNotifications } from 'hooks/useNotifications'; import { useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useQuery } from 'react-query'; +import { SuccessResponse } from 'types/api'; import { Pipeline } from 'types/api/pipeline/def'; +const pipelineRefetchInterval = ( + pipelineResponse: SuccessResponse | undefined, +): number | false => { + // Refetch pipeline data periodically if deployment of + // its latest changes is not complete yet. + const latestVersion = pipelineResponse?.payload?.history?.[0]; + const isLatestDeploymentFinished = ['DEPLOYED', 'FAILED'].includes( + latestVersion?.deployStatus || '', + ); + if (latestVersion && !isLatestDeploymentFinished) { + return 3000; + } + return false; +}; + function Pipelines(): JSX.Element { const { t } = useTranslation('common'); const { notifications } = useNotifications(); const { isLoading, - data: piplineData, + data: pipelineData, isError, refetch: refetchPipelineLists, } = useQuery(['version', 'latest', 'pipeline'], { @@ -23,6 +39,7 @@ function Pipelines(): JSX.Element { getPipeline({ version: 'latest', }), + refetchInterval: pipelineRefetchInterval, }); const tabItems: TabsProps['items'] = useMemo( @@ -33,26 +50,28 @@ function Pipelines(): JSX.Element { children: ( ), }, { key: 'change-history', label: `Change History`, - children: , + children: ( + + ), }, ], - [piplineData?.payload, refetchPipelineLists], + [pipelineData?.payload, refetchPipelineLists], ); useEffect(() => { - if (piplineData?.error && isError) { + if (pipelineData?.error && isError) { notifications.error({ - message: piplineData?.error || t('something_went_wrong'), + message: pipelineData?.error || t('something_went_wrong'), }); } - }, [isError, notifications, piplineData?.error, t]); + }, [isError, notifications, pipelineData?.error, t]); if (isLoading) { return ;