From 9cc842d580fd9570da1a57755cb4c3f7485f79a9 Mon Sep 17 00:00:00 2001 From: Luiz Georg Date: Wed, 24 Jun 2026 16:29:21 -0300 Subject: [PATCH 1/4] feat: remove checkout filtering in /trees (#1924) This filter was filtering very little in practice, and querying every lastest checkout is very cheap. Signed-off-by: Luiz Georg --- dashboard/src/utils/constants/general.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/utils/constants/general.ts b/dashboard/src/utils/constants/general.ts index d1cd1072e..0a90bbee8 100644 --- a/dashboard/src/utils/constants/general.ts +++ b/dashboard/src/utils/constants/general.ts @@ -9,4 +9,4 @@ export const ItemsPerPageValues = [5, 10, 20, 30, 40, 50]; export const DEFAULT_TIME_SEARCH = 7; export const REDUCED_TIME_SEARCH = 5; export const DEFAULT_LISTING_ITEMS = 10; -export const DEFAULT_LISTING_INTERVAL_IN_DAYS = 30; +export const DEFAULT_LISTING_INTERVAL_IN_DAYS = 36500; // 100 years, effectively no filter From 7cf98789c860d7407bec3c207a0406f333e063cb Mon Sep 17 00:00:00 2001 From: Luiz Georg Date: Wed, 24 Jun 2026 16:45:24 -0300 Subject: [PATCH 2/4] feat: add an indicator for the time filtering in /hardware (#1924) Closes: #1924 Signed-off-by: Luiz Georg --- dashboard/e2e/e2e-selectors.ts | 1 + dashboard/e2e/hardware-listing.spec.ts | 45 +++++++++++++++++++ .../components/FilterLabel/FilterLabel.tsx | 16 +++++++ dashboard/src/locales/messages/index.ts | 2 + .../src/pages/Hardware/HardwareTable.tsx | 23 +++++++--- 5 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 dashboard/src/components/FilterLabel/FilterLabel.tsx diff --git a/dashboard/e2e/e2e-selectors.ts b/dashboard/e2e/e2e-selectors.ts index f584cf1aa..78499fff1 100644 --- a/dashboard/e2e/e2e-selectors.ts +++ b/dashboard/e2e/e2e-selectors.ts @@ -49,4 +49,5 @@ export const HARDWARE_LISTING_SELECTORS = { branchSelector: '[data-test-id="hardware-branch-selector"]', revisionSelector: '[data-test-id="hardware-revision-selector"]', clearSelection: '[data-test-id="hardware-selection-clear"]', + filterLabel: '[data-test-id="hardware-filter-label"]', } as const; diff --git a/dashboard/e2e/hardware-listing.spec.ts b/dashboard/e2e/hardware-listing.spec.ts index c116597ba..b743f6e42 100644 --- a/dashboard/e2e/hardware-listing.spec.ts +++ b/dashboard/e2e/hardware-listing.spec.ts @@ -137,4 +137,49 @@ test.describe('Hardware Listing Page Tests', () => { ).toContainText('Select tree'); await expect(clearButton).toBeHidden(); }); + + test('filter label updates with query params', async ({ page }) => { + const filterLabel = page.locator(HARDWARE_LISTING_SELECTORS.filterLabel); + await expect(filterLabel).toBeVisible(); + await expect(filterLabel).toContainText( + /Showing latest checkout for trees updated in the last \d+ days/, + ); + + const url = new URL(page.url()); + + url.searchParams.set('days', '2'); + await page.goto(url.toString()); + await expect(filterLabel).toContainText('last 2 days'); + + url.searchParams.set('days', '7'); + await page.goto(url.toString()); + await expect(filterLabel).toContainText('last 7 days'); + }); + + test('selecting a revision toggles filter label', async ({ page }) => { + const filterLabel = page.locator(HARDWARE_LISTING_SELECTORS.filterLabel); + await expect(filterLabel).toBeVisible(); + + await selectComboboxOption(page, HARDWARE_LISTING_SELECTORS.treeSelector); + await expect(filterLabel).toBeHidden(); + + await page.locator(HARDWARE_LISTING_SELECTORS.clearSelection).click(); + await expect(filterLabel).toBeVisible(); + }); + + test('loading URL with revision does not show filter label', async ({ + page, + }) => { + await selectComboboxOption(page, HARDWARE_LISTING_SELECTORS.treeSelector); + const urlWithRevision = page.url(); + await expect(urlWithRevision).toMatch(/[?&]ch=/); + + await page.goto(urlWithRevision); + + const filterLabel = page.locator(HARDWARE_LISTING_SELECTORS.filterLabel); + await expect(filterLabel).toBeHidden(); + + await page.locator(HARDWARE_LISTING_SELECTORS.clearSelection).click(); + await expect(filterLabel).toBeVisible(); + }); }); diff --git a/dashboard/src/components/FilterLabel/FilterLabel.tsx b/dashboard/src/components/FilterLabel/FilterLabel.tsx new file mode 100644 index 000000000..bec508508 --- /dev/null +++ b/dashboard/src/components/FilterLabel/FilterLabel.tsx @@ -0,0 +1,16 @@ +import type { JSX } from 'react'; +import { FormattedMessage } from 'react-intl'; + +export function FilterLabel({ days }: { days: number }): JSX.Element { + return ( +

+ +

+ ); +} diff --git a/dashboard/src/locales/messages/index.ts b/dashboard/src/locales/messages/index.ts index 08c5f0202..d972da1e0 100644 --- a/dashboard/src/locales/messages/index.ts +++ b/dashboard/src/locales/messages/index.ts @@ -223,6 +223,8 @@ export const messages = { 'hardwareListing.branchSelectorSearchPlaceholder': 'Search branch...', 'hardwareListing.clearSelection': 'Clear selection', 'hardwareListing.description': 'List of hardware from kernel tests', + 'hardwareListing.latestCheckoutFilterLabel': + 'Showing latest checkout for trees updated in the last {days} days', 'hardwareListing.notFound': 'No hardware information available', 'hardwareListing.revisionEmpty': 'The selected revision has no hardware rows yet. Data ingestion may still be in progress.', diff --git a/dashboard/src/pages/Hardware/HardwareTable.tsx b/dashboard/src/pages/Hardware/HardwareTable.tsx index 67deb9414..a797e79ad 100644 --- a/dashboard/src/pages/Hardware/HardwareTable.tsx +++ b/dashboard/src/pages/Hardware/HardwareTable.tsx @@ -46,6 +46,8 @@ import type { import { sumStatus } from '@/utils/status'; +import { REDUCED_TIME_SEARCH } from '@/utils/constants/general'; + import { usePaginationState } from '@/hooks/usePaginationState'; import { zPossibleTabValidator } from '@/types/tree/TreeDetails'; @@ -61,6 +63,8 @@ import QuerySwitcher from '@/components/QuerySwitcher/QuerySwitcher'; import { MemoizedSectionError } from '@/components/DetailsPages/SectionError'; import { LoadingCircle } from '@/components/ui/loading-circle'; +import { FilterLabel } from '@/components/FilterLabel/FilterLabel'; + import { buildHardwareDetailsSearch } from './hardwareTableUtils'; import { HardwareRevisionSelectors } from './HardwareRevisionSelectors'; import type { HardwareRevisionSelectorValue } from './hardwareSelection'; @@ -390,7 +394,7 @@ export function HardwareTable({ onTreeChange = (): void => {}, onClearSelection = (): void => {}, }: IHardwareTable): JSX.Element { - const { listingSize } = useSearch({ strict: false }); + const { listingSize, intervalInDays } = useSearch({ strict: false }); const navigate = useNavigate({ from: navigateFrom }); const [sorting, setSorting] = useState([]); @@ -546,11 +550,18 @@ export function HardwareTable({ {tableBody} - +
+ {!selection && ( + + )} +
+ +
+
); } From 83754b72996fd15aedb1f7ae3dc096552e32fb1f Mon Sep 17 00:00:00 2001 From: Luiz Georg Date: Fri, 26 Jun 2026 12:43:50 -0300 Subject: [PATCH 3/4] fixup! feat: remove checkout filtering in /trees (#1924) this change was out of scope and requires further investigation Signed-off-by: Luiz Georg --- dashboard/src/utils/constants/general.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/utils/constants/general.ts b/dashboard/src/utils/constants/general.ts index 0a90bbee8..d1cd1072e 100644 --- a/dashboard/src/utils/constants/general.ts +++ b/dashboard/src/utils/constants/general.ts @@ -9,4 +9,4 @@ export const ItemsPerPageValues = [5, 10, 20, 30, 40, 50]; export const DEFAULT_TIME_SEARCH = 7; export const REDUCED_TIME_SEARCH = 5; export const DEFAULT_LISTING_ITEMS = 10; -export const DEFAULT_LISTING_INTERVAL_IN_DAYS = 36500; // 100 years, effectively no filter +export const DEFAULT_LISTING_INTERVAL_IN_DAYS = 30; From b2de4f9c1c89b7b554b664cdd02a73a036842af0 Mon Sep 17 00:00:00 2001 From: Luiz Georg Date: Fri, 26 Jun 2026 12:59:28 -0300 Subject: [PATCH 4/4] amend! feat: add an indicator for the time filtering in /hardware (#1924) feat: add a label to indicate hidden filtering filtering (#1924) Closes: #1924 Signed-off-by: Luiz Georg --- .../components/TreeListingPage/TreeTable.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/dashboard/src/components/TreeListingPage/TreeTable.tsx b/dashboard/src/components/TreeListingPage/TreeTable.tsx index 42dfd702b..5be6a8267 100644 --- a/dashboard/src/components/TreeListingPage/TreeTable.tsx +++ b/dashboard/src/components/TreeListingPage/TreeTable.tsx @@ -34,6 +34,7 @@ import { usePaginationState } from '@/hooks/usePaginationState'; import BaseTable, { TableHead } from '@/components/Table/BaseTable'; import { TableBody, TableCell, TableRow } from '@/components/ui/table'; import { ConditionalTableCell } from '@/components/Table/ConditionalTableCell'; +import { FilterLabel } from '@/components/FilterLabel/FilterLabel'; import { BaseGroupedStatusWithLink } from '@/components/Status/Status'; import { TableHeader } from '@/components/Table/TableHeader'; @@ -50,6 +51,7 @@ import QuerySwitcher from '@/components/QuerySwitcher/QuerySwitcher'; import { MemoizedSectionError } from '@/components/DetailsPages/SectionError'; import type { TreeListingRoutesMap } from '@/utils/constants/treeListing'; +import { DEFAULT_TIME_SEARCH } from '@/utils/constants/general'; import { commonTreeTableColumns, @@ -265,7 +267,7 @@ export function TreeTable({ isLoading?: boolean; urlFromMap: TreeListingRoutesMap; }): JSX.Element { - const { origin, listingSize } = useSearch({ + const { origin, listingSize, intervalInDays } = useSearch({ from: urlFromMap.search, }); const navigate = useNavigate({ from: urlFromMap.navigate }); @@ -395,11 +397,16 @@ export function TreeTable({ {tableBody} - +
+ +
+ +
+
); }