@sentry/junior-dashboard 0.264.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.
- package/LICENSE +201 -0
- package/README.md +2 -5
- package/dist/app.js +119 -35
- package/dist/client.js +145 -136
- package/dist/index.d.ts +0 -1
- package/dist/index.js +119 -35
- package/dist/tailwind.css +1 -1
- package/package.json +5 -4
- package/src/api/schema.ts +0 -1
- package/src/app.ts +5 -20
- package/src/client/App.tsx +29 -31
- package/src/client/api.ts +7 -0
- package/src/client/components/BottomSheet.tsx +12 -2
- package/src/client/components/CopyButton.tsx +83 -0
- package/src/client/components/DetailsPanel.tsx +133 -0
- package/src/client/components/Drawer.tsx +15 -24
- package/src/client/components/FilterBar.tsx +16 -31
- package/src/client/components/Metric.tsx +33 -23
- package/src/client/components/PageContentSkeleton.tsx +1 -1
- package/src/client/components/Pagination.tsx +1 -1
- package/src/client/components/ParticipantAvatarStack.tsx +40 -36
- package/src/client/components/ProfileMenu.tsx +27 -93
- package/src/client/components/README.md +86 -77
- package/src/client/components/SegmentedNav.tsx +1 -1
- package/src/client/components/ShimmerText.tsx +2 -6
- package/src/client/components/ThemeSwitcher.tsx +19 -15
- package/src/client/components/charts/ActivityChart.tsx +173 -288
- package/src/client/components/charts/CacheWrites.tsx +63 -50
- package/src/client/components/charts/InputCacheChart.tsx +137 -131
- package/src/client/components/charts/README.md +4 -4
- package/src/client/components/charts/SystemMetricCharts.tsx +68 -95
- package/src/client/components/charts/WorkspaceUsageChart.tsx +42 -62
- package/src/client/components/controls/DirectorySortSelect.tsx +3 -3
- package/src/client/components/controls/TimeRangeSelector.tsx +10 -15
- package/src/client/components/layout/DashboardHeader.tsx +44 -90
- package/src/client/components/layout/SecondaryNavigation.tsx +2 -1
- package/src/client/components/layout/VisualViewportShell.tsx +2 -2
- package/src/client/components/ui/accordion.tsx +77 -0
- package/src/client/components/ui/alert-dialog.tsx +89 -0
- package/src/client/components/ui/button.tsx +85 -0
- package/src/client/components/ui/chart.tsx +74 -0
- package/src/client/components/ui/checkbox.tsx +26 -0
- package/src/client/components/ui/collapsible.tsx +22 -0
- package/src/client/components/ui/field.tsx +49 -0
- package/src/client/components/ui/input.tsx +35 -0
- package/src/client/components/ui/native-select.tsx +57 -0
- package/src/client/components/ui/popover.tsx +67 -0
- package/src/client/components/ui/radio-group.tsx +32 -0
- package/src/client/components/ui/sheet.tsx +13 -3
- package/src/client/components/ui/skeleton.tsx +19 -0
- package/src/client/components/ui/table.tsx +80 -0
- package/src/client/components/ui/tabs.tsx +75 -0
- package/src/client/components/ui/textarea.tsx +17 -0
- package/src/client/components/ui/toast.tsx +215 -0
- package/src/client/components/ui/toggle-group.tsx +36 -0
- package/src/client/components/ui/toggle.tsx +37 -0
- package/src/client/components/ui/tooltip.tsx +168 -0
- package/src/client/components/ui/trace.tsx +96 -0
- package/src/client/conversations/ChatLayout.tsx +7 -3
- package/src/client/conversations/ConversationBrief.tsx +17 -6
- package/src/client/conversations/ConversationComposer.tsx +26 -12
- package/src/client/conversations/ConversationDetails.tsx +147 -62
- package/src/client/conversations/ConversationEventDetails.tsx +141 -0
- package/src/client/conversations/ConversationEventLog.tsx +150 -129
- package/src/client/conversations/ConversationHeader.tsx +8 -3
- package/src/client/conversations/ConversationHeaderActions.tsx +90 -82
- package/src/client/conversations/ConversationHomeList.tsx +1 -1
- package/src/client/conversations/ConversationLinkedWork.tsx +118 -0
- package/src/client/conversations/ConversationMeta.tsx +55 -88
- package/src/client/conversations/ConversationPage.tsx +220 -101
- package/src/client/conversations/ConversationSidebar.tsx +48 -29
- package/src/client/conversations/ConversationWatches.tsx +165 -0
- package/src/client/conversations/ConversationWorkspace.tsx +12 -22
- package/src/client/conversations/ConversationWorkspaceLoading.tsx +1 -1
- package/src/client/conversations/DetailsList.tsx +124 -0
- package/src/client/conversations/EventDetails.tsx +42 -8
- package/src/client/conversations/ForkConversationButton.tsx +27 -16
- package/src/client/conversations/ObjectCard.tsx +20 -8
- package/src/client/conversations/PendingMailboxStack.tsx +52 -33
- package/src/client/conversations/README.md +86 -13
- package/src/client/conversations/ShareConversationButton.tsx +25 -13
- package/src/client/conversations/SubagentTranscriptDrawer.tsx +21 -15
- package/src/client/conversations/ToolFrame.tsx +36 -52
- package/src/client/conversations/TranscriptActivityGroup.tsx +13 -4
- package/src/client/conversations/TranscriptAutomationTriggerView.tsx +5 -4
- package/src/client/conversations/TranscriptContextEventView.tsx +25 -11
- package/src/client/conversations/TranscriptHeadingRow.tsx +7 -7
- package/src/client/conversations/TranscriptLoading.tsx +1 -1
- package/src/client/conversations/TranscriptMarkdown.tsx +25 -20
- package/src/client/conversations/TranscriptMessageContextView.tsx +8 -2
- package/src/client/conversations/TranscriptMessageView.tsx +6 -1
- package/src/client/conversations/TranscriptReasoningView.tsx +54 -68
- package/src/client/conversations/TranscriptTimestamp.tsx +9 -7
- package/src/client/conversations/TranscriptToolView.tsx +1 -1
- package/src/client/conversations/TranscriptTurnContextView.tsx +99 -27
- package/src/client/conversations/TranscriptView.tsx +63 -27
- package/src/client/conversations/eventLog.ts +57 -0
- package/src/client/conversations/eventTime.ts +60 -0
- package/src/client/conversations/queries.ts +29 -0
- package/src/client/conversations/transcriptBottomPinning.ts +34 -0
- package/src/client/format.ts +5 -0
- package/src/client/pages/ConnectionsPage.tsx +2 -2
- package/src/client/pages/PersonalTokensPage.tsx +4 -4
- package/src/client/pages/SettingsPage.tsx +9 -10
- package/src/client/pages/admin/ServiceAccountsSection.tsx +2 -2
- package/src/client/pages/automations/AutomationCostChart.tsx +50 -71
- package/src/client/pages/automations/AutomationDeleteDialog.tsx +87 -0
- package/src/client/pages/automations/AutomationDetails.tsx +193 -0
- package/src/client/pages/automations/AutomationEditPage.tsx +7 -8
- package/src/client/pages/automations/AutomationEditor.tsx +41 -29
- package/src/client/pages/automations/AutomationEditorLoading.tsx +1 -1
- package/src/client/pages/automations/AutomationEventFields.tsx +202 -119
- package/src/client/pages/automations/AutomationExecutionChart.tsx +51 -64
- package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +47 -70
- package/src/client/pages/automations/AutomationExecutionsPage.tsx +150 -126
- package/src/client/pages/automations/AutomationFilters.tsx +189 -74
- package/src/client/pages/automations/AutomationLifecycle.tsx +109 -78
- package/src/client/pages/automations/AutomationOutcomeFields.tsx +26 -24
- package/src/client/pages/automations/AutomationRecentRuns.tsx +143 -0
- package/src/client/pages/automations/AutomationRow.tsx +12 -138
- package/src/client/pages/automations/AutomationRunDetails.tsx +307 -0
- package/src/client/pages/automations/AutomationRunsPage.tsx +119 -94
- package/src/client/pages/automations/AutomationScheduleFields.tsx +51 -51
- package/src/client/pages/automations/AutomationStatus.tsx +201 -0
- package/src/client/pages/automations/AutomationVersionsPage.tsx +65 -28
- package/src/client/pages/automations/AutomationsPage.tsx +80 -68
- package/src/client/pages/automations/AutomationsPageLayout.tsx +46 -14
- package/src/client/pages/automations/README.md +57 -0
- package/src/client/pages/automations/TriggerFilters.tsx +22 -0
- package/src/client/pages/automations/automationFormat.ts +37 -23
- package/src/client/pages/code/CodeActivityChart.tsx +59 -101
- package/src/client/pages/code/CodePage.tsx +52 -55
- package/src/client/pages/code/RepositoryPage.tsx +6 -8
- package/src/client/pages/locations/LocationActivityChart.tsx +53 -70
- package/src/client/pages/locations/LocationDirectoryActivityChart.tsx +60 -80
- package/src/client/pages/memory/MemoryCostChart.tsx +79 -103
- package/src/client/pages/memory/MemoryDetails.tsx +218 -0
- package/src/client/pages/memory/MemoryPage.tsx +168 -112
- package/src/client/pages/memory/MemoryPageLayout.tsx +33 -9
- package/src/client/pages/memory/MemoryTimeline.tsx +46 -69
- package/src/client/pages/memory/memoryRecord.ts +1 -1
- package/src/client/pages/people/ContributionGrid.tsx +23 -16
- package/src/client/pages/people/PeopleActivityChart.tsx +68 -107
- package/src/client/pages/people/ProfileCodeChanges.tsx +5 -5
- package/src/client/pages/system/BaseSandboxCard.tsx +1 -1
- package/src/client/pages/system/ConversationActivityChart.tsx +49 -67
- package/src/client/pages/system/GuardianActivity.tsx +1 -2
- package/src/client/pages/system/PluginBarChart.tsx +106 -87
- package/src/client/pages/system/PluginReportRecordSet.tsx +25 -24
- package/src/client/pages/system/README.md +23 -0
- package/src/client/pages/system/SystemNavigation.tsx +5 -1
- package/src/client/pages/system/WorkspaceDeleteDialog.tsx +111 -0
- package/src/client/pages/system/WorkspaceDetails.tsx +200 -43
- package/src/client/pages/system/WorkspaceEditor.tsx +59 -61
- package/src/client/pages/system/WorkspaceFormPage.tsx +23 -47
- package/src/client/pages/system/WorkspaceList.tsx +20 -30
- package/src/client/pages/system/WorkspacesPage.tsx +117 -119
- package/src/client/pages/system/sandboxSize.ts +8 -0
- package/src/client/pages/system/workspaceQueries.ts +53 -0
- package/src/client/pages/user/PluginUserPage.tsx +51 -2
- package/src/client/pages/user/pluginUserPageData.ts +1 -6
- package/src/client/styles.ts +4 -0
- package/src/client.tsx +7 -1
- package/src/mock-reporting/automation-collection.ts +4 -2
- package/src/mock-reporting/fixtures.ts +23 -7
- package/src/mock-reporting/routes.ts +12 -0
- package/src/mock-reporting/watches.ts +94 -0
- package/src/shell.ts +4 -9
- package/src/tailwind.css +0 -10
- package/src/client/components/Button.tsx +0 -118
- package/src/client/components/Field.tsx +0 -53
- package/src/client/components/SegmentedTabs.tsx +0 -119
- package/src/client/components/Select.tsx +0 -52
- package/src/client/components/Skeleton.tsx +0 -17
- package/src/client/components/TextInput.tsx +0 -58
- package/src/client/components/Tooltip.tsx +0 -216
- package/src/client/components/charts/useChartLayout.ts +0 -27
- package/src/client/components/ui/sheet.LICENSE +0 -21
- package/src/client/conversations/ConversationDetailsFrame.tsx +0 -119
- package/src/client/conversations/CopyMarkdownButton.tsx +0 -65
- package/src/client/pages/automations/AutomationDetailsDrawer.tsx +0 -219
- package/src/client/pages/dev/ChartFixtures.tsx +0 -325
- package/src/client/pages/dev/ComponentsPage.tsx +0 -899
- package/src/client/pages/dev/ConversationFixture.tsx +0 -231
- package/src/client/pages/dev/ObjectFixtures.tsx +0 -138
- package/src/client/pages/dev/SegmentedFixtures.tsx +0 -59
- package/src/client/pages/dev/SelectFixtures.tsx +0 -62
- package/src/client/pages/dev/TranscriptActivityFixtures.tsx +0 -206
- package/src/client/pages/memory/MemoryDetailsDrawer.tsx +0 -167
- package/src/client/pages/system/SandboxSizeSummary.tsx +0 -47
- package/src/client/pages/system/SnapshotSummary.tsx +0 -78
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import type { UseMutationResult } from "@tanstack/react-query";
|
|
2
|
-
import { BrainCircuit, Trash2 } from "lucide-react";
|
|
3
|
-
import { useEffect } from "react";
|
|
4
|
-
|
|
5
|
-
import { Detail, DetailList } from "../../components/DetailList";
|
|
6
|
-
import { Drawer } from "../../components/Drawer";
|
|
7
|
-
import { TranscriptText } from "../../conversations/TranscriptText";
|
|
8
|
-
import type {
|
|
9
|
-
PluginUserPageRecord,
|
|
10
|
-
PluginUserPageRecordAction,
|
|
11
|
-
} from "../user/pluginUserPageData";
|
|
12
|
-
|
|
13
|
-
// The memory plugin API does not resolve mentions yet, so memory text shows
|
|
14
|
-
// Slack ids instead of names.
|
|
15
|
-
const NO_MEMORY_MENTIONS: readonly [] = [];
|
|
16
|
-
|
|
17
|
-
type MemoryActionMutation = UseMutationResult<
|
|
18
|
-
void,
|
|
19
|
-
Error,
|
|
20
|
-
PluginUserPageRecordAction
|
|
21
|
-
>;
|
|
22
|
-
|
|
23
|
-
/** Show one memory's content and metadata in a right-side slide-out. */
|
|
24
|
-
export function MemoryDetailsDrawer(props: {
|
|
25
|
-
action: MemoryActionMutation;
|
|
26
|
-
onAction(action: PluginUserPageRecordAction): void;
|
|
27
|
-
onClose(): void;
|
|
28
|
-
record: PluginUserPageRecord | undefined;
|
|
29
|
-
}) {
|
|
30
|
-
const openRecordId = props.record?.id;
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
// Forget leaves the shared mutation in success/error until the next open.
|
|
34
|
-
// Clear it here so the new drawer does not inherit stale action UI state.
|
|
35
|
-
if (openRecordId) props.action.reset();
|
|
36
|
-
// oxlint-disable-next-line react/exhaustive-deps -- reset only on open id change
|
|
37
|
-
}, [openRecordId]);
|
|
38
|
-
|
|
39
|
-
if (!props.record) return null;
|
|
40
|
-
|
|
41
|
-
const { record } = props;
|
|
42
|
-
const kind = metadataValue(record, "Type");
|
|
43
|
-
const learned = metadataValue(record, "Learned");
|
|
44
|
-
const remembered = metadataValue(record, "Remembered");
|
|
45
|
-
const source = metadataValue(record, "Source");
|
|
46
|
-
const visibility = metadataValue(record, "Visibility");
|
|
47
|
-
const isPublic = visibility === "Public";
|
|
48
|
-
const story =
|
|
49
|
-
learned === "Automatic"
|
|
50
|
-
? `Junior learned this from a ${source} conversation on ${shortDate(remembered)}.`
|
|
51
|
-
: learned === "Explicit"
|
|
52
|
-
? isPublic
|
|
53
|
-
? `Someone asked Junior to remember this on ${shortDate(remembered)}.`
|
|
54
|
-
: `You asked Junior to remember this on ${shortDate(remembered)}.`
|
|
55
|
-
: `Junior recorded this on ${shortDate(remembered)}.`;
|
|
56
|
-
const scopeCopy = isPublic
|
|
57
|
-
? `It is stored as workspace ${kind.toLowerCase()} for future channels.`
|
|
58
|
-
: `It is stored as a ${kind.toLowerCase()} for future conversations.`;
|
|
59
|
-
const visibleMetadata = (record.metadata ?? []).filter(
|
|
60
|
-
(item) => !["Learned", "Source", "Memory ID"].includes(item.label),
|
|
61
|
-
);
|
|
62
|
-
const forgetAction = record.actions?.find(
|
|
63
|
-
(recordAction) => recordAction.tone === "danger",
|
|
64
|
-
);
|
|
65
|
-
const titleId = "memory-details-drawer-title";
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<Drawer
|
|
69
|
-
closeLabel="Close memory details"
|
|
70
|
-
header={
|
|
71
|
-
<>
|
|
72
|
-
<h2
|
|
73
|
-
className="m-0 font-display text-lg font-medium tracking-normal text-dashboard-text"
|
|
74
|
-
id={titleId}
|
|
75
|
-
>
|
|
76
|
-
What Junior remembers
|
|
77
|
-
</h2>
|
|
78
|
-
<div className="mt-1 break-words font-mono text-xs leading-snug text-dashboard-text-muted">
|
|
79
|
-
{kind} · {visibility} · {shortDate(remembered)}
|
|
80
|
-
</div>
|
|
81
|
-
</>
|
|
82
|
-
}
|
|
83
|
-
onClose={props.onClose}
|
|
84
|
-
openKey={record.id}
|
|
85
|
-
titleId={titleId}
|
|
86
|
-
>
|
|
87
|
-
<section className="grid gap-5">
|
|
88
|
-
<div>
|
|
89
|
-
<div className="mb-2 font-sans font-medium text-xs text-dashboard-text-muted">
|
|
90
|
-
Memory
|
|
91
|
-
</div>
|
|
92
|
-
<TranscriptText mentions={NO_MEMORY_MENTIONS} text={record.title} />
|
|
93
|
-
{record.description ? (
|
|
94
|
-
<div className="mt-3">
|
|
95
|
-
<TranscriptText
|
|
96
|
-
mentions={NO_MEMORY_MENTIONS}
|
|
97
|
-
text={record.description}
|
|
98
|
-
/>
|
|
99
|
-
</div>
|
|
100
|
-
) : null}
|
|
101
|
-
</div>
|
|
102
|
-
|
|
103
|
-
<div className="flex items-start gap-3 rounded-md border border-dashboard-accent/12 bg-dashboard-accent/[0.035] p-3">
|
|
104
|
-
<BrainCircuit
|
|
105
|
-
aria-hidden="true"
|
|
106
|
-
className="mt-0.5 shrink-0 text-dashboard-accent-text/70"
|
|
107
|
-
size={15}
|
|
108
|
-
/>
|
|
109
|
-
<div>
|
|
110
|
-
<div className="font-sans font-medium text-xs text-dashboard-accent-text/65">
|
|
111
|
-
Why Junior remembers this
|
|
112
|
-
</div>
|
|
113
|
-
<div className="mt-1 font-mono text-xs leading-relaxed text-dashboard-text">
|
|
114
|
-
{story} {scopeCopy}
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
|
|
119
|
-
{visibleMetadata.length ? (
|
|
120
|
-
<DetailList>
|
|
121
|
-
{visibleMetadata.map((item) => (
|
|
122
|
-
<Detail
|
|
123
|
-
key={item.label}
|
|
124
|
-
label={item.label}
|
|
125
|
-
valueClassName="font-mono"
|
|
126
|
-
>
|
|
127
|
-
{item.value}
|
|
128
|
-
</Detail>
|
|
129
|
-
))}
|
|
130
|
-
</DetailList>
|
|
131
|
-
) : null}
|
|
132
|
-
|
|
133
|
-
{forgetAction ? (
|
|
134
|
-
<button
|
|
135
|
-
className="inline-flex w-fit cursor-pointer items-center gap-2 rounded-md border border-rose-300/15 bg-rose-300/[0.035] px-3 py-2 font-sans font-medium text-xs text-rose-200/75 transition-colors hover:border-rose-300/30 hover:bg-rose-300/[0.07] hover:text-rose-100"
|
|
136
|
-
disabled={props.action.isPending}
|
|
137
|
-
onClick={() => {
|
|
138
|
-
if (
|
|
139
|
-
forgetAction.confirmation &&
|
|
140
|
-
!window.confirm(forgetAction.confirmation)
|
|
141
|
-
) {
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
props.onClose();
|
|
145
|
-
props.onAction({
|
|
146
|
-
...forgetAction,
|
|
147
|
-
confirmation: undefined,
|
|
148
|
-
});
|
|
149
|
-
}}
|
|
150
|
-
type="button"
|
|
151
|
-
>
|
|
152
|
-
<Trash2 aria-hidden="true" size={13} />
|
|
153
|
-
Forget this memory
|
|
154
|
-
</button>
|
|
155
|
-
) : null}
|
|
156
|
-
</section>
|
|
157
|
-
</Drawer>
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function metadataValue(record: PluginUserPageRecord, label: string): string {
|
|
162
|
-
return record.metadata?.find((item) => item.label === label)?.value ?? "—";
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function shortDate(value: string): string {
|
|
166
|
-
return value.split(",").slice(0, 2).join(",");
|
|
167
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { Cpu } from "lucide-react";
|
|
2
|
-
|
|
3
|
-
import { Detail, DetailList } from "../../components/DetailList";
|
|
4
|
-
import { Card } from "../../components/layout/Card";
|
|
5
|
-
|
|
6
|
-
/** Vercel Sandbox gives each vCPU 2 GB of memory. */
|
|
7
|
-
const MEMORY_GB_PER_VCPU = 2;
|
|
8
|
-
|
|
9
|
-
/** Format a Sandbox vCPU count with its memory. Null means the Vercel default. */
|
|
10
|
-
export function formatSandboxSize(vcpus: number | null): string {
|
|
11
|
-
if (vcpus === null) return "Vercel default";
|
|
12
|
-
return `${vcpus} vCPU${vcpus === 1 ? "" : "s"} · ${vcpus * MEMORY_GB_PER_VCPU} GB`;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** Show one Sandbox size in the shared System summary surface. */
|
|
16
|
-
export function SandboxSizeSummary(props: {
|
|
17
|
-
description: string;
|
|
18
|
-
headingId: string;
|
|
19
|
-
title: string;
|
|
20
|
-
value: string;
|
|
21
|
-
}) {
|
|
22
|
-
return (
|
|
23
|
-
<Card as="section" className="mb-0" padding="md" variant="section">
|
|
24
|
-
<div aria-labelledby={props.headingId} className="grid gap-4">
|
|
25
|
-
<div className="min-w-0 grid gap-1">
|
|
26
|
-
<h2
|
|
27
|
-
className="m-0 text-base font-semibold text-dashboard-text"
|
|
28
|
-
id={props.headingId}
|
|
29
|
-
>
|
|
30
|
-
{props.title}
|
|
31
|
-
</h2>
|
|
32
|
-
<p className="m-0 text-sm leading-relaxed text-dashboard-text-muted">
|
|
33
|
-
{props.description}
|
|
34
|
-
</p>
|
|
35
|
-
</div>
|
|
36
|
-
<DetailList>
|
|
37
|
-
<Detail label="Size">
|
|
38
|
-
<span className="inline-flex items-center gap-2">
|
|
39
|
-
<Cpu aria-hidden="true" size={14} />
|
|
40
|
-
{props.value}
|
|
41
|
-
</span>
|
|
42
|
-
</Detail>
|
|
43
|
-
</DetailList>
|
|
44
|
-
</div>
|
|
45
|
-
</Card>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { CalendarClock, Fingerprint, Layers3, Timer } from "lucide-react";
|
|
2
|
-
|
|
3
|
-
import { Detail, DetailList } from "../../components/DetailList";
|
|
4
|
-
import { Card } from "../../components/layout/Card";
|
|
5
|
-
import { formatMs, formatRelativeTime, formatTime } from "../../format";
|
|
6
|
-
|
|
7
|
-
type SnapshotSummaryValue = {
|
|
8
|
-
buildDurationMs: number;
|
|
9
|
-
dependencyCount?: number;
|
|
10
|
-
generatedAt: string;
|
|
11
|
-
id: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/** Show one reusable Sandbox snapshot in the shared System summary surface. */
|
|
15
|
-
export function SnapshotSummary(props: {
|
|
16
|
-
description: string;
|
|
17
|
-
emptyDescription: string;
|
|
18
|
-
headingId: string;
|
|
19
|
-
snapshot: SnapshotSummaryValue | null;
|
|
20
|
-
title: string;
|
|
21
|
-
}) {
|
|
22
|
-
const snapshot = props.snapshot;
|
|
23
|
-
const gridClassName =
|
|
24
|
-
snapshot?.dependencyCount == null
|
|
25
|
-
? "sm:grid-cols-3"
|
|
26
|
-
: "sm:grid-cols-2 lg:grid-cols-4";
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<Card as="section" className="mb-0" padding="md" variant="section">
|
|
30
|
-
<div aria-labelledby={props.headingId} className="grid gap-4">
|
|
31
|
-
<div className="min-w-0 grid gap-1">
|
|
32
|
-
<h2
|
|
33
|
-
className="m-0 text-base font-semibold text-dashboard-text"
|
|
34
|
-
id={props.headingId}
|
|
35
|
-
>
|
|
36
|
-
{props.title}
|
|
37
|
-
</h2>
|
|
38
|
-
<p className="m-0 text-sm leading-relaxed text-dashboard-text-muted">
|
|
39
|
-
{snapshot ? props.description : props.emptyDescription}
|
|
40
|
-
</p>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
{snapshot ? (
|
|
44
|
-
<DetailList className={gridClassName}>
|
|
45
|
-
<Detail label="Generated">
|
|
46
|
-
<span className="inline-flex items-center gap-2">
|
|
47
|
-
<CalendarClock aria-hidden="true" size={14} />
|
|
48
|
-
<span title={formatTime(snapshot.generatedAt)}>
|
|
49
|
-
{formatRelativeTime(snapshot.generatedAt)}
|
|
50
|
-
</span>
|
|
51
|
-
</span>
|
|
52
|
-
</Detail>
|
|
53
|
-
<Detail label="Build time">
|
|
54
|
-
<span className="inline-flex items-center gap-2">
|
|
55
|
-
<Timer aria-hidden="true" size={14} />
|
|
56
|
-
{formatMs(snapshot.buildDurationMs)}
|
|
57
|
-
</span>
|
|
58
|
-
</Detail>
|
|
59
|
-
{snapshot.dependencyCount == null ? null : (
|
|
60
|
-
<Detail label="Dependencies">
|
|
61
|
-
<span className="inline-flex items-center gap-2">
|
|
62
|
-
<Layers3 aria-hidden="true" size={14} />
|
|
63
|
-
{snapshot.dependencyCount}
|
|
64
|
-
</span>
|
|
65
|
-
</Detail>
|
|
66
|
-
)}
|
|
67
|
-
<Detail label="Snapshot ID" valueClassName="font-mono text-xs">
|
|
68
|
-
<span className="inline-flex items-center gap-2 break-all">
|
|
69
|
-
<Fingerprint aria-hidden="true" className="shrink-0" size={14} />
|
|
70
|
-
{snapshot.id}
|
|
71
|
-
</span>
|
|
72
|
-
</Detail>
|
|
73
|
-
</DetailList>
|
|
74
|
-
) : null}
|
|
75
|
-
</div>
|
|
76
|
-
</Card>
|
|
77
|
-
);
|
|
78
|
-
}
|