@astryxdesign/cli 0.1.4-canary.fd7ab46 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +1 -2
  2. package/docs/getting-started.doc.mjs +0 -4
  3. package/docs/migration.doc.mjs +0 -134
  4. package/docs/styling.doc.mjs +0 -53
  5. package/docs/working-with-ai.doc.mjs +1 -1
  6. package/package.json +10 -15
  7. package/src/api/component.mjs +1 -2
  8. package/src/api/doctor.mjs +2 -13
  9. package/src/api/template.mjs +3 -14
  10. package/src/codemods/__tests__/registry.test.mjs +0 -1
  11. package/src/codemods/__tests__/runner.test.mjs +0 -38
  12. package/src/codemods/registry.mjs +0 -1
  13. package/src/codemods/runner.mjs +0 -2
  14. package/src/commands/agent-docs.mjs +6 -9
  15. package/src/commands/agent-docs.test.mjs +0 -33
  16. package/src/commands/build-theme.mjs +14 -118
  17. package/src/commands/component-resolution.test.mjs +4 -4
  18. package/src/commands/doctor.test.mjs +0 -34
  19. package/src/commands/init.mjs +1 -1
  20. package/src/commands/swizzle.mjs +0 -34
  21. package/src/commands/swizzle.routing.test.mjs +0 -67
  22. package/src/lib/component-discovery.mjs +4 -8
  23. package/templates/blocks/components/AspectRatio/AspectRatioCircleImage.tsx +6 -1
  24. package/templates/blocks/components/AspectRatio/AspectRatioImageGallery.tsx +7 -2
  25. package/templates/blocks/components/AspectRatio/AspectRatioShowcase.tsx +5 -2
  26. package/templates/blocks/components/AspectRatio/AspectRatioSquareImage.tsx +6 -1
  27. package/templates/blocks/components/AspectRatio/AspectRatioWidescreen.tsx +6 -1
  28. package/templates/blocks/components/Collapsible/CollapsibleWithoutCard.tsx +23 -25
  29. package/templates/blocks/components/CommandPaletteGroup/CommandPaletteGroupShowcase.tsx +48 -27
  30. package/templates/blocks/components/CommandPaletteItem/CommandPaletteItemShowcase.tsx +54 -31
  31. package/templates/pages/classic-gallery/page.tsx +1 -1
  32. package/templates/pages/dashboard/page.tsx +1 -1
  33. package/templates/pages/documentation/page.tsx +1 -1
  34. package/templates/pages/kanban-board/page.tsx +13 -37
  35. package/templates/pages/mixed-gallery/page.tsx +1 -1
  36. package/templates/pages/payment-form/page.tsx +6 -2
  37. package/templates/pages/product-detail/page.tsx +11 -3
  38. package/templates/pages/product-gallery/page.tsx +1 -1
  39. package/templates/pages/settings/page.tsx +1 -1
  40. package/templates/pages/side-gallery/page.tsx +1 -1
  41. package/templates/pages/table-page/page.tsx +1 -1
  42. package/templates/pages/table-page-chart/page.tsx +14 -4
  43. package/templates/pages/table-page-heatmap-status/page.tsx +1 -1
  44. package/templates/pages/table-page-shoe-store-heatmap/page.tsx +19 -5
  45. package/src/codemods/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -93
  46. package/src/codemods/transforms/v0.1.5/index.mjs +0 -19
  47. package/src/codemods/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +0 -140
  48. package/src/commands/build-theme.color-scheme.test.mjs +0 -153
  49. package/src/commands/build-theme.variants.test.mjs +0 -193
  50. package/templates/blocks/components/BaseTypeahead/BaseTypeaheadCustomSearch.doc.mjs +0 -14
  51. package/templates/blocks/components/BaseTypeahead/BaseTypeaheadCustomSearch.tsx +0 -58
  52. package/templates/blocks/components/CodeBlock/CodeBlockTerminal.doc.mjs +0 -14
  53. package/templates/blocks/components/CodeBlock/CodeBlockTerminal.tsx +0 -24
  54. package/templates/blocks/components/Collapsible/CollapsibleDividedAccordion.doc.mjs +0 -13
  55. package/templates/blocks/components/Collapsible/CollapsibleDividedAccordion.tsx +0 -33
  56. package/templates/blocks/components/CommandPaletteInput/CommandPaletteInputBasic.doc.mjs +0 -15
  57. package/templates/blocks/components/CommandPaletteInput/CommandPaletteInputBasic.tsx +0 -39
  58. package/templates/blocks/components/CommandPaletteInput/CommandPaletteInputShowcase.doc.mjs +0 -15
  59. package/templates/blocks/components/CommandPaletteInput/CommandPaletteInputShowcase.tsx +0 -39
  60. package/templates/blocks/components/CommandPaletteList/CommandPaletteListBasic.doc.mjs +0 -15
  61. package/templates/blocks/components/CommandPaletteList/CommandPaletteListBasic.tsx +0 -27
  62. package/templates/blocks/components/CommandPaletteList/CommandPaletteListShowcase.doc.mjs +0 -15
  63. package/templates/blocks/components/CommandPaletteList/CommandPaletteListShowcase.tsx +0 -38
  64. package/templates/blocks/components/ContextMenuItem/ContextMenuItemBasic.doc.mjs +0 -14
  65. package/templates/blocks/components/ContextMenuItem/ContextMenuItemBasic.tsx +0 -44
  66. package/templates/blocks/components/ContextMenuItem/ContextMenuItemShowcase.doc.mjs +0 -15
  67. package/templates/blocks/components/ContextMenuItem/ContextMenuItemShowcase.tsx +0 -107
  68. package/templates/blocks/components/NavHeadingMenu/NavHeadingMenuShowcase.doc.mjs +0 -15
  69. package/templates/blocks/components/NavHeadingMenu/NavHeadingMenuShowcase.tsx +0 -47
  70. package/templates/pages/incident-console/page.tsx +0 -580
  71. package/templates/pages/incident-console/template.doc.mjs +0 -12
  72. package/templates/pages/messaging-shell/page.tsx +0 -676
  73. package/templates/pages/messaging-shell/template.doc.mjs +0 -12
@@ -1,580 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- 'use client';
4
-
5
- /**
6
- * Incident Console — an on-call incident response tool.
7
- *
8
- * Frame-first layout (see `npx astryx docs layout`), distilled from
9
- * product-scale apps built with the design system:
10
- *
11
- * Frame: header | grouped incident rows (fill) | inspector 380 (resizable)
12
- *
13
- * Responsive contract:
14
- * > 1024px header | rows | inspector 380
15
- * <= 1024px inspector hidden; rows keep full width
16
- *
17
- * Container policy (tracker archetype): dense data renders as rows —
18
- * edge-to-edge lists grouped by status, zero cards. Status is carried by
19
- * StatusDot (severity) and Token (state), not decorative badges.
20
- */
21
-
22
- import {useMemo, useState, type CSSProperties} from 'react';
23
-
24
- import {
25
- HStack,
26
- Layout,
27
- LayoutContent,
28
- LayoutHeader,
29
- StackItem,
30
- VStack,
31
- } from '@astryxdesign/core/Layout';
32
- import {ResizeHandle, useResizable} from '@astryxdesign/core/Resizable';
33
- import {LayoutPanel} from '@astryxdesign/core/Layout';
34
- import {Heading, Text} from '@astryxdesign/core/Text';
35
- import {Button} from '@astryxdesign/core/Button';
36
- import {Icon} from '@astryxdesign/core/Icon';
37
- import {Divider} from '@astryxdesign/core/Divider';
38
- import {EmptyState} from '@astryxdesign/core/EmptyState';
39
- import {List, ListItem} from '@astryxdesign/core/List';
40
- import {MetadataList, MetadataListItem} from '@astryxdesign/core/MetadataList';
41
- import {
42
- PowerSearch,
43
- usePowerSearchConfig,
44
- } from '@astryxdesign/core/PowerSearch';
45
- import type {PowerSearchFilter} from '@astryxdesign/core/PowerSearch';
46
- import {
47
- SegmentedControl,
48
- SegmentedControlItem,
49
- } from '@astryxdesign/core/SegmentedControl';
50
- import {StatusDot} from '@astryxdesign/core/StatusDot';
51
- import {Timestamp} from '@astryxdesign/core/Timestamp';
52
- import {Token} from '@astryxdesign/core/Token';
53
- import {useMediaQuery} from '@astryxdesign/core/hooks';
54
- import {BellAlertIcon, PlusIcon} from '@heroicons/react/24/outline';
55
-
56
- const styles: Record<string, CSSProperties> = {
57
- contentFill: {
58
- height: '100%',
59
- minHeight: 0,
60
- },
61
- searchRow: {
62
- padding: 'var(--spacing-3)',
63
- },
64
- groupHeader: {
65
- padding: 'var(--spacing-2) var(--spacing-3)',
66
- backgroundColor: 'var(--color-background-muted)',
67
- },
68
- rows: {
69
- overflowY: 'auto',
70
- minHeight: 0,
71
- },
72
- inspector: {
73
- padding: 'var(--spacing-4)',
74
- height: '100%',
75
- overflowY: 'auto',
76
- },
77
- };
78
-
79
- type Severity = 'sev1' | 'sev2' | 'sev3';
80
- type Status = 'investigating' | 'mitigated' | 'resolved';
81
-
82
- interface TimelineEvent {
83
- at: string;
84
- label: string;
85
- detail: string;
86
- }
87
-
88
- interface Incident extends Record<string, unknown> {
89
- id: string;
90
- title: string;
91
- service: string;
92
- severity: Severity;
93
- status: Status;
94
- commander: string;
95
- startedAt: string;
96
- impact: string;
97
- timeline: TimelineEvent[];
98
- }
99
-
100
- // Deterministic fixtures: fixed ISO timestamps, no clocks, no randomness.
101
- const INCIDENTS: Incident[] = [
102
- {
103
- id: 'INC-2417',
104
- title: 'Checkout API elevated 5xx rate',
105
- service: 'checkout-api',
106
- severity: 'sev1',
107
- status: 'investigating',
108
- commander: 'Priya Raman',
109
- startedAt: '2026-06-30T21:14:00Z',
110
- impact: '12% of checkout requests failing in us-east',
111
- timeline: [
112
- {
113
- at: '2026-06-30T21:14:00Z',
114
- label: 'Incident declared',
115
- detail: 'Paging monitor: checkout-api 5xx > 5% for 10m',
116
- },
117
- {
118
- at: '2026-06-30T21:19:00Z',
119
- label: 'Commander assigned',
120
- detail: 'Priya Raman took command',
121
- },
122
- {
123
- at: '2026-06-30T21:31:00Z',
124
- label: 'Suspect identified',
125
- detail: 'Deploy 8f31c2 correlates with error onset',
126
- },
127
- ],
128
- },
129
- {
130
- id: 'INC-2416',
131
- title: 'Search indexing lag above 30 minutes',
132
- service: 'search-indexer',
133
- severity: 'sev2',
134
- status: 'investigating',
135
- commander: 'Marcus Webb',
136
- startedAt: '2026-06-30T19:42:00Z',
137
- impact: 'New listings not searchable; stale results served',
138
- timeline: [
139
- {
140
- at: '2026-06-30T19:42:00Z',
141
- label: 'Incident declared',
142
- detail: 'Indexing lag alarm crossed 30m threshold',
143
- },
144
- {
145
- at: '2026-06-30T20:05:00Z',
146
- label: 'Mitigation attempted',
147
- detail: 'Doubled indexer worker pool; lag still climbing',
148
- },
149
- ],
150
- },
151
- {
152
- id: 'INC-2415',
153
- title: 'Webhook delivery retries exhausting queue',
154
- service: 'webhooks',
155
- severity: 'sev3',
156
- status: 'investigating',
157
- commander: 'Ana Duarte',
158
- startedAt: '2026-06-30T18:20:00Z',
159
- impact: 'Third-party webhook delivery delayed up to 15m',
160
- timeline: [
161
- {
162
- at: '2026-06-30T18:20:00Z',
163
- label: 'Incident declared',
164
- detail: 'Queue depth alarm on webhook-delivery',
165
- },
166
- ],
167
- },
168
- {
169
- id: 'INC-2414',
170
- title: 'Payments settlement job stalled',
171
- service: 'payments',
172
- severity: 'sev1',
173
- status: 'mitigated',
174
- commander: 'Priya Raman',
175
- startedAt: '2026-06-30T14:03:00Z',
176
- impact: 'Settlement batch delayed; no customer-visible impact',
177
- timeline: [
178
- {
179
- at: '2026-06-30T14:03:00Z',
180
- label: 'Incident declared',
181
- detail: 'Settlement job heartbeat missed twice',
182
- },
183
- {
184
- at: '2026-06-30T14:26:00Z',
185
- label: 'Mitigated',
186
- detail: 'Job restarted on standby worker; batch draining',
187
- },
188
- ],
189
- },
190
- {
191
- id: 'INC-2413',
192
- title: 'CDN cache hit ratio degraded in eu-west',
193
- service: 'edge-cdn',
194
- severity: 'sev2',
195
- status: 'mitigated',
196
- commander: 'Tom Okafor',
197
- startedAt: '2026-06-30T11:47:00Z',
198
- impact: 'Origin load 3x baseline; p95 latency +180ms in EU',
199
- timeline: [
200
- {
201
- at: '2026-06-30T11:47:00Z',
202
- label: 'Incident declared',
203
- detail: 'Cache hit ratio dropped below 80%',
204
- },
205
- {
206
- at: '2026-06-30T12:12:00Z',
207
- label: 'Mitigated',
208
- detail: 'Rolled back cache-key config change',
209
- },
210
- ],
211
- },
212
- {
213
- id: 'INC-2412',
214
- title: 'Login rate limiting misfiring for SSO users',
215
- service: 'auth',
216
- severity: 'sev2',
217
- status: 'resolved',
218
- commander: 'Ana Duarte',
219
- startedAt: '2026-06-29T22:31:00Z',
220
- impact: 'SSO users intermittently blocked at login',
221
- timeline: [
222
- {
223
- at: '2026-06-29T22:31:00Z',
224
- label: 'Incident declared',
225
- detail: 'Support surge: SSO login failures',
226
- },
227
- {
228
- at: '2026-06-29T23:02:00Z',
229
- label: 'Mitigated',
230
- detail: 'Raised limiter threshold for SSO IdP ranges',
231
- },
232
- {
233
- at: '2026-06-30T09:15:00Z',
234
- label: 'Resolved',
235
- detail: 'Limiter keying fixed to per-user; monitors green 8h',
236
- },
237
- ],
238
- },
239
- {
240
- id: 'INC-2411',
241
- title: 'Notification digests sent twice',
242
- service: 'notifications',
243
- severity: 'sev3',
244
- status: 'resolved',
245
- commander: 'Marcus Webb',
246
- startedAt: '2026-06-29T08:12:00Z',
247
- impact: 'Duplicate daily digest for ~40k users',
248
- timeline: [
249
- {
250
- at: '2026-06-29T08:12:00Z',
251
- label: 'Incident declared',
252
- detail: 'Duplicate-send reports from support',
253
- },
254
- {
255
- at: '2026-06-29T10:40:00Z',
256
- label: 'Resolved',
257
- detail: 'Dedup key restored in scheduler; backfill verified',
258
- },
259
- ],
260
- },
261
- ];
262
-
263
- const STATUS_ORDER: Status[] = ['investigating', 'mitigated', 'resolved'];
264
-
265
- const STATUS_LABEL: Record<Status, string> = {
266
- investigating: 'Investigating',
267
- mitigated: 'Mitigated',
268
- resolved: 'Resolved',
269
- };
270
-
271
- const STATUS_TOKEN_COLOR: Record<Status, 'red' | 'yellow' | 'green'> = {
272
- investigating: 'red',
273
- mitigated: 'yellow',
274
- resolved: 'green',
275
- };
276
-
277
- const SEVERITY_DOT: Record<Severity, 'error' | 'warning' | 'neutral'> = {
278
- sev1: 'error',
279
- sev2: 'warning',
280
- sev3: 'neutral',
281
- };
282
-
283
- const SERVICE_VALUES = [
284
- {value: 'checkout-api', label: 'checkout-api'},
285
- {value: 'search-indexer', label: 'search-indexer'},
286
- {value: 'webhooks', label: 'webhooks'},
287
- {value: 'payments', label: 'payments'},
288
- {value: 'edge-cdn', label: 'edge-cdn'},
289
- {value: 'auth', label: 'auth'},
290
- {value: 'notifications', label: 'notifications'},
291
- ];
292
-
293
- const SEVERITY_VALUES = [
294
- {value: 'sev1', label: 'SEV1'},
295
- {value: 'sev2', label: 'SEV2'},
296
- {value: 'sev3', label: 'SEV3'},
297
- ];
298
-
299
- const fieldDefs = [
300
- {key: 'title', type: 'string', label: 'Title'},
301
- {key: 'service', type: 'enum', label: 'Service', enumValues: SERVICE_VALUES},
302
- {
303
- key: 'severity',
304
- type: 'enum',
305
- label: 'Severity',
306
- enumValues: SEVERITY_VALUES,
307
- },
308
- {key: 'commander', type: 'string', label: 'Commander'},
309
- ] as const;
310
-
311
- function IncidentRows({
312
- incidents,
313
- selectedId,
314
- onSelect,
315
- }: {
316
- incidents: Incident[];
317
- selectedId: string | null;
318
- onSelect: (id: string) => void;
319
- }) {
320
- const groups = STATUS_ORDER.map(status => ({
321
- status,
322
- items: incidents.filter(incident => incident.status === status),
323
- })).filter(group => group.items.length > 0);
324
-
325
- if (groups.length === 0) {
326
- return (
327
- <EmptyState
328
- title="No matching incidents"
329
- description="Adjust the status filter or clear search filters."
330
- icon={<Icon icon={BellAlertIcon} size="lg" />}
331
- />
332
- );
333
- }
334
-
335
- return (
336
- <VStack gap={0}>
337
- {groups.map(group => (
338
- <VStack gap={0} key={group.status}>
339
- <HStack gap={2} vAlign="center" style={styles.groupHeader}>
340
- <Text type="label" color="secondary">
341
- {STATUS_LABEL[group.status]}
342
- </Text>
343
- <Text type="supporting" color="secondary">
344
- {group.items.length}
345
- </Text>
346
- </HStack>
347
- <List density="compact" hasDividers>
348
- {group.items.map(incident => (
349
- <ListItem
350
- key={incident.id}
351
- label={incident.title}
352
- description={`${incident.id} · ${incident.service} · ${incident.impact}`}
353
- startContent={
354
- <StatusDot
355
- variant={SEVERITY_DOT[incident.severity]}
356
- label={incident.severity.toUpperCase()}
357
- isPulsing={
358
- incident.severity === 'sev1' &&
359
- incident.status === 'investigating'
360
- }
361
- />
362
- }
363
- endContent={
364
- <HStack gap={3} vAlign="center">
365
- <Token
366
- size="sm"
367
- color={STATUS_TOKEN_COLOR[incident.status]}
368
- label={STATUS_LABEL[incident.status]}
369
- />
370
- <Timestamp
371
- value={incident.startedAt}
372
- format="relative"
373
- color="secondary"
374
- />
375
- </HStack>
376
- }
377
- onClick={() => onSelect(incident.id)}
378
- isSelected={incident.id === selectedId}
379
- />
380
- ))}
381
- </List>
382
- </VStack>
383
- ))}
384
- </VStack>
385
- );
386
- }
387
-
388
- function IncidentInspector({incident}: {incident: Incident}) {
389
- const nextAction =
390
- incident.status === 'investigating'
391
- ? 'Mark mitigated'
392
- : incident.status === 'mitigated'
393
- ? 'Resolve'
394
- : 'Reopen';
395
-
396
- return (
397
- <VStack gap={4} style={styles.inspector}>
398
- <VStack gap={2}>
399
- <HStack gap={2} vAlign="center">
400
- <StatusDot
401
- variant={SEVERITY_DOT[incident.severity]}
402
- label={incident.severity.toUpperCase()}
403
- />
404
- <Text type="supporting" color="secondary">
405
- {incident.id}
406
- </Text>
407
- <Token
408
- size="sm"
409
- color={STATUS_TOKEN_COLOR[incident.status]}
410
- label={STATUS_LABEL[incident.status]}
411
- />
412
- </HStack>
413
- <Heading level={2}>{incident.title}</Heading>
414
- </VStack>
415
-
416
- <HStack gap={2}>
417
- <Button label={nextAction} size="sm" />
418
- <Button label="Escalate" variant="secondary" size="sm" />
419
- </HStack>
420
-
421
- <Divider />
422
-
423
- <MetadataList columns="single" label={{position: 'start', width: 96}}>
424
- <MetadataListItem label="Service">
425
- <Text type="body">{incident.service}</Text>
426
- </MetadataListItem>
427
- <MetadataListItem label="Severity">
428
- <Text type="body">{incident.severity.toUpperCase()}</Text>
429
- </MetadataListItem>
430
- <MetadataListItem label="Commander">
431
- <Text type="body">{incident.commander}</Text>
432
- </MetadataListItem>
433
- <MetadataListItem label="Started">
434
- <Timestamp value={incident.startedAt} format="date_time" />
435
- </MetadataListItem>
436
- <MetadataListItem label="Impact">
437
- <Text type="body">{incident.impact}</Text>
438
- </MetadataListItem>
439
- </MetadataList>
440
-
441
- <Divider />
442
-
443
- <VStack gap={2}>
444
- <Heading level={3}>Timeline</Heading>
445
- <List density="compact">
446
- {incident.timeline.map(event => (
447
- <ListItem
448
- key={`${event.at}-${event.label}`}
449
- label={event.label}
450
- description={event.detail}
451
- endContent={
452
- <Timestamp value={event.at} format="time" color="secondary" />
453
- }
454
- />
455
- ))}
456
- </List>
457
- </VStack>
458
- </VStack>
459
- );
460
- }
461
-
462
- export default function IncidentConsolePage() {
463
- const [statusFilter, setStatusFilter] = useState('all');
464
- const [filters, setFilters] = useState<PowerSearchFilter[]>([]);
465
- const [selectedId, setSelectedId] = useState<string | null>(INCIDENTS[0].id);
466
- const {config, applyFilters} = usePowerSearchConfig(fieldDefs, 'Incidents');
467
-
468
- // Responsive contract: the inspector is hidden at <= 1024px so the row
469
- // list keeps its full width (never compress dense rows).
470
- const isNarrow = useMediaQuery('(max-width: 1024px)');
471
-
472
- const inspectorPanel = useResizable({
473
- defaultSize: 380,
474
- minSizePx: 320,
475
- maxSizePx: 480,
476
- });
477
-
478
- const visible = useMemo(() => {
479
- const searched = applyFilters(filters, INCIDENTS);
480
- return statusFilter === 'all'
481
- ? searched
482
- : searched.filter(incident => incident.status === statusFilter);
483
- }, [filters, applyFilters, statusFilter]);
484
-
485
- const selected = visible.find(incident => incident.id === selectedId) ?? null;
486
-
487
- const openCount = INCIDENTS.filter(
488
- incident => incident.status === 'investigating',
489
- ).length;
490
-
491
- return (
492
- <Layout
493
- height="fill"
494
- header={
495
- <LayoutHeader hasDivider>
496
- <HStack gap={3} vAlign="center">
497
- <StackItem size="fill">
498
- <HStack gap={2} vAlign="center">
499
- <Heading level={1}>Incidents</Heading>
500
- <Text type="supporting" color="secondary">
501
- {openCount} investigating
502
- </Text>
503
- </HStack>
504
- </StackItem>
505
- <SegmentedControl
506
- label="Filter by status"
507
- value={statusFilter}
508
- onChange={setStatusFilter}
509
- size="sm">
510
- <SegmentedControlItem label="All" value="all" />
511
- <SegmentedControlItem
512
- label="Investigating"
513
- value="investigating"
514
- />
515
- <SegmentedControlItem label="Mitigated" value="mitigated" />
516
- <SegmentedControlItem label="Resolved" value="resolved" />
517
- </SegmentedControl>
518
- <Button
519
- label="Declare incident"
520
- icon={<Icon icon={PlusIcon} size="sm" />}
521
- size="sm"
522
- />
523
- </HStack>
524
- </LayoutHeader>
525
- }
526
- content={
527
- <LayoutContent padding={0}>
528
- <VStack gap={0} style={styles.contentFill}>
529
- <HStack style={styles.searchRow}>
530
- <StackItem size="fill">
531
- <PowerSearch
532
- config={config}
533
- filters={filters}
534
- onChange={newFilters => setFilters([...newFilters])}
535
- placeholder="Search incidents..."
536
- resultCount={visible.length}
537
- />
538
- </StackItem>
539
- </HStack>
540
- <StackItem size="fill" style={styles.rows}>
541
- <IncidentRows
542
- incidents={visible}
543
- selectedId={selected?.id ?? null}
544
- onSelect={setSelectedId}
545
- />
546
- </StackItem>
547
- </VStack>
548
- </LayoutContent>
549
- }
550
- end={
551
- isNarrow ? undefined : (
552
- <>
553
- <ResizeHandle
554
- direction="horizontal"
555
- hasDivider
556
- isAlwaysVisible={false}
557
- resizable={inspectorPanel.props}
558
- label="Resize inspector"
559
- />
560
- <LayoutPanel
561
- width={inspectorPanel.size}
562
- padding={0}
563
- label="Incident details">
564
- {selected ? (
565
- <IncidentInspector incident={selected} />
566
- ) : (
567
- <EmptyState
568
- title="No incident selected"
569
- description="Select an incident to see details and timeline."
570
- icon={<Icon icon={BellAlertIcon} size="lg" />}
571
- isCompact
572
- />
573
- )}
574
- </LayoutPanel>
575
- </>
576
- )
577
- }
578
- />
579
- );
580
- }
@@ -1,12 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /** @type {import('../../../../core/src/docs-types').TemplateDoc} */
4
- export const doc = {
5
- type: 'page',
6
- name: 'Incident Console',
7
- displayName: 'Incident Console',
8
- description:
9
- 'On-call incident response console: grouped dense incident rows with severity dots, PowerSearch filtering, status segmented control, and a resizable inspector panel with metadata and timeline. Frame-first tracker archetype: rows, not cards.',
10
- isReady: false,
11
- category: 'Tools - Incident Console',
12
- };