@@ -3,15 +3,17 @@ import { Suspense } from "react";
33
44import { getAllProviders } from "@/actions/providers" ;
55import { getScans } from "@/actions/scans" ;
6- import { getSchedules } from "@/actions/schedules" ;
6+ import { getSchedules , getSchedulesPage } from "@/actions/schedules" ;
77import { auth } from "@/auth.config" ;
88import { PageReady } from "@/components/onboarding" ;
99import {
1010 appendPendingScheduleRowsToPage ,
11+ buildScheduledTabRows ,
1112 getProviderIdsFromScans ,
1213 getScanJobsTab ,
1314 getScanJobsTabFilters ,
1415 getScanJobsUserFilters ,
16+ pickScheduleProviderFilters ,
1517} from "@/components/scans/scans.utils" ;
1618import { ScansPageShell } from "@/components/scans/scans-page-shell" ;
1719import { ScansProvidersEmptyState } from "@/components/scans/scans-providers-empty-state" ;
@@ -21,35 +23,41 @@ import { ContentLayout } from "@/components/ui";
2123import {
2224 buildProviderScheduleSummary ,
2325 buildSchedulesByProviderId ,
26+ getScanScheduleCapability ,
2427 isScheduleConfigured ,
2528} from "@/lib/schedules" ;
29+ import { isCloud } from "@/lib/shared/env" ;
2630import {
31+ FilterType ,
2732 ProviderProps ,
2833 SCAN_JOBS_TAB ,
2934 SCAN_TRIGGER ,
3035 ScanProps ,
3136 SearchParamsProps ,
3237} from "@/types" ;
33- import type { ScanScheduleCapability } from "@/types/schedules" ;
38+ import {
39+ SCAN_SCHEDULE_CAPABILITY ,
40+ type ScanScheduleCapability ,
41+ } from "@/types/schedules" ;
3442
3543const ACTIVE_SCAN_COUNT_PAGE_SIZE = 1 ;
36- // Pending schedule rows are derived from provider schedules, but must honor the
37- // same provider filters as real scan rows. Keep these filter keys typed locally
38- // without narrowing the global SearchParamsProps shape used by Next pages .
44+ // Pending schedule rows must honor the same provider filters as real scan rows.
45+ // The `__in` keys reuse the shared FilterType; the singular variants have no
46+ // FilterType equivalent, so they stay as literals .
3947const PENDING_ROW_PROVIDER_FILTER = {
40- PROVIDER_UID_IN : "provider_uid__in" ,
41- PROVIDER_UID : "provider_uid " ,
42- PROVIDER_TYPE_IN : "provider_type__in" ,
48+ PROVIDER_IN : FilterType . PROVIDER ,
49+ PROVIDER : "provider " ,
50+ PROVIDER_TYPE_IN : FilterType . PROVIDER_TYPE ,
4351 PROVIDER_TYPE : "provider_type" ,
4452} as const ;
4553
4654type PendingRowProviderFilter =
4755 ( typeof PENDING_ROW_PROVIDER_FILTER ) [ keyof typeof PENDING_ROW_PROVIDER_FILTER ] ;
4856type PendingRowProviderFilterParam = `filter[${PendingRowProviderFilter } ]`;
4957
50- const PROVIDER_UID_FILTER_KEYS = [
51- `filter[${ PENDING_ROW_PROVIDER_FILTER . PROVIDER_UID_IN } ]` ,
52- `filter[${ PENDING_ROW_PROVIDER_FILTER . PROVIDER_UID } ]` ,
58+ const PROVIDER_ID_FILTER_KEYS = [
59+ `filter[${ PENDING_ROW_PROVIDER_FILTER . PROVIDER_IN } ]` ,
60+ `filter[${ PENDING_ROW_PROVIDER_FILTER . PROVIDER } ]` ,
5361] as const satisfies ReadonlyArray < PendingRowProviderFilterParam > ;
5462
5563const PROVIDER_TYPE_FILTER_KEYS = [
@@ -93,16 +101,16 @@ const filterProvidersForPendingRows = (
93101 providers : ProviderProps [ ] ,
94102 searchParams : SearchParamsProps ,
95103) : ProviderProps [ ] => {
96- const uids = parseCsvParam (
97- getFirstSearchParam ( searchParams , PROVIDER_UID_FILTER_KEYS ) ,
104+ const ids = parseCsvParam (
105+ getFirstSearchParam ( searchParams , PROVIDER_ID_FILTER_KEYS ) ,
98106 ) ;
99107 const types = parseCsvParam (
100108 getFirstSearchParam ( searchParams , PROVIDER_TYPE_FILTER_KEYS ) ,
101109 ) ;
102110
103111 return providers . filter (
104112 ( provider ) =>
105- ( uids . length === 0 || uids . includes ( provider . attributes . uid ) ) &&
113+ ( ids . length === 0 || ids . includes ( provider . id ) ) &&
106114 ( types . length === 0 || types . includes ( provider . attributes . provider ) ) ,
107115 ) ;
108116} ;
@@ -272,6 +280,33 @@ const SSRDataTableScans = async ({
272280
273281 const query = ( filters [ "filter[search]" ] as string ) || "" ;
274282
283+ // Advanced (Cloud) sources the Scheduled tab from /schedules; other envs keep the legacy /scans path.
284+ const capability =
285+ scanScheduleCapability ?? getScanScheduleCapability ( isCloud ( ) ) ;
286+
287+ if (
288+ tab === SCAN_JOBS_TAB . SCHEDULED &&
289+ capability === SCAN_SCHEDULE_CAPABILITY . ADVANCED
290+ ) {
291+ const schedulesPage = await getSchedulesPage ( {
292+ page,
293+ pageSize,
294+ sort,
295+ filters : pickScheduleProviderFilters ( searchParams ) ,
296+ } ) ;
297+ const { data, meta } = buildScheduledTabRows ( schedulesPage , new Date ( ) ) ;
298+
299+ return (
300+ < ScanJobsTable
301+ data = { data }
302+ meta = { meta }
303+ tab = { tab }
304+ hasFilters = { hasUserFilters }
305+ scanScheduleCapability = { capability }
306+ />
307+ ) ;
308+ }
309+
275310 const scansData = await getScans ( {
276311 query,
277312 page,
0 commit comments