mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-17 12:25:54 +08:00
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 <palashgdev@gmail.com>
This commit is contained in:
parent
3d03ad52b1
commit
7ad489ebb4
@ -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 (
|
||||
<HistoryTableWrapper>
|
||||
<Table
|
||||
columns={changeHistoryColumns}
|
||||
dataSource={piplineData?.history ?? []}
|
||||
dataSource={pipelineData?.history ?? []}
|
||||
rowKey="id"
|
||||
pagination={historyPagination}
|
||||
/>
|
||||
</HistoryTableWrapper>
|
||||
@ -18,7 +19,7 @@ function ChangeHistory({ piplineData }: ChangeHistoryProps): JSX.Element {
|
||||
}
|
||||
|
||||
interface ChangeHistoryProps {
|
||||
piplineData: Pipeline;
|
||||
pipelineData: Pipeline;
|
||||
}
|
||||
|
||||
export default ChangeHistory;
|
||||
|
@ -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;
|
||||
|
@ -7,7 +7,7 @@ import PipelinesSearchSection from './PipelinesSearchSection';
|
||||
|
||||
function PipelinePageLayout({
|
||||
refetchPipelineLists,
|
||||
piplineData,
|
||||
pipelineData,
|
||||
}: PipelinePageLayoutProps): JSX.Element {
|
||||
const [isActionType, setActionType] = useState<string>();
|
||||
const [isActionMode, setActionMode] = useState<string>('viewing-mode');
|
||||
@ -19,7 +19,7 @@ function PipelinePageLayout({
|
||||
setActionType={setActionType}
|
||||
setActionMode={setActionMode}
|
||||
isActionMode={isActionMode}
|
||||
piplineData={piplineData}
|
||||
pipelineData={pipelineData}
|
||||
/>
|
||||
<PipelinesSearchSection setPipelineSearchValue={setPipelineSearchValue} />
|
||||
<PipelineListsView
|
||||
@ -27,7 +27,7 @@ function PipelinePageLayout({
|
||||
setActionType={setActionType}
|
||||
setActionMode={setActionMode}
|
||||
isActionMode={isActionMode}
|
||||
piplineData={piplineData}
|
||||
pipelineData={pipelineData}
|
||||
refetchPipelineLists={refetchPipelineLists}
|
||||
pipelineSearchValue={pipelineSearchValue}
|
||||
/>
|
||||
@ -37,7 +37,7 @@ function PipelinePageLayout({
|
||||
|
||||
interface PipelinePageLayoutProps {
|
||||
refetchPipelineLists: VoidFunction;
|
||||
piplineData: Pipeline;
|
||||
pipelineData: Pipeline;
|
||||
}
|
||||
|
||||
export default PipelinePageLayout;
|
||||
|
@ -4,21 +4,21 @@ import { ModeAndConfigWrapper } from './styles';
|
||||
|
||||
function ModeAndConfiguration({
|
||||
isActionMode,
|
||||
verison,
|
||||
version,
|
||||
}: ModeAndConfigurationType): JSX.Element {
|
||||
const actionMode = isActionMode === ActionMode.Editing;
|
||||
|
||||
return (
|
||||
<ModeAndConfigWrapper>
|
||||
Mode: <span>{actionMode ? 'Editing' : 'Viewing'}</span>
|
||||
<div>Configuration Version: {verison}</div>
|
||||
<div>Configuration Version: {version}</div>
|
||||
</ModeAndConfigWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export interface ModeAndConfigurationType {
|
||||
isActionMode: string;
|
||||
verison: string | number;
|
||||
version: string | number;
|
||||
}
|
||||
|
||||
export default ModeAndConfiguration;
|
||||
|
@ -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<Array<PipelineData>>(
|
||||
cloneDeep(piplineData?.pipelines),
|
||||
cloneDeep(pipelineData?.pipelines),
|
||||
);
|
||||
const [currPipelineData, setCurrPipelineData] = useState<Array<PipelineData>>(
|
||||
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({
|
||||
<Container>
|
||||
<ModeAndConfiguration
|
||||
isActionMode={isActionMode}
|
||||
verison={piplineData?.version}
|
||||
version={pipelineData?.version}
|
||||
/>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Table
|
||||
@ -445,7 +445,7 @@ interface PipelineListsViewProps {
|
||||
setActionType: (actionType?: ActionType) => void;
|
||||
isActionMode: string;
|
||||
setActionMode: (actionMode: ActionMode) => void;
|
||||
piplineData: Pipeline;
|
||||
pipelineData: Pipeline;
|
||||
refetchPipelineLists: VoidFunction;
|
||||
pipelineSearchValue: string;
|
||||
}
|
||||
|
@ -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<PipelineData> = [
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ describe('PipelinePage container test', () => {
|
||||
setActionType={jest.fn()}
|
||||
isActionMode="viewing-mode"
|
||||
setActionMode={jest.fn()}
|
||||
piplineData={pipelineApiResponseMockData}
|
||||
pipelineData={pipelineApiResponseMockData}
|
||||
/>
|
||||
</I18nextProvider>
|
||||
</Provider>
|
||||
|
@ -49,7 +49,7 @@ describe('PipelinePage container test', () => {
|
||||
<Provider store={store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<PipelinePageLayout
|
||||
piplineData={pipelinedata}
|
||||
pipelineData={pipelinedata}
|
||||
refetchPipelineLists={refetchPipelineLists}
|
||||
/>
|
||||
</I18nextProvider>
|
||||
|
@ -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<Pipeline> | 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: (
|
||||
<PipelinePage
|
||||
refetchPipelineLists={refetchPipelineLists}
|
||||
piplineData={piplineData?.payload as Pipeline}
|
||||
pipelineData={pipelineData?.payload as Pipeline}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'change-history',
|
||||
label: `Change History`,
|
||||
children: <ChangeHistory piplineData={piplineData?.payload as Pipeline} />,
|
||||
children: (
|
||||
<ChangeHistory pipelineData={pipelineData?.payload as Pipeline} />
|
||||
),
|
||||
},
|
||||
],
|
||||
[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 <Spinner height="75vh" tip="Loading Pipelines..." />;
|
||||
|
Loading…
x
Reference in New Issue
Block a user