@sentry/junior-dashboard 0.264.0 → 0.266.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/ActorAvatar.tsx +10 -22
- package/src/client/components/BottomSheet.tsx +12 -2
- package/src/client/components/ConnectionBanner.tsx +4 -3
- package/src/client/components/CopyButton.tsx +82 -0
- package/src/client/components/DetailsPanel.tsx +133 -0
- package/src/client/components/Drawer.tsx +15 -24
- package/src/client/components/EmptyTelemetry.tsx +5 -3
- package/src/client/components/FilterBar.tsx +16 -31
- package/src/client/components/ImageAttachment.tsx +49 -63
- package/src/client/components/InlineError.tsx +8 -4
- package/src/client/components/Metric.tsx +33 -23
- package/src/client/components/Notice.tsx +19 -26
- package/src/client/components/PageContentSkeleton.tsx +1 -1
- package/src/client/components/Pagination.tsx +27 -27
- package/src/client/components/ParticipantAvatarStack.tsx +43 -39
- package/src/client/components/ProfileMenu.tsx +27 -93
- package/src/client/components/README.md +103 -78
- package/src/client/components/SearchInput.tsx +51 -41
- 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/VersionDriftBanner.tsx +9 -7
- package/src/client/components/charts/ActivityChart.tsx +173 -288
- package/src/client/components/charts/CacheWrites.tsx +59 -37
- 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/alert.tsx +64 -0
- package/src/client/components/ui/avatar.tsx +53 -0
- package/src/client/components/ui/button.tsx +86 -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/dialog.tsx +66 -0
- package/src/client/components/ui/empty.tsx +32 -0
- package/src/client/components/ui/field.tsx +49 -0
- package/src/client/components/ui/input-group.tsx +96 -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/pagination.tsx +60 -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/spinner.tsx +21 -0
- package/src/client/components/ui/table.tsx +101 -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/ConversationChildAgents.tsx +5 -5
- 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 +13 -7
- package/src/client/conversations/ConversationHeaderActions.tsx +97 -93
- 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 +49 -29
- package/src/client/conversations/ConversationUsageBreakdown.tsx +108 -65
- package/src/client/conversations/ConversationWatches.tsx +173 -0
- package/src/client/conversations/ConversationWorkspace.tsx +12 -22
- package/src/client/conversations/ConversationWorkspaceLoading.tsx +1 -1
- package/src/client/conversations/DetailsList.tsx +139 -0
- package/src/client/conversations/EventDetails.tsx +42 -8
- package/src/client/conversations/EventUsage.tsx +99 -74
- package/src/client/conversations/ForkConversationButton.tsx +27 -16
- package/src/client/conversations/ObjectCard.tsx +20 -8
- package/src/client/conversations/PendingMailboxStack.tsx +52 -38
- package/src/client/conversations/README.md +89 -13
- package/src/client/conversations/ShareConversationButton.tsx +28 -17
- 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/TranscriptEventView.tsx +35 -16
- 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 +35 -18
- package/src/client/conversations/TranscriptMessageView.tsx +6 -1
- package/src/client/conversations/TranscriptReasoningView.tsx +54 -68
- package/src/client/conversations/TranscriptStructuredEventView.tsx +25 -15
- package/src/client/conversations/TranscriptSummary.tsx +34 -2
- package/src/client/conversations/TranscriptTimestamp.tsx +9 -7
- package/src/client/conversations/TranscriptToolView.tsx +1 -1
- package/src/client/conversations/TranscriptTurnContextView.tsx +144 -65
- package/src/client/conversations/TranscriptView.tsx +63 -27
- package/src/client/conversations/eventLog.ts +58 -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/conversations/transcriptMentions.tsx +18 -5
- 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
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
useContext,
|
|
6
|
+
useId,
|
|
7
|
+
useState,
|
|
8
|
+
useSyncExternalStore,
|
|
9
|
+
type ComponentProps,
|
|
10
|
+
} from "react";
|
|
11
|
+
import { cn } from "@dashboard/lib/utils";
|
|
12
|
+
|
|
13
|
+
/** Open dashboard tooltips at once and keep them open briefly for the pointer to reach them. */
|
|
14
|
+
function TooltipProvider({
|
|
15
|
+
delay = 0,
|
|
16
|
+
closeDelay = 150,
|
|
17
|
+
...props
|
|
18
|
+
}: TooltipPrimitive.Provider.Props) {
|
|
19
|
+
return (
|
|
20
|
+
<TooltipPrimitive.Provider
|
|
21
|
+
data-slot="tooltip-provider"
|
|
22
|
+
delay={delay}
|
|
23
|
+
closeDelay={closeDelay}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Link the open popup to its trigger. Base UI leaves this to the app. */
|
|
30
|
+
const TooltipDescriptionContext = createContext<string | undefined>(undefined);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Wide screens with a fine hover pointer show tooltips. On smaller or touch
|
|
34
|
+
* screens, a tooltip can cover the menu that its trigger opens.
|
|
35
|
+
*/
|
|
36
|
+
const TOOLTIP_MEDIA_QUERY =
|
|
37
|
+
"(min-width: 768px) and (hover: hover) and (pointer: fine)";
|
|
38
|
+
|
|
39
|
+
function subscribeToTooltipMedia(onChange: () => void) {
|
|
40
|
+
const media = window.matchMedia(TOOLTIP_MEDIA_QUERY);
|
|
41
|
+
media.addEventListener("change", onChange);
|
|
42
|
+
return () => media.removeEventListener("change", onChange);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function tooltipMediaMatches() {
|
|
46
|
+
return window.matchMedia(TOOLTIP_MEDIA_QUERY).matches;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Own one tooltip's open state. It stays off where tooltips are not shown. */
|
|
50
|
+
function Tooltip({
|
|
51
|
+
disabled,
|
|
52
|
+
onOpenChange,
|
|
53
|
+
open: openProp,
|
|
54
|
+
...props
|
|
55
|
+
}: TooltipPrimitive.Root.Props) {
|
|
56
|
+
const available = useSyncExternalStore(
|
|
57
|
+
subscribeToTooltipMedia,
|
|
58
|
+
tooltipMediaMatches,
|
|
59
|
+
() => false,
|
|
60
|
+
);
|
|
61
|
+
const id = useId();
|
|
62
|
+
const [openState, setOpenState] = useState(props.defaultOpen ?? false);
|
|
63
|
+
const open = available && (openProp ?? openState);
|
|
64
|
+
return (
|
|
65
|
+
<TooltipDescriptionContext.Provider value={open ? id : undefined}>
|
|
66
|
+
<TooltipPrimitive.Root
|
|
67
|
+
data-slot="tooltip"
|
|
68
|
+
disabled={disabled || !available}
|
|
69
|
+
onOpenChange={(next, details) => {
|
|
70
|
+
setOpenState(next);
|
|
71
|
+
onOpenChange?.(next, details);
|
|
72
|
+
}}
|
|
73
|
+
open={openProp}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
</TooltipDescriptionContext.Provider>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Show the tooltip on mouse hover or keyboard focus. Touch does not open it.
|
|
82
|
+
* A click keeps it open, so copy and share feedback stays visible.
|
|
83
|
+
*/
|
|
84
|
+
function TooltipTrigger({
|
|
85
|
+
closeOnClick = false,
|
|
86
|
+
...props
|
|
87
|
+
}: TooltipPrimitive.Trigger.Props) {
|
|
88
|
+
const describedBy = useContext(TooltipDescriptionContext);
|
|
89
|
+
return (
|
|
90
|
+
<TooltipPrimitive.Trigger
|
|
91
|
+
aria-describedby={describedBy}
|
|
92
|
+
closeOnClick={closeOnClick}
|
|
93
|
+
data-slot="tooltip-trigger"
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const tooltipContentVariants = cva(
|
|
100
|
+
"z-50 select-text rounded-md border border-dashboard-border-emphasis bg-dashboard-surface-raised font-sans text-xs shadow-2xl shadow-black/70 outline-none",
|
|
101
|
+
{
|
|
102
|
+
variants: {
|
|
103
|
+
size: {
|
|
104
|
+
/** Selectable detail cards, such as chart buckets and metric breakdowns. */
|
|
105
|
+
default:
|
|
106
|
+
"min-w-36 max-w-lg px-3 py-2 leading-relaxed text-dashboard-text-muted",
|
|
107
|
+
/** One short label for an icon-only control. */
|
|
108
|
+
compact: "px-2.5 py-1.5 leading-none text-dashboard-text",
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
defaultVariants: { size: "default" },
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
/** Show tooltip text beside its trigger and keep it inside the viewport. */
|
|
116
|
+
function TooltipContent({
|
|
117
|
+
className,
|
|
118
|
+
side = "top",
|
|
119
|
+
sideOffset = 10,
|
|
120
|
+
align = "center",
|
|
121
|
+
size,
|
|
122
|
+
children,
|
|
123
|
+
...props
|
|
124
|
+
}: TooltipPrimitive.Popup.Props &
|
|
125
|
+
Pick<TooltipPrimitive.Positioner.Props, "align" | "side" | "sideOffset"> &
|
|
126
|
+
VariantProps<typeof tooltipContentVariants>) {
|
|
127
|
+
const id = useContext(TooltipDescriptionContext);
|
|
128
|
+
return (
|
|
129
|
+
<TooltipPrimitive.Portal>
|
|
130
|
+
<TooltipPrimitive.Positioner
|
|
131
|
+
align={align}
|
|
132
|
+
collisionPadding={8}
|
|
133
|
+
side={side}
|
|
134
|
+
sideOffset={sideOffset}
|
|
135
|
+
className="isolate z-50 data-anchor-hidden:invisible"
|
|
136
|
+
>
|
|
137
|
+
<TooltipPrimitive.Popup
|
|
138
|
+
data-slot="tooltip-content"
|
|
139
|
+
id={id}
|
|
140
|
+
role="tooltip"
|
|
141
|
+
className={cn(tooltipContentVariants({ size }), className)}
|
|
142
|
+
{...props}
|
|
143
|
+
>
|
|
144
|
+
{children}
|
|
145
|
+
</TooltipPrimitive.Popup>
|
|
146
|
+
</TooltipPrimitive.Positioner>
|
|
147
|
+
</TooltipPrimitive.Portal>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Name what a detail tooltip describes, such as a chart bucket date. */
|
|
152
|
+
function TooltipTitle({ className, ...props }: ComponentProps<"div">) {
|
|
153
|
+
return (
|
|
154
|
+
<div
|
|
155
|
+
className={cn("mb-1 font-semibold text-dashboard-text-muted", className)}
|
|
156
|
+
{...props}
|
|
157
|
+
/>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export {
|
|
162
|
+
Tooltip,
|
|
163
|
+
TooltipTrigger,
|
|
164
|
+
TooltipContent,
|
|
165
|
+
TooltipTitle,
|
|
166
|
+
TooltipProvider,
|
|
167
|
+
tooltipContentVariants,
|
|
168
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "@dashboard/lib/utils";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
Collapsible,
|
|
6
|
+
CollapsibleContent,
|
|
7
|
+
CollapsibleTrigger,
|
|
8
|
+
} from "@dashboard/components/ui/collapsible";
|
|
9
|
+
import { ChevronRightIcon } from "lucide-react";
|
|
10
|
+
|
|
11
|
+
function TraceIcon({ className, ...props }: React.ComponentProps<"span">) {
|
|
12
|
+
return (
|
|
13
|
+
<span
|
|
14
|
+
data-slot="trace-icon"
|
|
15
|
+
aria-hidden="true"
|
|
16
|
+
className={cn(
|
|
17
|
+
"flex size-4 shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
|
|
18
|
+
className,
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Keep one trace row and its details in one open state. */
|
|
26
|
+
function TraceCollapsible({
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}: Omit<React.ComponentProps<typeof Collapsible>, "open"> &
|
|
30
|
+
(
|
|
31
|
+
| { open?: undefined }
|
|
32
|
+
| {
|
|
33
|
+
open: boolean;
|
|
34
|
+
onOpenChange: NonNullable<
|
|
35
|
+
React.ComponentProps<typeof Collapsible>["onOpenChange"]
|
|
36
|
+
>;
|
|
37
|
+
}
|
|
38
|
+
)) {
|
|
39
|
+
return (
|
|
40
|
+
<Collapsible
|
|
41
|
+
data-slot="trace-collapsible"
|
|
42
|
+
className={cn("flex w-full min-w-0 flex-col", className)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Render the row button with a chevron that turns while open. */
|
|
49
|
+
function TraceCollapsibleTrigger({
|
|
50
|
+
className,
|
|
51
|
+
children,
|
|
52
|
+
...props
|
|
53
|
+
}: React.ComponentProps<typeof CollapsibleTrigger>) {
|
|
54
|
+
return (
|
|
55
|
+
<CollapsibleTrigger
|
|
56
|
+
data-slot="trace-collapsible-trigger"
|
|
57
|
+
className={cn(
|
|
58
|
+
"group/trace-collapsible-trigger flex w-fit max-w-full min-w-0 cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-left text-dashboard-text-muted transition-colors outline-none hover:bg-dashboard-fill-hover focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-dashboard-focus disabled:cursor-default disabled:hover:bg-transparent",
|
|
59
|
+
className,
|
|
60
|
+
)}
|
|
61
|
+
{...props}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
<TraceIcon className="transition-transform group-aria-expanded/trace-collapsible-trigger:rotate-90 motion-reduce:transition-none">
|
|
65
|
+
<ChevronRightIcon className="size-3 text-dashboard-text-faint" />
|
|
66
|
+
</TraceIcon>
|
|
67
|
+
</CollapsibleTrigger>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Reveal row details in a card under the row title. */
|
|
72
|
+
function TraceCollapsibleContent({
|
|
73
|
+
className,
|
|
74
|
+
children,
|
|
75
|
+
...props
|
|
76
|
+
}: React.ComponentProps<typeof CollapsibleContent>) {
|
|
77
|
+
return (
|
|
78
|
+
<CollapsibleContent
|
|
79
|
+
data-slot="trace-collapsible-content"
|
|
80
|
+
className="h-(--collapsible-panel-height) min-w-0 overflow-hidden transition-[height] duration-200 data-ending-style:h-0 data-starting-style:h-0 motion-reduce:transition-none"
|
|
81
|
+
{...props}
|
|
82
|
+
>
|
|
83
|
+
<div
|
|
84
|
+
data-slot="trace-collapsible-content-inner"
|
|
85
|
+
className={cn(
|
|
86
|
+
"mt-1.5 ml-6 min-w-0 overflow-hidden rounded-md border border-dashboard-border-subtle bg-dashboard-surface-panel",
|
|
87
|
+
className,
|
|
88
|
+
)}
|
|
89
|
+
>
|
|
90
|
+
{children}
|
|
91
|
+
</div>
|
|
92
|
+
</CollapsibleContent>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { TraceCollapsible, TraceCollapsibleTrigger, TraceCollapsibleContent };
|
|
@@ -5,12 +5,14 @@ import { cn } from "../styles";
|
|
|
5
5
|
/**
|
|
6
6
|
* Own the conversation chat frame: one scroll region above one dock.
|
|
7
7
|
*
|
|
8
|
-
* Pages pass `scroll
|
|
8
|
+
* Pages pass `header`, `scroll`, and `dock`. Do not invent footer padding, safe-area,
|
|
9
9
|
* or shell height math outside this component and `ComposerDock`.
|
|
10
10
|
*/
|
|
11
11
|
export function ChatLayout(props: {
|
|
12
12
|
className?: string;
|
|
13
13
|
dock?: ReactNode;
|
|
14
|
+
/** Keep conversation chrome outside the scrolling content. */
|
|
15
|
+
header?: ReactNode;
|
|
14
16
|
/** When true, keep a taller minimum scroll region for long transcripts. */
|
|
15
17
|
scrollMinTall?: boolean;
|
|
16
18
|
scroll: ReactNode;
|
|
@@ -20,11 +22,13 @@ export function ChatLayout(props: {
|
|
|
20
22
|
return (
|
|
21
23
|
<div
|
|
22
24
|
className={cn(
|
|
23
|
-
"grid h-full min-h-0 min-w-0 grid-rows-[
|
|
24
|
-
props.scrollMinTall &&
|
|
25
|
+
"grid h-full min-h-0 min-w-0 grid-rows-[auto_minmax(0,1fr)_minmax(0,auto)]",
|
|
26
|
+
props.scrollMinTall &&
|
|
27
|
+
"grid-rows-[auto_minmax(7rem,1fr)_minmax(0,auto)]",
|
|
25
28
|
props.className,
|
|
26
29
|
)}
|
|
27
30
|
>
|
|
31
|
+
<div className="min-w-0">{props.header}</div>
|
|
28
32
|
<div
|
|
29
33
|
aria-label={props.scrollAriaLabel}
|
|
30
34
|
className={cn(
|
|
@@ -4,7 +4,13 @@ import type { ConversationDetailReport } from "@sentry/junior/api/schema";
|
|
|
4
4
|
|
|
5
5
|
import { Detail, DetailList } from "../components/DetailList";
|
|
6
6
|
import { StatusChip, type StatusChipTone } from "../components/StatusChip";
|
|
7
|
+
import {
|
|
8
|
+
Collapsible,
|
|
9
|
+
CollapsibleContent,
|
|
10
|
+
CollapsibleTrigger,
|
|
11
|
+
} from "../components/ui/collapsible";
|
|
7
12
|
import { formatTime } from "../format";
|
|
13
|
+
import { cn, dashboardDisclosureChevronClass } from "../styles";
|
|
8
14
|
import { MentionPeopleProvider, renderMentionText } from "./transcriptMentions";
|
|
9
15
|
|
|
10
16
|
type ConversationBriefReport = NonNullable<ConversationDetailReport["brief"]>;
|
|
@@ -160,16 +166,21 @@ function BriefContentView(props: {
|
|
|
160
166
|
|
|
161
167
|
function BriefSection(props: { children: ReactNode; title: string }) {
|
|
162
168
|
return (
|
|
163
|
-
<
|
|
164
|
-
<
|
|
169
|
+
<Collapsible className="min-w-0 border-t border-dashboard-border pt-3">
|
|
170
|
+
<CollapsibleTrigger className="group flex w-full cursor-pointer items-center gap-2 text-left text-sm font-medium text-dashboard-text focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus">
|
|
165
171
|
<ChevronRight
|
|
166
172
|
aria-hidden="true"
|
|
167
|
-
className=
|
|
173
|
+
className={cn(
|
|
174
|
+
dashboardDisclosureChevronClass,
|
|
175
|
+
"text-dashboard-text-muted",
|
|
176
|
+
)}
|
|
168
177
|
/>
|
|
169
178
|
{props.title}
|
|
170
|
-
</
|
|
171
|
-
<
|
|
172
|
-
|
|
179
|
+
</CollapsibleTrigger>
|
|
180
|
+
<CollapsibleContent hiddenUntilFound>
|
|
181
|
+
<div className="mt-3">{props.children}</div>
|
|
182
|
+
</CollapsibleContent>
|
|
183
|
+
</Collapsible>
|
|
173
184
|
);
|
|
174
185
|
}
|
|
175
186
|
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
CircleDot,
|
|
8
8
|
CirclePause,
|
|
9
9
|
CircleX,
|
|
10
|
-
LoaderCircle,
|
|
11
10
|
LockKeyhole,
|
|
12
11
|
type LucideIcon,
|
|
13
12
|
} from "lucide-react";
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
} from "@sentry/junior/api/schema";
|
|
18
17
|
|
|
19
18
|
import type { StatusChipTone } from "../components/StatusChip";
|
|
19
|
+
import { Spinner } from "../components/ui/spinner";
|
|
20
20
|
import {
|
|
21
21
|
formatConversationCostTotal,
|
|
22
22
|
formatRuntime,
|
|
@@ -115,7 +115,6 @@ const statusIcons: Partial<Record<string, LucideIcon>> = {
|
|
|
115
115
|
error: CircleX,
|
|
116
116
|
failed: CircleX,
|
|
117
117
|
paused: CirclePause,
|
|
118
|
-
running: LoaderCircle,
|
|
119
118
|
};
|
|
120
119
|
|
|
121
120
|
const statusIconToneClass: Record<StatusChipTone, string> = {
|
|
@@ -129,7 +128,10 @@ const statusIconToneClass: Record<StatusChipTone, string> = {
|
|
|
129
128
|
|
|
130
129
|
/** Mark a child agent status with one icon and an audible label. */
|
|
131
130
|
function ChildAgentStatusIcon(props: { status: string }) {
|
|
132
|
-
const Icon =
|
|
131
|
+
const Icon =
|
|
132
|
+
props.status === "running"
|
|
133
|
+
? Spinner
|
|
134
|
+
: (statusIcons[props.status] ?? Circle);
|
|
133
135
|
return (
|
|
134
136
|
<span className="mt-px grid size-4 shrink-0 place-items-center">
|
|
135
137
|
<Icon
|
|
@@ -137,8 +139,6 @@ function ChildAgentStatusIcon(props: { status: string }) {
|
|
|
137
139
|
className={cn(
|
|
138
140
|
"size-3.5",
|
|
139
141
|
statusIconToneClass[subagentStatusTone(props.status)],
|
|
140
|
-
props.status === "running" &&
|
|
141
|
-
"animate-spin motion-reduce:animate-none",
|
|
142
142
|
)}
|
|
143
143
|
/>
|
|
144
144
|
<span className="sr-only">{props.status}</span>
|
|
@@ -12,7 +12,12 @@ import {
|
|
|
12
12
|
} from "react";
|
|
13
13
|
import { ImagePlus, Send, Square } from "lucide-react";
|
|
14
14
|
|
|
15
|
-
import { Button } from "../components/
|
|
15
|
+
import { Button } from "../components/ui/button";
|
|
16
|
+
import {
|
|
17
|
+
Tooltip,
|
|
18
|
+
TooltipContent,
|
|
19
|
+
TooltipTrigger,
|
|
20
|
+
} from "../components/ui/tooltip";
|
|
16
21
|
import { useDashboardOnline } from "../connection";
|
|
17
22
|
import { cn, dashboardComposerSurfaceClass } from "../styles";
|
|
18
23
|
|
|
@@ -447,16 +452,25 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
447
452
|
)}
|
|
448
453
|
>
|
|
449
454
|
<div className="flex min-w-0 items-center gap-3">
|
|
450
|
-
<
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
455
|
+
<Tooltip>
|
|
456
|
+
<TooltipTrigger
|
|
457
|
+
render={
|
|
458
|
+
<Button
|
|
459
|
+
focusableWhenDisabled
|
|
460
|
+
aria-label="Attach images"
|
|
461
|
+
disabled={sendLocked || readingImages}
|
|
462
|
+
onClick={() => fileInputRef.current?.click()}
|
|
463
|
+
size="icon"
|
|
464
|
+
type="button"
|
|
465
|
+
>
|
|
466
|
+
<ImagePlus aria-hidden="true" size={16} />
|
|
467
|
+
</Button>
|
|
468
|
+
}
|
|
469
|
+
/>
|
|
470
|
+
<TooltipContent size="compact">
|
|
471
|
+
Attach images (up to 3 MB total)
|
|
472
|
+
</TooltipContent>
|
|
473
|
+
</Tooltip>
|
|
460
474
|
{props.footerStart}
|
|
461
475
|
{props.footerStart ? null : (
|
|
462
476
|
<div className="hidden min-w-0 font-sans text-xs leading-relaxed text-dashboard-text-muted md:block">
|
|
@@ -488,7 +502,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
488
502
|
readingImages
|
|
489
503
|
}
|
|
490
504
|
title={sendLocked ? "Sending message" : props.submitLabel}
|
|
491
|
-
|
|
505
|
+
variant="primary"
|
|
492
506
|
type="submit"
|
|
493
507
|
>
|
|
494
508
|
<Send aria-hidden="true" size={14} />
|