Skip to content

Commit

Permalink
feat(listing-details): add and implements query inconsistency invalid…
Browse files Browse the repository at this point in the history
…ator hook

add hook to cache bust in case of inconsistency between listing and
details

closes #833

```
  • Loading branch information
WilsonNet committed Jan 31, 2025
1 parent d5cda0d commit eece1ad
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 32 deletions.
13 changes: 8 additions & 5 deletions dashboard/src/components/TreeListingPage/TreeListingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMemo } from 'react';

import type {
TableTestStatus,
Tree,
TreeFastPathResponse,
TreeTableBody,
Expand Down Expand Up @@ -67,25 +68,27 @@ const TreeListingPage = ({ inputFilter }: ITreeListingPage): JSX.Element => {
: undefined;

const testStatus = isCompleteTree(tree)
? {
done: tree.test_status.done,
? ({
error: tree.test_status.error,
fail: tree.test_status.fail,
miss: tree.test_status.miss,
pass: tree.test_status.pass,
skip: tree.test_status.skip,
}
done: tree.test_status.done,
null: tree.test_status.null,
} satisfies TableTestStatus)
: undefined;

const bootStatus = isCompleteTree(tree)
? {
? ({
done: tree.boot_status.done,
error: tree.boot_status.error,
fail: tree.boot_status.fail,
miss: tree.boot_status.miss,
pass: tree.boot_status.pass,
skip: tree.boot_status.skip,
}
null: tree.boot_status.null,
} satisfies TableTestStatus)
: undefined;

return {
Expand Down
36 changes: 31 additions & 5 deletions dashboard/src/components/TreeListingPage/TreeTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { TooltipDateTime } from '@/components/TooltipDateTime';

import type { TreeTableBody } from '@/types/tree/Tree';
import { RedirectFrom, zOrigin } from '@/types/general';
import type { TFilter, TOrigins } from '@/types/general';
import type { TFilter, TOrigins, BuildStatus } from '@/types/general';

import { formattedBreakLineValue } from '@/locales/messages';

Expand Down Expand Up @@ -62,6 +62,8 @@ import CopyButton from '@/components/Button/CopyButton';

import type { ListingTableColumnMeta } from '@/types/table';

import { statusCountToRequiredStatusCount } from '@/utils/status';

import { InputTime } from './InputTime';

const MemoizedInputTime = memo(InputTime);
Expand All @@ -75,10 +77,6 @@ const getLinkProps = (
return {
to: '/tree/$treeId',
params: { treeId: row.original.id },
state: {
id: row.original.id,
from: RedirectFrom.Tree,
},
search: previousSearch => ({
tableFilter: {
bootsTable: possibleTestsTableFilter[0],
Expand All @@ -97,6 +95,34 @@ const getLinkProps = (
},
intervalInDays: previousSearch.intervalInDays,
}),
state: s => ({
...s,
id: row.original.id,
from: RedirectFrom.Tree,
treeStatusCount: {
buildsStatus: {
valid: row.original.buildStatus?.valid ?? 0,
invalid: row.original.buildStatus?.invalid ?? 0,
null: row.original.buildStatus?.null ?? 0,
} satisfies BuildStatus,
testStatus: statusCountToRequiredStatusCount({
DONE: row.original.testStatus?.done,
PASS: row.original.testStatus?.pass,
FAIL: row.original.testStatus?.fail,
ERROR: row.original.testStatus?.error,
MISS: row.original.testStatus?.miss,
SKIP: row.original.testStatus?.skip,
}),
bootStatus: statusCountToRequiredStatusCount({
DONE: row.original.bootStatus?.done,
PASS: row.original.bootStatus?.pass,
FAIL: row.original.bootStatus?.fail,
ERROR: row.original.bootStatus?.error,
MISS: row.original.bootStatus?.miss,
SKIP: row.original.bootStatus?.skip,
}),
},
}),
};
};

Expand Down
46 changes: 46 additions & 0 deletions dashboard/src/hooks/useQueryInconsistencyInvalidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { useQueryClient } from '@tanstack/react-query';
import type { UseNavigateResult } from '@tanstack/react-router';
import { useEffect } from 'react';
import { isEqual } from 'lodash-es';

type ReferenceTable =
| Record<string, Record<string, number> | undefined>
| undefined;

type QueryInconsistencyInvalidatorArgs<T extends ReferenceTable> = {
referenceData?: T;
comparedData?: T;
enabled?: boolean;
navigate: UseNavigateResult<'/tree/$treeId' | '/hardware/$hardwareId'>;
};

export const useQueryInconsistencyInvalidator = <T extends ReferenceTable>({
referenceData: referenceData,
comparedData: comparedData,
navigate,
enabled = true,
}: QueryInconsistencyInvalidatorArgs<T>): void => {
const queryClient = useQueryClient();
useEffect(() => {
if (!enabled || !referenceData || !comparedData) {
return;
}

const shouldInvalidate = !isEqual(referenceData, comparedData);

if (shouldInvalidate) {
queryClient.invalidateQueries().then(() => {
navigate({
search: s => s,
state: s => {
return {
...s,
treeStatusCount: undefined,
hardwareStatusCount: undefined,
};
},
});
});
}
}, [referenceData, comparedData, queryClient, navigate, enabled]);
};
16 changes: 15 additions & 1 deletion dashboard/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import { routeTree } from './routeTree.gen';
import './index.css';
import { isDev } from './lib/utils/vite';
import { ToastProvider } from './components/ui/toast';
import type { RedirectFrom } from './types/general';
import type {
BuildStatus,
RedirectFrom,
RequiredStatusCount,
} from './types/general';
import { parseSearch, stringifySearch } from './utils/search';

declare global {
Expand All @@ -40,6 +44,16 @@ declare module '@tanstack/react-router' {
interface HistoryState {
id?: string;
from?: RedirectFrom;
treeStatusCount?: {
buildsStatus?: BuildStatus;
bootStatus?: RequiredStatusCount;
testStatus?: RequiredStatusCount;
};
hardwareStatusCount?: {
builds: BuildStatus;
boot: RequiredStatusCount;
test: RequiredStatusCount;
};
}
}

Expand Down
8 changes: 5 additions & 3 deletions dashboard/src/pages/Hardware/HardwareListingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { dateObjectToTimestampInSeconds, daysToSeconds } from '@/utils/date';

import { MemoizedSectionError } from '@/components/DetailsPages/SectionError';

import type { BuildStatus, StatusCount } from '@/types/general';

import { HardwareTable } from './HardwareTable';

interface HardwareListingPageProps {
Expand Down Expand Up @@ -77,13 +79,13 @@ const HardwareListingPage = ({
return hardware.hardware_name?.includes(inputFilter);
})
.map((hardware): HardwareTableItem => {
const buildCount = {
const buildCount: BuildStatus = {
valid: hardware.build_status_summary?.valid,
invalid: hardware.build_status_summary?.invalid,
null: hardware.build_status_summary?.null,
};

const testStatusCount = {
const testStatusCount: StatusCount = {
DONE: hardware.test_status_summary.DONE,
ERROR: hardware.test_status_summary.ERROR,
FAIL: hardware.test_status_summary.FAIL,
Expand All @@ -93,7 +95,7 @@ const HardwareListingPage = ({
NULL: hardware.test_status_summary.NULL,
};

const bootStatusCount = {
const bootStatusCount: StatusCount = {
DONE: hardware.boot_status_summary.DONE,
ERROR: hardware.boot_status_summary.ERROR,
FAIL: hardware.boot_status_summary.FAIL,
Expand Down
20 changes: 15 additions & 5 deletions dashboard/src/pages/Hardware/HardwareTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { PaginationInfo } from '@/components/Table/PaginationInfo';

import type { HardwareTableItem } from '@/types/hardware';

import { sumStatus } from '@/utils/status';
import { statusCountToRequiredStatusCount, sumStatus } from '@/utils/status';

import { usePaginationState } from '@/hooks/usePaginationState';

Expand Down Expand Up @@ -71,17 +71,27 @@ const getLinkProps = (
from: '/hardware',
to: '/hardware/$hardwareId',
params: { hardwareId: row.original.hardware_name },
state: {
id: row.original.hardware_name,
from: RedirectFrom.Hardware,
},
search: previousSearch => ({
...previousSearch,
currentPageTab: zPossibleTabValidator.parse(tabTarget),
startTimestampInSeconds,
endTimestampInSeconds,
diffFilter: { ...previousSearch.diffFilter, ...newDiffFilter },
}),
state: s => ({
...s,
id: row.original.hardware_name,
from: RedirectFrom.Hardware,
hardwareStatusCount: {
builds: row.original.build_status_summary,
test: statusCountToRequiredStatusCount(
row.original.test_status_summary,
),
boot: statusCountToRequiredStatusCount(
row.original.boot_status_summary,
),
},
}),
};
};

Expand Down
34 changes: 33 additions & 1 deletion dashboard/src/pages/TreeDetails/TreeDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { useNavigate, useParams, useSearch } from '@tanstack/react-router';
import {
useNavigate,
useParams,
useRouterState,
useSearch,
} from '@tanstack/react-router';
import { useCallback, useMemo } from 'react';

import { FormattedMessage } from 'react-intl';
Expand Down Expand Up @@ -48,6 +53,10 @@ import { useTreeDetailsLazyLoadQuery } from '@/hooks/useTreeDetailsLazyLoadQuery

import { LoadingCircle } from '@/components/ui/loading-circle';

import { useQueryInconsistencyInvalidator } from '@/hooks/useQueryInconsistencyInvalidator';

import { statusCountToRequiredStatusCount } from '@/utils/status';

import TreeDetailsFilter from './TreeDetailsFilter';
import type { TreeDetailsTabRightElement } from './Tabs/TreeDetailsTab';
import TreeDetailsTab from './Tabs/TreeDetailsTab';
Expand Down Expand Up @@ -139,6 +148,29 @@ function TreeDetails(): JSX.Element {
status: summaryQueryStatus,
} = treeDetailsLazyLoaded.summary;

const treeRouterStatus = useRouterState({
select: s => s.location.state.treeStatusCount,
});

type TreeRouterStatus = typeof treeRouterStatus;

const comparedData: TreeRouterStatus = useMemo(() => {
if (!data) return undefined;

const { builds, tests, boots } = data.summary;

return {
buildsStatus: builds.status,
testStatus: statusCountToRequiredStatusCount(tests.status),
bootStatus: statusCountToRequiredStatusCount(boots.status),
} satisfies TreeRouterStatus;
}, [data]);

useQueryInconsistencyInvalidator<TreeRouterStatus>({
referenceData: treeRouterStatus,
comparedData: comparedData,
navigate: navigate,
});
const onFilterChange = useCallback(
(newFilter: TFilter) => {
navigate({
Expand Down
37 changes: 36 additions & 1 deletion dashboard/src/pages/hardwareDetails/HardwareDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { useNavigate, useParams, useSearch } from '@tanstack/react-router';
import {
useNavigate,
useParams,
useRouterState,
useSearch,
} from '@tanstack/react-router';

import { FormattedMessage } from 'react-intl';

Expand Down Expand Up @@ -45,6 +50,10 @@ import { MemoizedSectionError } from '@/components/DetailsPages/SectionError';

import { useHardwareDetailsLazyLoadQuery } from '@/hooks/useHardwareDetailsLazyLoadQuery';

import { useQueryInconsistencyInvalidator } from '@/hooks/useQueryInconsistencyInvalidator';

import { statusCountToRequiredStatusCount } from '@/utils/status';

import { HardwareHeader } from './HardwareDetailsHeaderTable';
import type { TreeDetailsTabRightElement } from './Tabs/HardwareDetailsTabs';
import HardwareDetailsTabs from './Tabs/HardwareDetailsTabs';
Expand Down Expand Up @@ -153,6 +162,32 @@ function HardwareDetails(): JSX.Element {
treeIndexesLength: treeIndexesLength,
});

const hardwareStatusHistoryState = useRouterState({
select: s => s.location.state.hardwareStatusCount,
});

type HardwareStatusComparedState = typeof hardwareStatusHistoryState;

const hardwareDataPreparedForInconsistencyValidation: HardwareStatusComparedState =
useMemo(() => {
const { data } = summaryResponse;
if (!data) return;

const { boots, builds, tests } = data;

return {
boot: statusCountToRequiredStatusCount(boots.status),
test: statusCountToRequiredStatusCount(tests.status),
builds: builds.status,
} satisfies HardwareStatusComparedState;
}, [summaryResponse]);

useQueryInconsistencyInvalidator<HardwareStatusComparedState>({
referenceData: hardwareStatusHistoryState,
comparedData: hardwareDataPreparedForInconsistencyValidation,
navigate: navigate,
});

const hardwareTableForCommitHistory = useMemo(() => {
const result: CommitHead[] = [];
if (!summaryResponse.isLoading && summaryResponse.data) {
Expand Down
6 changes: 4 additions & 2 deletions dashboard/src/types/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,17 @@ export type BuildStatus = {
null: number;
};

export interface StatusCount {
export type StatusCount = {
PASS?: number;
FAIL?: number;
MISS?: number;
SKIP?: number;
ERROR?: number;
NULL?: number;
DONE?: number;
}
};

export type RequiredStatusCount = Required<StatusCount>;

export type Architecture = Record<
string,
Expand Down
Loading

0 comments on commit eece1ad

Please sign in to comment.