Skip to content

Commit 31393af

Browse files
feat: add new hardware view using hardware-v2 endpoint
1 parent 088fc4b commit 31393af

File tree

15 files changed

+963
-5
lines changed

15 files changed

+963
-5
lines changed

dashboard/src/api/hardware.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { useQuery } from '@tanstack/react-query';
33

44
import { useSearch } from '@tanstack/react-router';
55

6-
import type { HardwareListingResponse } from '@/types/hardware';
6+
import type {
7+
HardwareListingResponse,
8+
HardwareListingResponseV2,
9+
} from '@/types/hardware';
710

811
import { RequestData } from './commonRequest';
912

@@ -50,3 +53,47 @@ export const useHardwareListing = (
5053
refetchOnWindowFocus: false,
5154
});
5255
};
56+
57+
const fetchHardwareListingV2 = async (
58+
origin: string,
59+
startTimestampInSeconds: number,
60+
endTimestampInSeconds: number,
61+
): Promise<HardwareListingResponseV2> => {
62+
const data = await RequestData.get<HardwareListingResponseV2>(
63+
'/api/hardware-v2/',
64+
{
65+
params: {
66+
startTimestampInSeconds,
67+
endTimestampInSeconds,
68+
origin,
69+
},
70+
},
71+
);
72+
73+
return data;
74+
};
75+
76+
export const useHardwareListingV2 = (
77+
startTimestampInSeconds: number,
78+
endTimestampInSeconds: number,
79+
): UseQueryResult<HardwareListingResponseV2> => {
80+
const { origin } = useSearch({ from: '/_main/hardware-new' });
81+
82+
const queryKey = [
83+
'hardwareListingV2',
84+
startTimestampInSeconds,
85+
endTimestampInSeconds,
86+
origin,
87+
];
88+
89+
return useQuery({
90+
queryKey,
91+
queryFn: () =>
92+
fetchHardwareListingV2(
93+
origin,
94+
startTimestampInSeconds,
95+
endTimestampInSeconds,
96+
),
97+
refetchOnWindowFocus: false,
98+
});
99+
};

dashboard/src/components/OpenGraphTags/ListingOGTags.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const ListingOGTags = ({
3030
case '/issues':
3131
descriptionId = 'issueListing.description';
3232
break;
33+
case '/hardware-new':
34+
descriptionId = 'hardwareListing.description';
35+
break;
3336
}
3437
return (
3538
formatMessage({ id: descriptionId }) +
@@ -47,6 +50,8 @@ const ListingOGTags = ({
4750
return formatMessage({ id: 'hardwareListing.title' });
4851
case '/issues':
4952
return formatMessage({ id: 'issueListing.title' });
53+
case '/hardware-new':
54+
return formatMessage({ id: 'hardwareListing.title' });
5055
}
5156
}, [formatMessage, monitor]);
5257

dashboard/src/components/SideMenu/SideMenu.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ type SideMenuItemProps = {
7777
const SideMenuItem = ({ item }: SideMenuItemProps): JSX.Element => {
7878
const { pathname } = useLocation();
7979

80-
const isCurrentPath = pathname.startsWith(item.navigateTo);
80+
const isCurrentPath =
81+
pathname.startsWith(item.navigateTo) &&
82+
(pathname.length === item.navigateTo.length ||
83+
pathname[item.navigateTo.length] === '/');
8184

8285
return (
8386
<NavigationMenuItem key={item.idIntl} className="w-full">
@@ -108,6 +111,12 @@ const SideMenu = (): JSX.Element => {
108111
icon: <MdOutlineMonitorHeart className="size-5" />,
109112
selected: false,
110113
},
114+
{
115+
navigateTo: '/hardware-new',
116+
idIntl: 'routes.hardwareNewMonitor',
117+
icon: <MdOutlineMonitorHeart className="size-5" />,
118+
selected: false,
119+
},
111120
{
112121
navigateTo: '/issues',
113122
idIntl: 'routes.issueMonitor',

dashboard/src/components/TopBar/TopBar.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const getTargetPath = (basePath: string): PossibleMonitorPath => {
1717
switch (basePath) {
1818
case 'hardware':
1919
return '/hardware';
20+
case 'hardware-new':
21+
return '/hardware-new';
2022
case 'issues':
2123
return '/issues';
2224
default:
@@ -47,7 +49,7 @@ const OriginSelect = ({ basePath }: { basePath: string }): JSX.Element => {
4749
}
4850

4951
let pageOrigins: string[];
50-
if (targetPath === '/hardware') {
52+
if (targetPath === '/hardware' || targetPath === '/hardware-new') {
5153
pageOrigins = originData.test_origins;
5254
} else {
5355
pageOrigins = originData.checkout_origins;
@@ -93,6 +95,8 @@ const TitleName = ({ basePath }: { basePath: string }): JSX.Element => {
9395
return <FormattedMessage id="routes.treeMonitor" />;
9496
case 'hardware':
9597
return <FormattedMessage id="routes.hardwareMonitor" />;
98+
case 'hardware-new':
99+
return <FormattedMessage id="routes.hardwareNewMonitor" />;
96100
case 'issues':
97101
return <FormattedMessage id="routes.issueMonitor" />;
98102
case 'build':

dashboard/src/locales/messages/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ export const messages = {
263263
"This is the same logspec data that's in the misc data section",
264264
'routes.buildDetails': 'Build',
265265
'routes.hardwareMonitor': 'Hardware',
266+
'routes.hardwareNewMonitor': 'Hardware New',
266267
'routes.issueDetails': 'Issue',
267268
'routes.issueMonitor': 'Issues',
268269
'routes.testDetails': 'Test',

dashboard/src/pages/Hardware/Hardware.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useCallback } from 'react';
33

44
import { useIntl } from 'react-intl';
55

6-
import { useNavigate, useSearch } from '@tanstack/react-router';
6+
import { useNavigate, useSearch, Link } from '@tanstack/react-router';
77

88
import HardwareListingPage from '@/pages/Hardware/HardwareListingPage';
99

@@ -48,6 +48,23 @@ const Hardware = (): JSX.Element => {
4848
/>
4949
</div>
5050
</div>
51+
<div className="rounded-md bg-yellow-100 p-3 text-sm text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300">
52+
This is the original version of the hardware listing, please refer to
53+
the new, optimized version{' '}
54+
<Link to="/hardware-new" className="underline">
55+
here
56+
</Link>
57+
. If you find any bugs or divergences, please report to{' '}
58+
<a
59+
href="https://github.com/kernelci/dashboard/issues"
60+
target="_blank"
61+
rel="noreferrer"
62+
className="underline"
63+
>
64+
GitHub Issues
65+
</a>
66+
. This page will be deprecated on March 27, 2026.
67+
</div>
5168
<div className="bg-light-gray w-full py-10">
5269
<HardwareListingPage inputFilter={hardwareSearch ?? ''} />
5370
</div>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import type { ChangeEvent, JSX } from 'react';
2+
import { useCallback } from 'react';
3+
4+
import { useIntl } from 'react-intl';
5+
6+
import { useNavigate, useSearch, Link } from '@tanstack/react-router';
7+
8+
import HardwareListingPage from '@/pages/HardwareNew/HardwareListingPage';
9+
10+
import DebounceInput from '@/components/DebounceInput/DebounceInput';
11+
import { MemoizedListingOGTags } from '@/components/OpenGraphTags/ListingOGTags';
12+
13+
const Hardware = (): JSX.Element => {
14+
const { hardwareSearch } = useSearch({
15+
from: '/_main/hardware-new',
16+
});
17+
18+
const navigate = useNavigate({ from: '/hardware-new' });
19+
20+
const onInputSearchTextChange = useCallback(
21+
(e: ChangeEvent<HTMLInputElement>) => {
22+
navigate({
23+
from: '/hardware-new',
24+
search: previousSearch => ({
25+
...previousSearch,
26+
hardwareSearch: e.target.value,
27+
}),
28+
state: s => s,
29+
});
30+
},
31+
[navigate],
32+
);
33+
34+
const { formatMessage } = useIntl();
35+
36+
return (
37+
<>
38+
<MemoizedListingOGTags monitor="/hardware-new" search={hardwareSearch} />
39+
<div className="fixed top-0 z-10 mx-[380px] flex w-full pt-5 pr-12 pl-6">
40+
<div className="flex w-2/3 items-center px-6">
41+
<DebounceInput
42+
debouncedSideEffect={onInputSearchTextChange}
43+
className="w-2/3"
44+
type="text"
45+
startingValue={hardwareSearch}
46+
placeholder={formatMessage({
47+
id: 'hardware.searchPlaceholder',
48+
})}
49+
/>
50+
</div>
51+
</div>
52+
<div className="rounded-md bg-green-100 p-3 text-sm text-green-800 dark:bg-green-900 dark:text-green-300">
53+
This is the new, optimized version of the hardware listing. If you find
54+
any bugs, please report to{' '}
55+
<a
56+
href="https://github.com/kernelci/dashboard/issues"
57+
target="_blank"
58+
rel="noreferrer"
59+
className="underline"
60+
>
61+
GitHub Issues
62+
</a>{' '}
63+
and you can still access the old version{' '}
64+
<Link to="/hardware" className="underline">
65+
here
66+
</Link>
67+
. Please note that some historical data might be missing, but it should
68+
be updated with recent data.
69+
</div>
70+
<div className="bg-light-gray w-full py-10">
71+
<HardwareListingPage inputFilter={hardwareSearch ?? ''} />
72+
</div>
73+
</>
74+
);
75+
};
76+
77+
export default Hardware;

0 commit comments

Comments
 (0)