@sentry/junior-dashboard 0.263.0 → 0.265.0

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 (197) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +2 -5
  3. package/dist/app.js +119 -35
  4. package/dist/client.js +148 -135
  5. package/dist/index.d.ts +0 -1
  6. package/dist/index.js +119 -35
  7. package/dist/tailwind.css +1 -1
  8. package/package.json +9 -4
  9. package/src/api/schema.ts +0 -1
  10. package/src/app.ts +5 -20
  11. package/src/client/App.tsx +29 -31
  12. package/src/client/api.ts +7 -0
  13. package/src/client/components/BottomSheet.tsx +26 -18
  14. package/src/client/components/CopyButton.tsx +83 -0
  15. package/src/client/components/DetailsPanel.tsx +133 -0
  16. package/src/client/components/Drawer.tsx +34 -33
  17. package/src/client/components/FilterBar.tsx +16 -31
  18. package/src/client/components/Metric.tsx +33 -23
  19. package/src/client/components/PageContentSkeleton.tsx +1 -1
  20. package/src/client/components/Pagination.tsx +1 -1
  21. package/src/client/components/ParticipantAvatarStack.tsx +40 -36
  22. package/src/client/components/ProfileMenu.tsx +27 -93
  23. package/src/client/components/README.md +101 -64
  24. package/src/client/components/SegmentedNav.tsx +1 -1
  25. package/src/client/components/ShimmerText.tsx +2 -6
  26. package/src/client/components/ThemeSwitcher.tsx +19 -15
  27. package/src/client/components/charts/ActivityChart.tsx +173 -288
  28. package/src/client/components/charts/CacheWrites.tsx +63 -50
  29. package/src/client/components/charts/InputCacheChart.tsx +137 -131
  30. package/src/client/components/charts/README.md +4 -4
  31. package/src/client/components/charts/SystemMetricCharts.tsx +68 -95
  32. package/src/client/components/charts/WorkspaceUsageChart.tsx +42 -62
  33. package/src/client/components/controls/DirectorySortSelect.tsx +3 -3
  34. package/src/client/components/controls/TimeRangeSelector.tsx +10 -15
  35. package/src/client/components/layout/DashboardHeader.tsx +44 -90
  36. package/src/client/components/layout/SecondaryNavigation.tsx +2 -1
  37. package/src/client/components/layout/VisualViewportShell.tsx +2 -2
  38. package/src/client/components/ui/accordion.tsx +77 -0
  39. package/src/client/components/ui/alert-dialog.tsx +89 -0
  40. package/src/client/components/ui/button.tsx +85 -0
  41. package/src/client/components/ui/chart.tsx +74 -0
  42. package/src/client/components/ui/checkbox.tsx +26 -0
  43. package/src/client/components/ui/collapsible.tsx +22 -0
  44. package/src/client/components/ui/field.tsx +49 -0
  45. package/src/client/components/ui/input.tsx +35 -0
  46. package/src/client/components/ui/native-select.tsx +57 -0
  47. package/src/client/components/ui/popover.tsx +67 -0
  48. package/src/client/components/ui/radio-group.tsx +32 -0
  49. package/src/client/components/ui/sheet.tsx +151 -0
  50. package/src/client/components/ui/skeleton.tsx +19 -0
  51. package/src/client/components/ui/table.tsx +80 -0
  52. package/src/client/components/ui/tabs.tsx +75 -0
  53. package/src/client/components/ui/textarea.tsx +17 -0
  54. package/src/client/components/ui/toast.tsx +215 -0
  55. package/src/client/components/ui/toggle-group.tsx +36 -0
  56. package/src/client/components/ui/toggle.tsx +37 -0
  57. package/src/client/components/ui/tooltip.tsx +168 -0
  58. package/src/client/components/ui/trace.tsx +96 -0
  59. package/src/client/components/ui/useSheet.ts +74 -0
  60. package/src/client/conversations/ChatLayout.tsx +7 -3
  61. package/src/client/conversations/ConversationBrief.tsx +17 -6
  62. package/src/client/conversations/ConversationChildAgents.tsx +87 -58
  63. package/src/client/conversations/ConversationComposer.tsx +26 -12
  64. package/src/client/conversations/ConversationDetails.tsx +198 -95
  65. package/src/client/conversations/ConversationEventDetails.tsx +141 -0
  66. package/src/client/conversations/ConversationEventLog.tsx +150 -129
  67. package/src/client/conversations/ConversationHeader.tsx +8 -3
  68. package/src/client/conversations/ConversationHeaderActions.tsx +90 -82
  69. package/src/client/conversations/ConversationHomeList.tsx +1 -1
  70. package/src/client/conversations/ConversationLinkedWork.tsx +118 -0
  71. package/src/client/conversations/ConversationMeta.tsx +111 -92
  72. package/src/client/conversations/ConversationPage.tsx +241 -110
  73. package/src/client/conversations/ConversationSidebar.tsx +48 -29
  74. package/src/client/conversations/ConversationUsageBreakdown.tsx +16 -3
  75. package/src/client/conversations/ConversationWatches.tsx +165 -0
  76. package/src/client/conversations/ConversationWorkspace.tsx +12 -22
  77. package/src/client/conversations/ConversationWorkspaceLoading.tsx +1 -1
  78. package/src/client/conversations/DetailsList.tsx +124 -0
  79. package/src/client/conversations/EventDetails.tsx +42 -8
  80. package/src/client/conversations/ForkConversationButton.tsx +27 -16
  81. package/src/client/conversations/ObjectCard.tsx +20 -8
  82. package/src/client/conversations/PendingMailboxStack.tsx +52 -33
  83. package/src/client/conversations/README.md +93 -19
  84. package/src/client/conversations/ShareConversationButton.tsx +28 -3
  85. package/src/client/conversations/SubagentTranscriptDrawer.tsx +21 -15
  86. package/src/client/conversations/ToolFrame.tsx +36 -52
  87. package/src/client/conversations/TranscriptActivityGroup.tsx +13 -4
  88. package/src/client/conversations/TranscriptAutomationTriggerView.tsx +5 -4
  89. package/src/client/conversations/TranscriptContextEventView.tsx +25 -11
  90. package/src/client/conversations/TranscriptHeadingRow.tsx +7 -7
  91. package/src/client/conversations/TranscriptLoading.tsx +1 -1
  92. package/src/client/conversations/TranscriptMarkdown.tsx +25 -20
  93. package/src/client/conversations/TranscriptMessageContextView.tsx +8 -2
  94. package/src/client/conversations/TranscriptMessageView.tsx +6 -1
  95. package/src/client/conversations/TranscriptReasoningView.tsx +54 -68
  96. package/src/client/conversations/TranscriptSubagentView.tsx +3 -3
  97. package/src/client/conversations/TranscriptTimestamp.tsx +9 -7
  98. package/src/client/conversations/TranscriptToolView.tsx +1 -1
  99. package/src/client/conversations/TranscriptTurnContextView.tsx +99 -27
  100. package/src/client/conversations/TranscriptView.tsx +63 -27
  101. package/src/client/conversations/eventLog.ts +57 -0
  102. package/src/client/conversations/eventTime.ts +60 -0
  103. package/src/client/conversations/queries.ts +29 -0
  104. package/src/client/conversations/transcriptBottomPinning.ts +34 -0
  105. package/src/client/format.ts +5 -0
  106. package/src/client/lib/utils.ts +1 -0
  107. package/src/client/pages/ConnectionsPage.tsx +2 -2
  108. package/src/client/pages/PersonalTokensPage.tsx +4 -4
  109. package/src/client/pages/SettingsPage.tsx +9 -10
  110. package/src/client/pages/admin/ServiceAccountsSection.tsx +2 -2
  111. package/src/client/pages/automations/AutomationCostChart.tsx +50 -71
  112. package/src/client/pages/automations/AutomationDeleteDialog.tsx +87 -0
  113. package/src/client/pages/automations/AutomationDetails.tsx +193 -0
  114. package/src/client/pages/automations/AutomationEditPage.tsx +7 -8
  115. package/src/client/pages/automations/AutomationEditor.tsx +41 -29
  116. package/src/client/pages/automations/AutomationEditorLoading.tsx +1 -1
  117. package/src/client/pages/automations/AutomationEventFields.tsx +202 -119
  118. package/src/client/pages/automations/AutomationExecutionChart.tsx +51 -64
  119. package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +47 -70
  120. package/src/client/pages/automations/AutomationExecutionsPage.tsx +150 -126
  121. package/src/client/pages/automations/AutomationFilters.tsx +189 -74
  122. package/src/client/pages/automations/AutomationLifecycle.tsx +109 -78
  123. package/src/client/pages/automations/AutomationOutcomeFields.tsx +26 -24
  124. package/src/client/pages/automations/AutomationRecentRuns.tsx +143 -0
  125. package/src/client/pages/automations/AutomationRow.tsx +12 -138
  126. package/src/client/pages/automations/AutomationRunDetails.tsx +307 -0
  127. package/src/client/pages/automations/AutomationRunsPage.tsx +119 -94
  128. package/src/client/pages/automations/AutomationScheduleFields.tsx +51 -51
  129. package/src/client/pages/automations/AutomationStatus.tsx +201 -0
  130. package/src/client/pages/automations/AutomationVersionsPage.tsx +65 -28
  131. package/src/client/pages/automations/AutomationsPage.tsx +80 -68
  132. package/src/client/pages/automations/AutomationsPageLayout.tsx +46 -14
  133. package/src/client/pages/automations/README.md +57 -0
  134. package/src/client/pages/automations/TriggerFilters.tsx +22 -0
  135. package/src/client/pages/automations/automationFormat.ts +37 -23
  136. package/src/client/pages/code/CodeActivityChart.tsx +59 -101
  137. package/src/client/pages/code/CodePage.tsx +52 -55
  138. package/src/client/pages/code/RepositoryPage.tsx +6 -8
  139. package/src/client/pages/locations/LocationActivityChart.tsx +53 -70
  140. package/src/client/pages/locations/LocationDirectoryActivityChart.tsx +60 -80
  141. package/src/client/pages/memory/MemoryCostChart.tsx +79 -103
  142. package/src/client/pages/memory/MemoryDetails.tsx +218 -0
  143. package/src/client/pages/memory/MemoryPage.tsx +168 -112
  144. package/src/client/pages/memory/MemoryPageLayout.tsx +33 -9
  145. package/src/client/pages/memory/MemoryTimeline.tsx +46 -69
  146. package/src/client/pages/memory/memoryRecord.ts +1 -1
  147. package/src/client/pages/people/ContributionGrid.tsx +23 -16
  148. package/src/client/pages/people/PeopleActivityChart.tsx +68 -107
  149. package/src/client/pages/people/ProfileCodeChanges.tsx +5 -5
  150. package/src/client/pages/system/BaseSandboxCard.tsx +1 -1
  151. package/src/client/pages/system/ConversationActivityChart.tsx +49 -67
  152. package/src/client/pages/system/GuardianActivity.tsx +1 -2
  153. package/src/client/pages/system/PluginBarChart.tsx +106 -87
  154. package/src/client/pages/system/PluginReportRecordSet.tsx +25 -24
  155. package/src/client/pages/system/README.md +23 -0
  156. package/src/client/pages/system/SystemNavigation.tsx +5 -1
  157. package/src/client/pages/system/WorkspaceDeleteDialog.tsx +111 -0
  158. package/src/client/pages/system/WorkspaceDetails.tsx +200 -43
  159. package/src/client/pages/system/WorkspaceEditor.tsx +59 -61
  160. package/src/client/pages/system/WorkspaceFormPage.tsx +23 -47
  161. package/src/client/pages/system/WorkspaceList.tsx +20 -30
  162. package/src/client/pages/system/WorkspacesPage.tsx +117 -119
  163. package/src/client/pages/system/sandboxSize.ts +8 -0
  164. package/src/client/pages/system/workspaceQueries.ts +53 -0
  165. package/src/client/pages/user/PluginUserPage.tsx +51 -2
  166. package/src/client/pages/user/pluginUserPageData.ts +1 -6
  167. package/src/client/styles.ts +4 -0
  168. package/src/client.tsx +7 -1
  169. package/src/mock-reporting/automation-collection.ts +4 -2
  170. package/src/mock-reporting/fixtures.ts +23 -7
  171. package/src/mock-reporting/routes.ts +12 -0
  172. package/src/mock-reporting/watches.ts +94 -0
  173. package/src/shell.ts +4 -9
  174. package/src/tailwind.css +77 -10
  175. package/src/client/components/Button.tsx +0 -118
  176. package/src/client/components/Field.tsx +0 -53
  177. package/src/client/components/SegmentedTabs.tsx +0 -119
  178. package/src/client/components/Select.tsx +0 -52
  179. package/src/client/components/Sheet.LICENSE +0 -21
  180. package/src/client/components/Sheet.tsx +0 -141
  181. package/src/client/components/Skeleton.tsx +0 -17
  182. package/src/client/components/TextInput.tsx +0 -58
  183. package/src/client/components/Tooltip.tsx +0 -216
  184. package/src/client/components/charts/useChartLayout.ts +0 -27
  185. package/src/client/conversations/ConversationDetailsFrame.tsx +0 -91
  186. package/src/client/conversations/CopyMarkdownButton.tsx +0 -65
  187. package/src/client/pages/automations/AutomationDetailsDrawer.tsx +0 -219
  188. package/src/client/pages/dev/ChartFixtures.tsx +0 -325
  189. package/src/client/pages/dev/ComponentsPage.tsx +0 -899
  190. package/src/client/pages/dev/ConversationFixture.tsx +0 -231
  191. package/src/client/pages/dev/ObjectFixtures.tsx +0 -138
  192. package/src/client/pages/dev/SegmentedFixtures.tsx +0 -59
  193. package/src/client/pages/dev/SelectFixtures.tsx +0 -62
  194. package/src/client/pages/dev/TranscriptActivityFixtures.tsx +0 -206
  195. package/src/client/pages/memory/MemoryDetailsDrawer.tsx +0 -167
  196. package/src/client/pages/system/SandboxSizeSummary.tsx +0 -47
  197. package/src/client/pages/system/SnapshotSummary.tsx +0 -78
@@ -1,219 +0,0 @@
1
- import { AutomationLifecycle } from "./AutomationLifecycle";
2
- import { automationOutcomeLabel } from "./automationOutcomes";
3
- import {
4
- automationEventConditions,
5
- automationEventNames,
6
- automationScheduleLabel,
7
- formatAutomationRunTime,
8
- } from "./automationFormat";
9
- import type { AutomationSummary } from "@sentry/junior/api/schema";
10
- import { Link, useLocation } from "react-router";
11
- import { Detail, DetailList } from "../../components/DetailList";
12
- import { Drawer } from "../../components/Drawer";
13
- import {
14
- timeRangeLabel,
15
- type TimeRangeDays,
16
- } from "../../components/controls/TimeRangeSelector";
17
- import { conversationPath } from "../../conversations/conversationRoutes";
18
- import { formatTime, peoplePath } from "../../format";
19
- import { TranscriptText } from "../../conversations/TranscriptText";
20
- import { cn, dashboardInlineLinkClass } from "../../styles";
21
-
22
- /** Show one automation's instruction and metadata in a right-side slide-out. */
23
- export function AutomationDetailsDrawer(props: {
24
- onClose(): void;
25
- range: TimeRangeDays;
26
- automation: AutomationSummary | undefined;
27
- }) {
28
- const location = useLocation();
29
- if (!props.automation) return null;
30
-
31
- const { automation } = props;
32
- const createdBy = automation.createdByEmail ? (
33
- <Link
34
- className={cn("font-semibold", dashboardInlineLinkClass)}
35
- to={peoplePath(automation.createdByEmail)}
36
- >
37
- {automation.ownedByViewer ? "you" : automation.createdBy}
38
- </Link>
39
- ) : automation.ownedByViewer ? (
40
- "you"
41
- ) : (
42
- automation.createdBy
43
- );
44
- const conditions =
45
- automation.kind === "event" ? automationEventConditions(automation) : "";
46
- const details =
47
- automation.kind === "scheduled"
48
- ? [
49
- { label: "Schedule", value: automationScheduleLabel(automation) },
50
- {
51
- label: "Next run",
52
- value:
53
- automation.status === "active" && automation.nextRunAt
54
- ? formatAutomationRunTime(automation.nextRunAt)
55
- : "None",
56
- },
57
- ]
58
- : [
59
- { label: "Watching", value: automation.resource },
60
- { label: "Events", value: automationEventNames(automation) },
61
- ...(conditions ? [{ label: "Conditions", value: conditions }] : []),
62
- ];
63
- const titleId = "automation-details-drawer-title";
64
-
65
- return (
66
- <Drawer
67
- closeLabel="Close automation details"
68
- header={
69
- <>
70
- <h2
71
- className="m-0 font-display text-lg font-medium tracking-normal text-dashboard-text"
72
- id={titleId}
73
- >
74
- {automation.title}
75
- </h2>
76
- <div className="mt-1 break-words text-sm text-dashboard-text-muted">
77
- Created by {createdBy} · {automation.destination.label}
78
- </div>
79
- </>
80
- }
81
- onClose={props.onClose}
82
- openKey={`${automation.kind}:${automation.id}`}
83
- titleId={titleId}
84
- >
85
- <section className="grid gap-5">
86
- <div>
87
- <h3 className="mt-0 mb-2 text-sm font-medium text-dashboard-text-muted">
88
- What to do
89
- </h3>
90
- <TranscriptText
91
- mentions={automation.mentions ?? []}
92
- text={automation.instruction}
93
- />
94
- </div>
95
- <AutomationLifecycle
96
- key={`${automation.kind}:${automation.id}`}
97
- automation={automation}
98
- editPath={`/automations/${encodeURIComponent(automation.id)}/edit${location.search}`}
99
- />
100
- <DetailList>
101
- {details.map((detail) => (
102
- <Detail key={detail.label} label={detail.label}>
103
- {detail.value}
104
- </Detail>
105
- ))}
106
- <Detail label="On success">
107
- {automation.outcomes.length === 0 ? (
108
- "No message on success"
109
- ) : (
110
- <ol className="m-0 pl-4">
111
- {automation.outcomes.map((outcome, index) => (
112
- <li key={index}>
113
- {automationOutcomeLabel(outcome, automation.destination)}
114
- </li>
115
- ))}
116
- </ol>
117
- )}
118
- </Detail>
119
- </DetailList>
120
- <div className="flex flex-wrap gap-x-5">
121
- {automation.totalRuns > 0 &&
122
- automation.lastRunStatus !== "failed" &&
123
- automation.lastRunStatus !== "blocked" ? (
124
- <Link
125
- className="w-fit py-2 text-sm text-dashboard-text underline underline-offset-2"
126
- to={`/automations/${encodeURIComponent(automation.id)}/executions`}
127
- >
128
- View all runs
129
- </Link>
130
- ) : null}
131
- <Link
132
- className="w-fit py-2 text-sm text-dashboard-text underline underline-offset-2"
133
- to={`/automations/${encodeURIComponent(automation.id)}/versions${location.search}`}
134
- >
135
- Version history
136
- </Link>
137
- </div>
138
- <details>
139
- <summary className="cursor-pointer py-3 text-sm text-dashboard-text-muted hover:text-dashboard-text focus-visible:outline focus-visible:outline-dashboard-focus">
140
- More details
141
- </summary>
142
- <DetailList>
143
- <Detail label="Connected accounts">
144
- {automation.credentialMode === "creator" ? (
145
- <>
146
- Uses accounts connected by{" "}
147
- {automation.ownedByViewer ? "you" : automation.createdBy}.
148
- </>
149
- ) : (
150
- "Junior’s accounts only"
151
- )}
152
- </Detail>
153
- <Detail label="Created">{formatDate(automation.createdAt)}</Detail>
154
- <Detail label="Run history">
155
- <AutomationExecutionSummary
156
- range={props.range}
157
- automation={automation}
158
- />
159
- </Detail>
160
- </DetailList>
161
- </details>
162
- </section>
163
- </Drawer>
164
- );
165
- }
166
-
167
- function AutomationExecutionSummary(props: {
168
- range: TimeRangeDays;
169
- automation: Pick<
170
- AutomationSummary,
171
- "id" | "kind" | "lastConversationId" | "lastRunAt" | "runs" | "totalRuns"
172
- >;
173
- }) {
174
- const { range, automation } = props;
175
- const runCount = automation.runs[range];
176
- const rangeLabel = timeRangeLabel(range);
177
- const executionsPath = `/automations/${encodeURIComponent(automation.id)}/executions`;
178
- return (
179
- <div className="text-sm text-dashboard-text-muted">
180
- {automation.totalRuns > 0 ? (
181
- <Link className={dashboardInlineLinkClass} to={executionsPath}>
182
- {runCount} runs / {rangeLabel}
183
- </Link>
184
- ) : (
185
- <span className="text-dashboard-text">
186
- {runCount} runs / {rangeLabel}
187
- </span>
188
- )}
189
- <span className="mx-2 opacity-45">·</span>
190
- <span>
191
- {automation.totalRuns > 0 ? (
192
- <Link className={dashboardInlineLinkClass} to={executionsPath}>
193
- {automation.totalRuns} total
194
- </Link>
195
- ) : (
196
- <>{automation.totalRuns} total</>
197
- )}
198
- {automation.lastRunAt ? " · Last run " : " · Never run"}
199
- {automation.lastRunAt && automation.lastConversationId ? (
200
- <Link
201
- className={dashboardInlineLinkClass}
202
- to={conversationPath(automation.lastConversationId)}
203
- >
204
- {formatAutomationRunTime(automation.lastRunAt)}
205
- </Link>
206
- ) : automation.lastRunAt ? (
207
- formatAutomationRunTime(automation.lastRunAt)
208
- ) : null}
209
- </span>
210
- </div>
211
- );
212
- }
213
-
214
- function formatDate(value: string): string {
215
- return formatTime(value, {
216
- dateStyle: "medium",
217
- timeStyle: "short",
218
- });
219
- }
@@ -1,325 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import type {
3
- AutomationExecutionDay,
4
- AutomationExecutionStatusDay,
5
- CodeActivityDay,
6
- ConversationMetricDay,
7
- DailyConversationActivity,
8
- GuardianMetricDay,
9
- LocationActivityDayReport,
10
- PeopleActivityDayReport,
11
- PluginOperationalReport,
12
- } from "@sentry/junior/api/schema";
13
- import { InputCacheChart } from "../../components/charts/InputCacheChart";
14
- import { SystemMetricCharts } from "../../components/charts/SystemMetricCharts";
15
- import { WorkspaceUsageChart } from "../../components/charts/WorkspaceUsageChart";
16
- import { AutomationCostChart } from "../automations/AutomationCostChart";
17
- import { AutomationExecutionChart } from "../automations/AutomationExecutionChart";
18
- import { AutomationExecutionStatusChart } from "../automations/AutomationExecutionStatusChart";
19
- import { CodeActivityChart } from "../code/CodeActivityChart";
20
- import { LocationActivityChart } from "../locations/LocationActivityChart";
21
- import { LocationDirectoryActivityChart } from "../locations/LocationDirectoryActivityChart";
22
- import { MemoryCostChart } from "../memory/MemoryCostChart";
23
- import { MemoryTimeline } from "../memory/MemoryTimeline";
24
- import type { MemoryCostDay, MemoryDay } from "../memory/memoryDashboard";
25
- import { ContributionGrid } from "../people/ContributionGrid";
26
- import { PeopleActivityChart } from "../people/PeopleActivityChart";
27
- import { ConversationActivityChart } from "../system/ConversationActivityChart";
28
- import { GuardianActivity } from "../system/GuardianActivity";
29
- import { PluginBarChart } from "../system/PluginBarChart";
30
- import { Card } from "../../components/layout/Card";
31
- import { CardHeader } from "../../components/layout/CardHeader";
32
-
33
- type PluginWidget = NonNullable<PluginOperationalReport["widgets"]>[number];
34
-
35
- // The gallery browser scenario saves one image for each id.
36
- const CHART_FIXTURE_IDS = [
37
- "conversation-activity",
38
- "conversation-activity-hourly",
39
- "input-cache",
40
- "system-metrics",
41
- "people-activity",
42
- "location-directory-activity",
43
- "location-activity",
44
- "code-activity",
45
- "code-activity-dense",
46
- "code-activity-empty",
47
- "workspace-usage",
48
- "automation-executions",
49
- "automation-execution-status",
50
- "automation-cost",
51
- "memory-timeline",
52
- "memory-cost",
53
- "guardian-activity",
54
- "plugin-bar-chart",
55
- "contribution-grid",
56
- ] as const;
57
-
58
- type ChartFixtureId = (typeof CHART_FIXTURE_IDS)[number];
59
-
60
- const METRIC_DAYS: ConversationMetricDay[] = fixtureDates(14).map(
61
- (date, index) => ({
62
- conversations: 4 + ((index * 5) % 17),
63
- costUsd: 0.7 + ((index * 7) % 11) * 0.18,
64
- date,
65
- durationMs: 90_000 + ((index * 41) % 13) * 24_000,
66
- tokens: 18_000 + ((index * 17) % 19) * 2_300,
67
- }),
68
- );
69
-
70
- const HOURLY_METRIC_DAYS: ConversationMetricDay[] = fixtureHours(24).map(
71
- (date, index) => ({
72
- conversations: index % 5 === 0 ? 0 : 1 + ((index * 7) % 9),
73
- costUsd: 0.05 + ((index * 3) % 7) * 0.04,
74
- date,
75
- durationMs: 30_000 + ((index * 11) % 7) * 9_000,
76
- tokens: 2_000 + ((index * 13) % 11) * 400,
77
- }),
78
- );
79
-
80
- const PEOPLE_DAYS: PeopleActivityDayReport[] = fixtureDates(30).map(
81
- (date, index) => ({
82
- activePeople: 4 + ((index * 7) % 13),
83
- conversations: 18 + ((index * 11) % 31),
84
- date,
85
- }),
86
- );
87
-
88
- const LOCATION_DAYS: LocationActivityDayReport[] = fixtureDates(30).map(
89
- (date, index) => ({
90
- date,
91
- privateConversations: 3 + ((index * 5) % 12),
92
- publicConversations: 12 + ((index * 9) % 28),
93
- }),
94
- );
95
-
96
- const LOCATION_DETAIL_DAYS: DailyConversationActivity[] = fixtureDates(90).map(
97
- (date, index) => {
98
- const conversations = index % 11 === 0 ? 0 : 2 + ((index * 7) % 15);
99
- return {
100
- active: Math.min(conversations, index % 4),
101
- conversations,
102
- date,
103
- durationMs: conversations * 60_000,
104
- failed: index % 13 === 0 ? 1 : 0,
105
- };
106
- },
107
- );
108
-
109
- const CODE_DAYS: CodeActivityDay[] = codeDays(30);
110
-
111
- const DENSE_CODE_DAYS: CodeActivityDay[] = codeDays(90);
112
-
113
- const EMPTY_CODE_DAYS: CodeActivityDay[] = fixtureDates(30).map((date) => ({
114
- closed: 0,
115
- created: 0,
116
- date,
117
- merged: 0,
118
- }));
119
-
120
- const WORKSPACE_USAGE_DAYS = fixtureDates(30).map((date, index) => ({
121
- count: index % 6 === 0 ? 0 : 1 + ((index * 5) % 9),
122
- date,
123
- }));
124
-
125
- const AUTOMATION_DAYS: AutomationExecutionDay[] = fixtureDates(30).map(
126
- (date, index) => ({
127
- costUsd: index % 7 === 0 ? 0 : 0.04 + ((index * 5) % 9) * 0.11,
128
- date,
129
- event: (index * 3) % 5,
130
- scheduled: index % 7 === 0 ? 0 : 1 + ((index * 7) % 6),
131
- }),
132
- );
133
-
134
- const AUTOMATION_STATUS_DAYS: AutomationExecutionStatusDay[] = fixtureDates(
135
- 30,
136
- ).map((date, index) => ({
137
- blocked: index % 9 === 0 ? 1 : 0,
138
- completed: index % 7 === 0 ? 0 : 1 + ((index * 5) % 4),
139
- date,
140
- failed: index % 5 === 0 ? 1 : 0,
141
- }));
142
-
143
- const MEMORY_DAYS: MemoryDay[] = fixtureDates(30).map((date, index) => ({
144
- date,
145
- personal: index % 8 === 0 ? 0 : (index * 3) % 7,
146
- public: (index * 5) % 4,
147
- }));
148
-
149
- const MEMORY_EXTRACTION_DAYS: MemoryCostDay[] = fixtureDates(30).map(
150
- (date, index) => ({
151
- costUsd: index % 8 === 0 ? 0 : 0.02 + ((index * 7) % 9) * 0.015,
152
- date,
153
- events: index % 8 === 0 ? 0 : 1 + ((index * 3) % 6),
154
- }),
155
- );
156
-
157
- const MEMORY_RECALL_DAYS: MemoryCostDay[] = fixtureDates(30).map(
158
- (date, index) => ({
159
- costUsd: 0.01 + ((index * 5) % 7) * 0.008,
160
- date,
161
- events: 2 + ((index * 5) % 9),
162
- }),
163
- );
164
-
165
- const GUARDIAN_DAYS: GuardianMetricDay[] = fixtureDates(30).map(
166
- (date, index) => {
167
- const allow = 6 + ((index * 7) % 19);
168
- const ask = (index * 3) % 5;
169
- const deny = index % 6 === 0 ? 2 : 0;
170
- return {
171
- allow,
172
- ask,
173
- costUsd: (allow + ask + deny) * 0.0021,
174
- date,
175
- deny,
176
- requests: allow + ask + deny,
177
- };
178
- },
179
- );
180
-
181
- const PLUGIN_WIDGET: PluginWidget = {
182
- categories: fixtureDates(14).map((date, index) => ({
183
- id: date,
184
- label: date,
185
- values: {
186
- failed: index % 4 === 0 ? 2 : 0,
187
- succeeded: 3 + ((index * 5) % 11),
188
- },
189
- })),
190
- description: "Deliveries reported by the plugin.",
191
- id: "deliveries",
192
- series: [
193
- { key: "succeeded", label: "Succeeded", tone: "good" },
194
- { key: "failed", label: "Failed", tone: "danger" },
195
- ],
196
- title: "Deliveries",
197
- type: "bar_chart",
198
- };
199
-
200
- const CONTRIBUTION_DAYS = fixtureDates(70).map((date, index) => ({
201
- conversations: index % 9 === 0 ? 0 : 1 + ((index * 7) % 18),
202
- date,
203
- durationMs: index % 9 === 0 ? 0 : 45_000 + ((index * 13) % 20) * 18_000,
204
- }));
205
-
206
- /** Render every dashboard chart with fixed data for visual review. */
207
- export function ChartFixtures() {
208
- return (
209
- <>
210
- <ChartFixture id="conversation-activity">
211
- <ConversationActivityChart days={METRIC_DAYS} />
212
- </ChartFixture>
213
- <ChartFixture id="conversation-activity-hourly">
214
- <ConversationActivityChart
215
- bucketUnit="hour"
216
- days={HOURLY_METRIC_DAYS}
217
- />
218
- </ChartFixture>
219
- <ChartFixture id="input-cache">
220
- <InputCacheChart
221
- bucketUnit="day"
222
- days={METRIC_DAYS.map((day, index) => ({
223
- ...day,
224
- inputTokens: 2_000,
225
- cachedInputTokens: index === 9 ? 8_000 : 180_000,
226
- cacheCreationTokens:
227
- index === 5 ? undefined : index === 9 ? 190_000 : 10_000,
228
- }))}
229
- />
230
- </ChartFixture>
231
- <ChartFixture id="system-metrics">
232
- <SystemMetricCharts days={METRIC_DAYS} />
233
- </ChartFixture>
234
- <ChartFixture id="people-activity">
235
- <PeopleActivityChart days={PEOPLE_DAYS} />
236
- </ChartFixture>
237
- <ChartFixture id="location-directory-activity">
238
- <LocationDirectoryActivityChart days={LOCATION_DAYS} />
239
- </ChartFixture>
240
- <ChartFixture id="location-activity">
241
- <LocationActivityChart days={LOCATION_DETAIL_DAYS} />
242
- </ChartFixture>
243
- <ChartFixture id="code-activity">
244
- <CodeActivityChart days={CODE_DAYS} range={30} />
245
- </ChartFixture>
246
- <ChartFixture id="code-activity-dense">
247
- <CodeActivityChart days={DENSE_CODE_DAYS} range={90} />
248
- </ChartFixture>
249
- <ChartFixture id="code-activity-empty">
250
- <CodeActivityChart days={EMPTY_CODE_DAYS} range={30} />
251
- </ChartFixture>
252
- <ChartFixture id="workspace-usage">
253
- <WorkspaceUsageChart
254
- days={WORKSPACE_USAGE_DAYS}
255
- range={30}
256
- workspaceName="junior"
257
- />
258
- </ChartFixture>
259
- <ChartFixture id="automation-executions">
260
- <AutomationExecutionChart days={AUTOMATION_DAYS} range={30} />
261
- </ChartFixture>
262
- <ChartFixture id="automation-execution-status">
263
- <AutomationExecutionStatusChart
264
- days={AUTOMATION_STATUS_DAYS}
265
- range={30}
266
- />
267
- </ChartFixture>
268
- <ChartFixture id="automation-cost">
269
- <AutomationCostChart days={AUTOMATION_DAYS} range={30} />
270
- </ChartFixture>
271
- <ChartFixture id="memory-timeline">
272
- <MemoryTimeline days={MEMORY_DAYS} range={30} />
273
- </ChartFixture>
274
- <ChartFixture id="memory-cost">
275
- <MemoryCostChart
276
- extractionDays={MEMORY_EXTRACTION_DAYS}
277
- range={30}
278
- recallDays={MEMORY_RECALL_DAYS}
279
- />
280
- </ChartFixture>
281
- <ChartFixture id="guardian-activity">
282
- <GuardianActivity days={GUARDIAN_DAYS} />
283
- </ChartFixture>
284
- <ChartFixture id="plugin-bar-chart">
285
- <PluginBarChart widget={PLUGIN_WIDGET} />
286
- </ChartFixture>
287
- <ChartFixture id="contribution-grid">
288
- <Card>
289
- <CardHeader
290
- description="Daily conversation intensity over ten weeks."
291
- title="Contribution activity"
292
- />
293
- <ContributionGrid days={CONTRIBUTION_DAYS} />
294
- </Card>
295
- </ChartFixture>
296
- </>
297
- );
298
- }
299
-
300
- function ChartFixture(props: { children: ReactNode; id: ChartFixtureId }) {
301
- return <div data-gallery-chart={props.id}>{props.children}</div>;
302
- }
303
-
304
- function codeDays(count: number): CodeActivityDay[] {
305
- return fixtureDates(count).map((date, index) => ({
306
- closed: index % 9 === 0 ? 1 : 0,
307
- created: index % 4 === 0 ? 0 : 1 + ((index * 5) % 3),
308
- date,
309
- merged: index % 3 === 0 ? 1 + (index % 2) : 0,
310
- }));
311
- }
312
-
313
- function fixtureDates(count: number): string[] {
314
- const start = Date.UTC(2026, 4, 1);
315
- return Array.from({ length: count }, (_, index) =>
316
- new Date(start + index * 86_400_000).toISOString().slice(0, 10),
317
- );
318
- }
319
-
320
- function fixtureHours(count: number): string[] {
321
- const start = Date.UTC(2026, 4, 1);
322
- return Array.from({ length: count }, (_, index) =>
323
- new Date(start + index * 3_600_000).toISOString().slice(0, 13),
324
- );
325
- }