@@ -16,6 +16,7 @@ import AdminPage from '@/app/admin/components/AdminPage';
1616import {
1717 useCloudAgentNextHealthErrorSessions ,
1818 useCloudAgentNextHealthOverview ,
19+ useCloudAgentNextHealthPlatforms ,
1920 type CloudAgentNextHealthFilters ,
2021} from '@/app/admin/api/cloud-agent-next/hooks' ;
2122import { CopyButton } from '@/components/admin/CopyButton' ;
@@ -88,6 +89,23 @@ type TopError = HealthData['topErrors'][number];
8889type TooltipPayload = { payload : SeriesPoint } ;
8990
9091const DEFAULT_RANGE : RangeValue = DEFAULT_HEALTH_PERIOD ;
92+ const ALL_PLATFORMS_VALUE = 'all-platforms' ;
93+ const UNKNOWN_PLATFORM_VALUE = 'unknown-platform' ;
94+ const EXACT_PLATFORM_PREFIX = 'platform:' ;
95+
96+ function platformSelectionValue ( platform : string ) : string {
97+ return `${ EXACT_PLATFORM_PREFIX } ${ platform } ` ;
98+ }
99+
100+ function createdOnPlatformForSelection ( selection : string ) : string | null | undefined {
101+ if ( selection === ALL_PLATFORMS_VALUE ) return undefined ;
102+ if ( selection === UNKNOWN_PLATFORM_VALUE ) return null ;
103+ if ( selection . startsWith ( EXACT_PLATFORM_PREFIX ) ) {
104+ return selection . slice ( EXACT_PLATFORM_PREFIX . length ) ;
105+ }
106+ return undefined ;
107+ }
108+
91109const utcLongLabel = new Intl . DateTimeFormat ( 'en-US' , {
92110 timeZone : 'UTC' ,
93111 month : 'short' ,
@@ -107,15 +125,20 @@ const utcShortDay = new Intl.DateTimeFormat('en-US', {
107125 day : 'numeric' ,
108126} ) ;
109127
110- function intervalForRange ( range : RangeValue ) : CloudAgentNextHealthFilters {
128+ function intervalForRange (
129+ range : RangeValue ,
130+ platformSelection = ALL_PLATFORMS_VALUE
131+ ) : CloudAgentNextHealthFilters {
111132 const selectedRange = RANGE_OPTIONS . find ( option => option . value === range ) ?? RANGE_OPTIONS [ 3 ] ;
133+ const createdOnPlatform = createdOnPlatformForSelection ( platformSelection ) ;
112134 const end = new Date ( ) ;
113135 if ( selectedRange . bucket === 'day' ) end . setUTCHours ( 0 , 0 , 0 , 0 ) ;
114136 else end . setUTCMinutes ( 0 , 0 , 0 ) ;
115137 return {
116138 startDate : new Date ( end . getTime ( ) - selectedRange . durationMs ) . toISOString ( ) ,
117139 endDate : end . toISOString ( ) ,
118140 bucket : selectedRange . bucket ,
141+ ...( createdOnPlatform === undefined ? { } : { createdOnPlatform } ) ,
119142 } ;
120143}
121144
@@ -565,8 +588,10 @@ function TopErrors({
565588
566589export default function CloudAgentNextOutcomesPage ( ) {
567590 const [ range , setRange ] = useState < RangeValue > ( DEFAULT_RANGE ) ;
591+ const [ platformSelection , setPlatformSelection ] = useState ( ALL_PLATFORMS_VALUE ) ;
568592 const [ interval , setInterval ] = useState ( ( ) => intervalForRange ( DEFAULT_RANGE ) ) ;
569593 const [ hasLoadedPeriodPreference , setHasLoadedPeriodPreference ] = useState ( false ) ;
594+ const healthPlatforms = useCloudAgentNextHealthPlatforms ( ) ;
570595 const health = useCloudAgentNextHealthOverview ( interval , hasLoadedPeriodPreference ) ;
571596 const bucket = interval . bucket ;
572597
@@ -583,15 +608,21 @@ export default function CloudAgentNextOutcomesPage() {
583608 if ( ! isHealthPeriod ( value ) ) return ;
584609 setStoredHealthPeriod ( value ) ;
585610 setRange ( value ) ;
586- setInterval ( intervalForRange ( value ) ) ;
611+ setInterval ( intervalForRange ( value , platformSelection ) ) ;
612+ }
613+
614+ function updatePlatformSelection ( value : string ) {
615+ setPlatformSelection ( value ) ;
616+ setInterval ( intervalForRange ( range , value ) ) ;
587617 }
588618
589619 function refresh ( ) {
590- const nextInterval = intervalForRange ( range ) ;
620+ const nextInterval = intervalForRange ( range , platformSelection ) ;
591621 if (
592622 nextInterval . startDate === interval . startDate &&
593623 nextInterval . endDate === interval . endDate &&
594- nextInterval . bucket === interval . bucket
624+ nextInterval . bucket === interval . bucket &&
625+ nextInterval . createdOnPlatform === interval . createdOnPlatform
595626 ) {
596627 void health . refetch ( ) ;
597628 return ;
@@ -620,20 +651,49 @@ export default function CloudAgentNextOutcomesPage() {
620651 Operational outcome trends from best-effort Cloud Agent reporting.
621652 </ p >
622653 </ div >
623- < div className = "flex min-w-60 flex-col gap-2" >
624- < Label htmlFor = "cloud-agent-health-period" > Period</ Label >
625- < Select value = { range } onValueChange = { updateRange } >
626- < SelectTrigger id = "cloud-agent-health-period" className = "w-full" >
627- < SelectValue />
628- </ SelectTrigger >
629- < SelectContent >
630- { RANGE_OPTIONS . map ( option => (
631- < SelectItem key = { option . value } value = { option . value } >
632- { option . label }
633- </ SelectItem >
634- ) ) }
635- </ SelectContent >
636- </ Select >
654+ < div className = "grid w-full gap-3 sm:grid-cols-2 md:w-auto md:min-w-[32rem]" >
655+ < div className = "flex flex-col gap-2" >
656+ < Label htmlFor = "cloud-agent-health-period" > Period</ Label >
657+ < Select value = { range } onValueChange = { updateRange } >
658+ < SelectTrigger id = "cloud-agent-health-period" className = "w-full" >
659+ < SelectValue />
660+ </ SelectTrigger >
661+ < SelectContent >
662+ { RANGE_OPTIONS . map ( option => (
663+ < SelectItem key = { option . value } value = { option . value } >
664+ { option . label }
665+ </ SelectItem >
666+ ) ) }
667+ </ SelectContent >
668+ </ Select >
669+ </ div >
670+ < div className = "flex flex-col gap-2" >
671+ < Label htmlFor = "cloud-agent-health-platform" > Created on platform</ Label >
672+ < Select value = { platformSelection } onValueChange = { updatePlatformSelection } >
673+ < SelectTrigger id = "cloud-agent-health-platform" className = "w-full" >
674+ < SelectValue />
675+ </ SelectTrigger >
676+ < SelectContent >
677+ < SelectItem value = { ALL_PLATFORMS_VALUE } > All platforms</ SelectItem >
678+ { healthPlatforms . isLoading && (
679+ < SelectItem value = "loading-platforms" disabled >
680+ Loading platforms...
681+ </ SelectItem >
682+ ) }
683+ { healthPlatforms . error && (
684+ < SelectItem value = "platforms-unavailable" disabled >
685+ Platforms unavailable
686+ </ SelectItem >
687+ ) }
688+ { healthPlatforms . data ?. map ( platform => (
689+ < SelectItem key = { platform } value = { platformSelectionValue ( platform ) } >
690+ < span className = "font-mono text-xs" > { platform } </ span >
691+ </ SelectItem >
692+ ) ) }
693+ < SelectItem value = { UNKNOWN_PLATFORM_VALUE } > Unknown / unlinked</ SelectItem >
694+ </ SelectContent >
695+ </ Select >
696+ </ div >
637697 </ div >
638698 </ div >
639699 < p className = "text-muted-foreground text-xs" >
0 commit comments