@sentry/junior-dashboard 0.247.0 → 0.249.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/dist/app.js +69 -15
- package/dist/client.js +51 -50
- package/dist/index.js +69 -15
- package/dist/tailwind.css +1 -1
- package/package.json +3 -3
- package/src/client/App.tsx +1 -5
- package/src/client/components/ActorAvatar.tsx +7 -4
- package/src/client/components/AutomationCard.tsx +2 -2
- package/src/client/components/Button.tsx +12 -11
- package/src/client/components/ConversationList.tsx +3 -3
- package/src/client/components/ConversationSummary.tsx +2 -1
- package/src/client/components/DetailList.tsx +3 -3
- package/src/client/components/Drawer.tsx +2 -2
- package/src/client/components/EmptyTelemetry.tsx +1 -1
- package/src/client/components/Field.tsx +1 -2
- package/src/client/components/FilterBar.tsx +6 -6
- package/src/client/components/Metric.tsx +11 -16
- package/src/client/components/Notice.tsx +7 -7
- package/src/client/components/PageContentSkeleton.tsx +2 -2
- package/src/client/components/Pagination.tsx +2 -2
- package/src/client/components/ParticipantAvatarStack.tsx +4 -4
- package/src/client/components/ProfileMenu.tsx +5 -7
- package/src/client/components/README.md +122 -58
- package/src/client/components/SearchInput.tsx +4 -3
- package/src/client/components/SegmentedNav.tsx +10 -17
- package/src/client/components/SegmentedTabs.tsx +3 -3
- package/src/client/components/Select.tsx +1 -1
- package/src/client/components/SelectableRow.tsx +2 -2
- package/src/client/components/Skeleton.tsx +1 -1
- package/src/client/components/StatusChip.tsx +1 -1
- package/src/client/components/StatusDot.tsx +1 -1
- package/src/client/components/TextInput.tsx +1 -1
- package/src/client/components/Tooltip.tsx +2 -2
- package/src/client/components/VersionDriftBanner.tsx +2 -2
- package/src/client/components/charts/ActivityChart.tsx +5 -6
- package/src/client/components/charts/CacheWrites.tsx +3 -3
- package/src/client/components/charts/ChartHeader.tsx +4 -4
- package/src/client/components/charts/ChartLegend.tsx +1 -1
- package/src/client/components/charts/InputCacheChart.tsx +5 -5
- package/src/client/components/charts/WorkspaceUsageChart.tsx +4 -11
- package/src/client/components/controls/DirectorySortSelect.tsx +2 -2
- package/src/client/components/directory/DirectoryMetric.tsx +2 -2
- package/src/client/components/directory/DirectoryRowsSkeleton.tsx +5 -5
- package/src/client/components/directory/DirectoryTable.tsx +3 -3
- package/src/client/components/layout/CardHeader.tsx +4 -4
- package/src/client/components/layout/DashboardChrome.tsx +9 -3
- package/src/client/components/layout/DashboardHeader.tsx +7 -7
- package/src/client/components/layout/PageHeader.tsx +2 -2
- package/src/client/components/layout/SecondaryNavigation.tsx +7 -14
- package/src/client/components/layout/SectionIntro.tsx +1 -1
- package/src/client/components/layout/SectionTitle.tsx +1 -1
- package/src/client/components/metrics/StatCard.tsx +2 -2
- package/src/client/conversations/ConversationArchiveNotices.tsx +1 -1
- package/src/client/conversations/ConversationBrief.tsx +4 -4
- package/src/client/conversations/ConversationChildAgents.tsx +13 -4
- package/src/client/conversations/ConversationComposer.tsx +8 -7
- package/src/client/conversations/ConversationHeader.tsx +5 -5
- package/src/client/conversations/ConversationHeaderActions.tsx +9 -9
- package/src/client/conversations/ConversationHomeList.tsx +3 -3
- package/src/client/conversations/ConversationListStatusIcon.tsx +1 -1
- package/src/client/conversations/ConversationMemories.tsx +4 -4
- package/src/client/conversations/ConversationMeta.tsx +30 -11
- package/src/client/conversations/ConversationPage.tsx +13 -5
- package/src/client/conversations/ConversationSidebar.tsx +6 -6
- package/src/client/conversations/ConversationUsageBreakdown.tsx +278 -0
- package/src/client/conversations/ConversationWorkspace.tsx +1 -1
- package/src/client/conversations/ConversationWorkspaceLoading.tsx +4 -4
- package/src/client/conversations/CopyMarkdownButton.tsx +1 -1
- package/src/client/conversations/EventUsage.tsx +2 -2
- package/src/client/conversations/PendingMailboxStack.tsx +5 -5
- package/src/client/conversations/README.md +9 -0
- package/src/client/conversations/SubagentTranscriptDrawer.tsx +39 -23
- package/src/client/conversations/TelemetryMetrics.tsx +327 -180
- package/src/client/conversations/ToolFrame.tsx +36 -14
- package/src/client/conversations/TranscriptActivityGroup.tsx +10 -3
- package/src/client/conversations/TranscriptAttachmentsDeliveredView.tsx +4 -6
- package/src/client/conversations/TranscriptContextEventView.tsx +2 -2
- package/src/client/conversations/TranscriptEventView.tsx +1 -1
- package/src/client/conversations/TranscriptMarkdown.tsx +3 -3
- package/src/client/conversations/TranscriptMessageContextView.tsx +7 -7
- package/src/client/conversations/TranscriptMessageView.tsx +2 -6
- package/src/client/conversations/TranscriptRailEvent.tsx +20 -8
- package/src/client/conversations/TranscriptReasoningView.tsx +12 -12
- package/src/client/conversations/TranscriptStructuredEventView.tsx +16 -11
- package/src/client/conversations/TranscriptSubagentView.tsx +64 -39
- package/src/client/conversations/TranscriptText.tsx +5 -4
- package/src/client/conversations/TranscriptToolView.tsx +9 -11
- package/src/client/conversations/TranscriptTurnContextView.tsx +3 -3
- package/src/client/conversations/TranscriptView.tsx +3 -3
- package/src/client/conversations/UsageCard.tsx +172 -0
- package/src/client/conversations/eventTranscript.ts +7 -0
- package/src/client/conversations/transcriptMarkdownLinks.ts +2 -4
- package/src/client/conversations/transcriptStyles.ts +1 -1
- package/src/client/format.ts +1 -0
- package/src/client/pages/PersonalTokensPage.tsx +4 -4
- package/src/client/pages/admin/AdminPage.tsx +2 -2
- package/src/client/pages/automations/AutomationCostChart.tsx +2 -2
- package/src/client/pages/automations/AutomationDetailsDrawer.tsx +5 -10
- package/src/client/pages/automations/AutomationEditor.tsx +1 -1
- package/src/client/pages/automations/AutomationExecutionChart.tsx +2 -2
- package/src/client/pages/automations/AutomationExecutionStatusChart.tsx +2 -2
- package/src/client/pages/automations/AutomationExecutionsPage.tsx +4 -4
- package/src/client/pages/automations/AutomationRow.tsx +4 -4
- package/src/client/pages/automations/AutomationRunsPage.tsx +3 -3
- package/src/client/pages/automations/AutomationScheduleFields.tsx +1 -1
- package/src/client/pages/automations/AutomationVersionsPage.tsx +1 -1
- package/src/client/pages/code/CodeActivityChart.tsx +7 -6
- package/src/client/pages/code/CodeChangeRow.tsx +1 -1
- package/src/client/pages/code/CodePage.tsx +5 -5
- package/src/client/pages/code/RepositoryPage.tsx +2 -2
- package/src/client/pages/dev/ComponentsPage.tsx +40 -146
- package/src/client/pages/dev/TranscriptActivityFixtures.tsx +206 -0
- package/src/client/pages/locations/LocationDetailPage.tsx +4 -4
- package/src/client/pages/locations/LocationDirectory.tsx +1 -1
- package/src/client/pages/locations/PrivateActivityCard.tsx +3 -3
- package/src/client/pages/memory/MemoryCostChart.tsx +3 -5
- package/src/client/pages/memory/MemoryDetailsDrawer.tsx +5 -5
- package/src/client/pages/memory/MemoryPage.tsx +15 -15
- package/src/client/pages/memory/MemoryTimeline.tsx +3 -5
- package/src/client/pages/people/ContributionGrid.tsx +8 -5
- package/src/client/pages/people/PersonProfilePage.tsx +3 -6
- package/src/client/pages/people/ProfilePluginReports.tsx +2 -2
- package/src/client/pages/system/GuardianActivity.tsx +9 -9
- package/src/client/pages/system/PluginBarChart.tsx +4 -6
- package/src/client/pages/system/PluginDetails.tsx +11 -7
- package/src/client/pages/system/PluginPanels.tsx +8 -8
- package/src/client/pages/system/PluginReportRecordSet.tsx +14 -14
- package/src/client/pages/system/PluginReports.tsx +7 -11
- package/src/client/pages/system/SkillInventory.tsx +9 -9
- package/src/client/pages/system/SystemActivity.tsx +1 -1
- package/src/client/pages/system/SystemPage.tsx +3 -6
- package/src/client/pages/system/WorkspaceDetails.tsx +2 -5
- package/src/client/pages/system/WorkspaceEditor.tsx +2 -2
- package/src/client/pages/system/WorkspaceList.tsx +2 -2
- package/src/client/pages/user/PluginUserPage.tsx +3 -3
- package/src/client/styles.ts +5 -4
- package/src/client/types.ts +3 -0
- package/src/mock-reporting/fixtures.ts +73 -14
- package/src/tailwind.css +36 -38
|
@@ -16,7 +16,7 @@ export function SectionIntro(props: {
|
|
|
16
16
|
{props.title}
|
|
17
17
|
</h2>
|
|
18
18
|
{props.description ? (
|
|
19
|
-
<p className="mt-1.5 mb-0 max-w-2xl font-
|
|
19
|
+
<p className="mt-1.5 mb-0 max-w-2xl font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
20
20
|
{props.description}
|
|
21
21
|
</p>
|
|
22
22
|
) : null}
|
|
@@ -3,7 +3,7 @@ import type { ReactNode } from "react";
|
|
|
3
3
|
/** Render compact section titles that fit inside operational panels. */
|
|
4
4
|
export function SectionTitle(props: { children: ReactNode }) {
|
|
5
5
|
return (
|
|
6
|
-
<div className="min-w-0 break-words font-
|
|
6
|
+
<div className="min-w-0 break-words font-sans text-xs font-medium leading-tight text-dashboard-text-muted">
|
|
7
7
|
{props.children}
|
|
8
8
|
</div>
|
|
9
9
|
);
|
|
@@ -14,7 +14,7 @@ export function StatCard(props: {
|
|
|
14
14
|
return (
|
|
15
15
|
<Card className="relative p-4 sm:p-5">
|
|
16
16
|
<div className="flex items-start justify-between gap-4">
|
|
17
|
-
<div className="font-
|
|
17
|
+
<div className="font-sans text-xs font-medium text-dashboard-text-muted">
|
|
18
18
|
{props.label}
|
|
19
19
|
</div>
|
|
20
20
|
<Icon aria-hidden="true" className="text-amber-400/55" size={15} />
|
|
@@ -23,7 +23,7 @@ export function StatCard(props: {
|
|
|
23
23
|
{props.value}
|
|
24
24
|
</div>
|
|
25
25
|
{props.detail ? (
|
|
26
|
-
<div className="mt-2 font-
|
|
26
|
+
<div className="mt-2 font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
27
27
|
{props.detail}
|
|
28
28
|
</div>
|
|
29
29
|
) : null}
|
|
@@ -102,7 +102,7 @@ function ArchivedNotice(props: {
|
|
|
102
102
|
>
|
|
103
103
|
{restore.error ? (
|
|
104
104
|
<div
|
|
105
|
-
className="border-t border-rose-300/25 bg-rose-400/[0.12] px-3 py-2 font-
|
|
105
|
+
className="border-t border-rose-300/25 bg-rose-400/[0.12] px-3 py-2 font-sans text-xs text-rose-50/85"
|
|
106
106
|
role="alert"
|
|
107
107
|
>
|
|
108
108
|
Could not restore the conversation.
|
|
@@ -49,7 +49,7 @@ export function ConversationBrief(props: {
|
|
|
49
49
|
<StatusChip tone={outcomeTones[content.outcome.status]}>
|
|
50
50
|
{displayLabel(content.outcome.status)}
|
|
51
51
|
</StatusChip>
|
|
52
|
-
<span className="
|
|
52
|
+
<span className="text-xs text-dashboard-text-muted">
|
|
53
53
|
Brief v{props.brief.version} · updated{" "}
|
|
54
54
|
{formatTime(props.brief.updatedAt, {
|
|
55
55
|
dateStyle: "medium",
|
|
@@ -101,14 +101,14 @@ export function ConversationBrief(props: {
|
|
|
101
101
|
key={`${link.kind}:${link.url}`}
|
|
102
102
|
>
|
|
103
103
|
<a
|
|
104
|
-
className="min-w-0 break-all font-medium text-
|
|
104
|
+
className="min-w-0 break-all font-medium text-dashboard-accent-text underline decoration-dashboard-accent/30 underline-offset-2 hover:text-dashboard-accent-text"
|
|
105
105
|
href={link.url}
|
|
106
106
|
rel="noopener noreferrer"
|
|
107
107
|
target="_blank"
|
|
108
108
|
>
|
|
109
109
|
{link.label}
|
|
110
110
|
</a>
|
|
111
|
-
<span className="
|
|
111
|
+
<span className="text-xs text-dashboard-text-muted">
|
|
112
112
|
{displayLabel(link.kind)}
|
|
113
113
|
</span>
|
|
114
114
|
{link.status ? (
|
|
@@ -172,7 +172,7 @@ function BriefDecisions(props: { decisions: BriefContent["decisions"] }) {
|
|
|
172
172
|
<span className="min-w-0">{decision.text}</span>
|
|
173
173
|
</div>
|
|
174
174
|
{decision.by ? (
|
|
175
|
-
<div className="mt-0.5
|
|
175
|
+
<div className="mt-0.5 text-xs text-dashboard-text-muted">
|
|
176
176
|
by · {decision.by}
|
|
177
177
|
</div>
|
|
178
178
|
) : null}
|
|
@@ -110,21 +110,30 @@ function ChildAgentRow(props: {
|
|
|
110
110
|
// A title is often a short form of the task. Skip the task when it adds nothing.
|
|
111
111
|
const detail = agent.title && task && task !== agent.title ? task : undefined;
|
|
112
112
|
const runtime = formatRuntime(agent.cumulativeDurationMs);
|
|
113
|
+
// Totals include this subagent's own subagents. Say so, so the row does not
|
|
114
|
+
// read as the work of this subagent alone.
|
|
115
|
+
const nested = agent.childAgentTotals?.count;
|
|
113
116
|
const stats = [
|
|
114
117
|
formatUsageTotal(agent.cumulativeUsage),
|
|
115
118
|
formatConversationCostTotal(agent.cumulativeUsage, agent.auxiliaryCosts),
|
|
116
119
|
runtime ? `${runtime} runtime` : "",
|
|
120
|
+
nested
|
|
121
|
+
? `incl. ${nested} nested ${nested === 1 ? "subagent" : "subagents"}`
|
|
122
|
+
: "",
|
|
117
123
|
].filter(Boolean);
|
|
118
124
|
|
|
119
125
|
return (
|
|
120
126
|
<button
|
|
121
|
-
className="grid w-full min-w-0 cursor-pointer gap-1.5 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface px-3 py-2.5 text-left text-inherit transition-colors duration-200 hover:border-dashboard-border-emphasis hover:bg-dashboard-surface-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-dashboard-focus"
|
|
127
|
+
className="grid w-full min-w-0 cursor-pointer gap-1.5 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface-panel px-3 py-2.5 text-left text-inherit transition-colors duration-200 hover:border-dashboard-border-emphasis hover:bg-dashboard-surface-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-dashboard-focus"
|
|
122
128
|
onClick={() =>
|
|
123
129
|
props.onOpen({
|
|
124
130
|
conversationId: agent.conversationId,
|
|
125
131
|
...(agent.redacted
|
|
126
132
|
? undefined
|
|
127
|
-
: {
|
|
133
|
+
: {
|
|
134
|
+
...(agent.name ? { agentName: agent.name } : undefined),
|
|
135
|
+
label: agent.title ?? agent.name,
|
|
136
|
+
}),
|
|
128
137
|
status: agent.status,
|
|
129
138
|
})
|
|
130
139
|
}
|
|
@@ -137,7 +146,7 @@ function ChildAgentRow(props: {
|
|
|
137
146
|
Private subagent
|
|
138
147
|
</span>
|
|
139
148
|
) : (
|
|
140
|
-
<span className="min-w-0 truncate font-
|
|
149
|
+
<span className="min-w-0 truncate font-medium text-dashboard-text-muted">
|
|
141
150
|
{agent.name ?? "subagent"}
|
|
142
151
|
</span>
|
|
143
152
|
)}
|
|
@@ -179,7 +188,7 @@ function ChildAgentRow(props: {
|
|
|
179
188
|
</span>
|
|
180
189
|
) : null}
|
|
181
190
|
{stats.length > 0 ? (
|
|
182
|
-
<span className="block
|
|
191
|
+
<span className="block text-xs tabular-nums text-dashboard-text-muted">
|
|
183
192
|
{stats.join(" · ")}
|
|
184
193
|
</span>
|
|
185
194
|
) : null}
|
|
@@ -351,7 +351,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
351
351
|
{props.error || imageError ? (
|
|
352
352
|
<div
|
|
353
353
|
aria-live="polite"
|
|
354
|
-
className="min-w-0 font-
|
|
354
|
+
className="min-w-0 font-sans text-xs leading-relaxed text-rose-300"
|
|
355
355
|
>
|
|
356
356
|
{imageError ?? props.error}
|
|
357
357
|
</div>
|
|
@@ -361,10 +361,10 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
361
361
|
// Accessory chrome needs a full footer row. Side-by-side mobile is
|
|
362
362
|
// only for the bare reply dock.
|
|
363
363
|
props.footerStart
|
|
364
|
-
? "block overflow-hidden focus-within:border-
|
|
365
|
-
: "grid grid-cols-[minmax(0,1fr)_auto] items-end overflow-hidden focus-within:border-
|
|
364
|
+
? "block overflow-hidden focus-within:border-dashboard-focus/45 focus-within:ring-1 focus-within:ring-dashboard-focus/25"
|
|
365
|
+
: "grid grid-cols-[minmax(0,1fr)_auto] items-end overflow-hidden focus-within:border-dashboard-accent/35 focus-within:ring-1 focus-within:ring-dashboard-focus/35 md:block",
|
|
366
366
|
dashboardComposerSurfaceClass,
|
|
367
|
-
dragging && "ring-2 ring-
|
|
367
|
+
dragging && "ring-2 ring-dashboard-focus",
|
|
368
368
|
)}
|
|
369
369
|
onDragOver={(event) => {
|
|
370
370
|
if (!event.dataTransfer.types.includes("Files")) return;
|
|
@@ -431,7 +431,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
431
431
|
autoCapitalize="off"
|
|
432
432
|
autoComplete="off"
|
|
433
433
|
autoCorrect="off"
|
|
434
|
-
className="min-h-12 max-h-28 w-full resize-none overflow-y-auto border-0 bg-transparent px-3 py-3 font-sans text-base leading-relaxed text-dashboard-text outline-none placeholder:text-dashboard-text-muted/65 md:min-h-14 md:max-h-none md:
|
|
434
|
+
className="min-h-12 max-h-28 w-full resize-none overflow-y-auto border-0 bg-transparent px-3 py-3 font-sans text-base leading-relaxed text-dashboard-text outline-none placeholder:text-dashboard-text-muted/65 md:min-h-14 md:max-h-none md:overflow-visible md:px-4 md:py-3"
|
|
435
435
|
disabled={Boolean(props.restoreDraftOnError && createPending)}
|
|
436
436
|
enterKeyHint="send"
|
|
437
437
|
id={id}
|
|
@@ -462,6 +462,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
462
462
|
aria-label="Attach images"
|
|
463
463
|
disabled={sendLocked || readingImages}
|
|
464
464
|
onClick={() => fileInputRef.current?.click()}
|
|
465
|
+
size="icon"
|
|
465
466
|
title="Attach images (up to 3 MB total)"
|
|
466
467
|
type="button"
|
|
467
468
|
>
|
|
@@ -478,7 +479,6 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
478
479
|
{props.onStop ? (
|
|
479
480
|
<Button
|
|
480
481
|
aria-label={props.stopPending ? "Stopping" : "Stop"}
|
|
481
|
-
className="rounded-lg font-sans"
|
|
482
482
|
disabled={props.stopPending || !online}
|
|
483
483
|
onClick={() => void stopTurn()}
|
|
484
484
|
title="Stop Junior"
|
|
@@ -491,7 +491,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
491
491
|
) : null}
|
|
492
492
|
<Button
|
|
493
493
|
aria-label={sendLocked ? "Sending message" : props.submitLabel}
|
|
494
|
-
className="
|
|
494
|
+
className="disabled:!border-transparent disabled:!bg-dashboard-fill-hover disabled:!text-dashboard-text-muted disabled:!opacity-100"
|
|
495
495
|
disabled={
|
|
496
496
|
(!canSend && !images.length) ||
|
|
497
497
|
!online ||
|
|
@@ -499,6 +499,7 @@ export const ConversationComposer = memo(function ConversationComposer(
|
|
|
499
499
|
readingImages
|
|
500
500
|
}
|
|
501
501
|
title={sendLocked ? "Sending message" : props.submitLabel}
|
|
502
|
+
tone="primary"
|
|
502
503
|
type="submit"
|
|
503
504
|
>
|
|
504
505
|
<Send aria-hidden="true" size={14} />
|
|
@@ -114,7 +114,7 @@ export function ConversationHeader(props: {
|
|
|
114
114
|
<Ellipsis aria-hidden="true" size={18} strokeWidth={2} />
|
|
115
115
|
</HeaderIconButton>
|
|
116
116
|
{mobileMenuOpen ? (
|
|
117
|
-
<div className="absolute right-0 top-[calc(100%+0.35rem)] z-40 w-56 rounded-xl border border-
|
|
117
|
+
<div className="absolute right-0 top-[calc(100%+0.35rem)] z-40 w-56 rounded-xl border border-dashboard-border-strong bg-dashboard-surface-raised/95 p-1.5 shadow-2xl shadow-black/75 backdrop-blur-xl">
|
|
118
118
|
<ConversationHeaderActions
|
|
119
119
|
archive={props.archive}
|
|
120
120
|
conversationId={props.conversationId}
|
|
@@ -138,7 +138,7 @@ export function ConversationHeader(props: {
|
|
|
138
138
|
/>
|
|
139
139
|
{openMobileNavigation ? (
|
|
140
140
|
<button
|
|
141
|
-
className="mt-0.5 flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-
|
|
141
|
+
className="mt-0.5 flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-dashboard-fill-hover focus-visible:bg-dashboard-fill-hover focus-visible:outline-none"
|
|
142
142
|
onClick={() => {
|
|
143
143
|
setMobileMenuOpen(false);
|
|
144
144
|
openMobileNavigation();
|
|
@@ -175,7 +175,7 @@ export function ConversationHeader(props: {
|
|
|
175
175
|
<MobileHeaderLivePortal>{liveIndicator}</MobileHeaderLivePortal>
|
|
176
176
|
<header
|
|
177
177
|
className={cn(
|
|
178
|
-
"sticky top-0 z-10 -mx-4 border-b border-dashboard-border
|
|
178
|
+
"sticky top-0 z-10 -mx-4 border-b border-dashboard-border bg-dashboard-bg md:-mx-7",
|
|
179
179
|
!showMobileHeader && "hidden md:block",
|
|
180
180
|
)}
|
|
181
181
|
>
|
|
@@ -221,12 +221,12 @@ export function ConversationHeader(props: {
|
|
|
221
221
|
{props.linkedWork ? (
|
|
222
222
|
<div
|
|
223
223
|
aria-label="Linked work"
|
|
224
|
-
className="border-t border-dashboard-border
|
|
224
|
+
className="border-t border-dashboard-border-subtle px-4 py-2.5 md:px-7"
|
|
225
225
|
>
|
|
226
226
|
{props.linkedWork}
|
|
227
227
|
</div>
|
|
228
228
|
) : null}
|
|
229
|
-
<div className="hidden border-t border-dashboard-border px-7 md:flex">
|
|
229
|
+
<div className="hidden border-t border-dashboard-border-subtle px-7 md:flex">
|
|
230
230
|
<TranscriptViewToggle
|
|
231
231
|
labelled
|
|
232
232
|
onChange={props.onViewChange}
|
|
@@ -96,7 +96,7 @@ export function ConversationHeaderActions(props: {
|
|
|
96
96
|
<Button
|
|
97
97
|
aria-label="Conversation details"
|
|
98
98
|
aria-pressed={props.detailsOpen}
|
|
99
|
-
className="ml-2
|
|
99
|
+
className="ml-2"
|
|
100
100
|
onClick={props.onDetailsClick}
|
|
101
101
|
>
|
|
102
102
|
<PanelRight aria-hidden="true" size={15} strokeWidth={2} />
|
|
@@ -153,13 +153,13 @@ function ViewModeButton(props: {
|
|
|
153
153
|
<ToggleButton
|
|
154
154
|
aria-label={props.label}
|
|
155
155
|
className={cn(
|
|
156
|
-
"!
|
|
156
|
+
"!no-underline",
|
|
157
157
|
props.labelled
|
|
158
|
-
? "relative flex h-11 items-center gap-2 px-0 py-0 text-
|
|
159
|
-
: "grid size-7 place-items-center rounded px-0 py-0",
|
|
158
|
+
? "relative flex h-11 items-center gap-2 rounded-none px-0 py-0 text-sm after:absolute after:inset-x-0 after:bottom-0 after:h-0.5"
|
|
159
|
+
: "grid size-7 place-items-center rounded-md px-0 py-0",
|
|
160
160
|
props.active &&
|
|
161
161
|
(props.labelled
|
|
162
|
-
? "text-
|
|
162
|
+
? "text-dashboard-text after:bg-dashboard-text-solid"
|
|
163
163
|
: "bg-dashboard-fill-hover text-dashboard-text"),
|
|
164
164
|
)}
|
|
165
165
|
onClick={props.onClick}
|
|
@@ -191,7 +191,7 @@ export function HeaderIconButton(props: {
|
|
|
191
191
|
aria-pressed={props.pressed}
|
|
192
192
|
className={cn(
|
|
193
193
|
"text-dashboard-text-muted",
|
|
194
|
-
props.pressed && "bg-
|
|
194
|
+
props.pressed && "bg-dashboard-fill-strong text-dashboard-text",
|
|
195
195
|
)}
|
|
196
196
|
onClick={props.onClick}
|
|
197
197
|
size="icon"
|
|
@@ -233,8 +233,8 @@ function MenuActionButton(props: {
|
|
|
233
233
|
aria-label={props.label}
|
|
234
234
|
aria-pressed={props.pressed}
|
|
235
235
|
className={cn(
|
|
236
|
-
"flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-
|
|
237
|
-
props.pressed && "bg-
|
|
236
|
+
"flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-dashboard-fill-strong focus-visible:bg-dashboard-fill-strong focus-visible:outline-none",
|
|
237
|
+
props.pressed && "bg-dashboard-fill-strong",
|
|
238
238
|
)}
|
|
239
239
|
onClick={props.onClick}
|
|
240
240
|
type="button"
|
|
@@ -258,7 +258,7 @@ function ArchiveConversationButton(
|
|
|
258
258
|
return (
|
|
259
259
|
<button
|
|
260
260
|
aria-label={label}
|
|
261
|
-
className="flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-
|
|
261
|
+
className="flex w-full cursor-pointer items-center gap-2.5 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-sm font-semibold text-dashboard-text transition-colors hover:bg-dashboard-fill-strong focus-visible:bg-dashboard-fill-strong focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
262
262
|
disabled={props.disabled}
|
|
263
263
|
onClick={props.onClick}
|
|
264
264
|
type="button"
|
|
@@ -172,7 +172,7 @@ function ConversationCardSection(props: {
|
|
|
172
172
|
return (
|
|
173
173
|
<section aria-labelledby={`conversation-section-${props.section.key}`}>
|
|
174
174
|
<h3
|
|
175
|
-
className="mb-2 mt-0 px-1 font-
|
|
175
|
+
className="mb-2 mt-0 px-1 font-sans text-xs font-medium text-dashboard-text-muted"
|
|
176
176
|
id={`conversation-section-${props.section.key}`}
|
|
177
177
|
>
|
|
178
178
|
{props.section.label}
|
|
@@ -238,7 +238,7 @@ function ConversationCard(props: {
|
|
|
238
238
|
</div>
|
|
239
239
|
<div className="flex items-start gap-3">
|
|
240
240
|
<Link
|
|
241
|
-
className="pointer-events-auto whitespace-nowrap font-
|
|
241
|
+
className="pointer-events-auto whitespace-nowrap font-sans text-xs tabular-nums text-dashboard-text-muted hover:text-dashboard-text focus:outline-none focus:ring-2 focus:ring-dashboard-focus"
|
|
242
242
|
to={conversationPath(conversation.id)}
|
|
243
243
|
>
|
|
244
244
|
{formatRelativeTime(conversation.lastSeenAt)}
|
|
@@ -272,7 +272,7 @@ function ConversationCard(props: {
|
|
|
272
272
|
{status === "active" ? "Working…" : "No recent message"}
|
|
273
273
|
</p>
|
|
274
274
|
)}
|
|
275
|
-
<div className="relative z-[1] flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-1 font-
|
|
275
|
+
<div className="relative z-[1] flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-1 font-sans text-xs text-dashboard-text-muted pointer-events-none">
|
|
276
276
|
{location ? <span className="truncate">{location}</span> : null}
|
|
277
277
|
{location && participants.length > 0 ? (
|
|
278
278
|
<span aria-hidden="true">·</span>
|
|
@@ -45,7 +45,7 @@ export function ConversationListStatusIcon(props: {
|
|
|
45
45
|
className={cn(
|
|
46
46
|
"size-1.5 shrink-0 rounded-full",
|
|
47
47
|
props.status === "failed" && "bg-rose-300",
|
|
48
|
-
props.status === "idle" && "bg-
|
|
48
|
+
props.status === "idle" && "bg-dashboard-text-faint",
|
|
49
49
|
)}
|
|
50
50
|
/>
|
|
51
51
|
);
|
|
@@ -66,17 +66,17 @@ export function ConversationMemories(props: { conversationId: string }) {
|
|
|
66
66
|
<ol className="m-0 grid list-none gap-3 p-0">
|
|
67
67
|
{query.data.memories.map((memory) => (
|
|
68
68
|
<li
|
|
69
|
-
className="grid gap-2 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface px-3 py-3"
|
|
69
|
+
className="grid gap-2 rounded-lg border border-dashboard-border-subtle bg-dashboard-surface-panel px-3 py-3"
|
|
70
70
|
key={memory.id}
|
|
71
71
|
>
|
|
72
72
|
<p className="m-0 whitespace-pre-wrap break-words text-sm leading-relaxed text-dashboard-text">
|
|
73
73
|
{memory.content}
|
|
74
74
|
</p>
|
|
75
|
-
<div className="flex flex-wrap items-center gap-1.5
|
|
76
|
-
<span className="rounded border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
75
|
+
<div className="flex flex-wrap items-center gap-1.5 text-xs tabular-nums text-dashboard-text-muted">
|
|
76
|
+
<span className="rounded-md border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
77
77
|
{memory.kind}
|
|
78
78
|
</span>
|
|
79
|
-
<span className="rounded border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
79
|
+
<span className="rounded-md border border-dashboard-border-subtle bg-dashboard-surface-raised px-1.5 py-0.5">
|
|
80
80
|
{memory.visibility}
|
|
81
81
|
</span>
|
|
82
82
|
<time className="ml-auto" dateTime={memory.capturedAt}>
|
|
@@ -24,8 +24,13 @@ import {
|
|
|
24
24
|
} from "../format";
|
|
25
25
|
import { Tooltip } from "../components/Tooltip";
|
|
26
26
|
import { MetricList, type MetricListItem } from "../components/Metric";
|
|
27
|
-
import { cn } from "../styles";
|
|
28
|
-
import {
|
|
27
|
+
import { cn, dashboardInlineLinkClass } from "../styles";
|
|
28
|
+
import {
|
|
29
|
+
CostMetric,
|
|
30
|
+
DurationMetric,
|
|
31
|
+
SubagentsMetric,
|
|
32
|
+
TokenMetric,
|
|
33
|
+
} from "./TelemetryMetrics";
|
|
29
34
|
import type { Conversation } from "../types";
|
|
30
35
|
import {
|
|
31
36
|
projectSidebarAnnotationBadges,
|
|
@@ -44,9 +49,9 @@ export function PendingAuthorization(props: {
|
|
|
44
49
|
};
|
|
45
50
|
}) {
|
|
46
51
|
return (
|
|
47
|
-
<div className="mb-2 rounded-lg border border-
|
|
52
|
+
<div className="mb-2 rounded-lg border border-dashboard-accent/20 bg-dashboard-accent/[0.07] px-3 py-2.5 font-sans text-sm text-dashboard-text">
|
|
48
53
|
<a
|
|
49
|
-
className="font-medium text-
|
|
54
|
+
className="font-medium text-dashboard-accent-text underline decoration-dashboard-accent/40 underline-offset-2 hover:text-dashboard-accent-text"
|
|
50
55
|
href={props.authorization.authorizationUrl}
|
|
51
56
|
rel="noreferrer"
|
|
52
57
|
target="_blank"
|
|
@@ -77,7 +82,7 @@ export function ConversationPrivacyChip(props: {
|
|
|
77
82
|
className={
|
|
78
83
|
isPublic
|
|
79
84
|
? "inline-flex max-w-full items-center gap-1 rounded-full border border-dashboard-border-emphasis bg-dashboard-fill-soft px-2 py-0.5 font-sans text-2xs font-medium text-dashboard-text-muted"
|
|
80
|
-
: "inline-flex max-w-full items-center gap-1 rounded-full border border-
|
|
85
|
+
: "inline-flex max-w-full items-center gap-1 rounded-full border border-dashboard-border-strong bg-dashboard-fill-soft px-2 py-0.5 font-sans text-2xs font-medium text-dashboard-text-muted"
|
|
81
86
|
}
|
|
82
87
|
role="note"
|
|
83
88
|
title={`${fullLabel}. ${detail}`}
|
|
@@ -171,7 +176,7 @@ export function ConversationSidebarAnnotations(props: {
|
|
|
171
176
|
<SidebarAnnotationGroupChip group={group} key={group.label} />
|
|
172
177
|
))}
|
|
173
178
|
{badges.overflowGroupCount > 0 ? (
|
|
174
|
-
<span className="inline-flex h-5 min-w-7 shrink-0 items-center justify-center rounded-full border border-
|
|
179
|
+
<span className="inline-flex h-5 min-w-7 shrink-0 items-center justify-center rounded-full border border-dashboard-border-strong bg-dashboard-control px-1.5 font-sans text-2xs tabular-nums leading-none text-dashboard-text-muted">
|
|
175
180
|
+{badges.overflowGroupCount}
|
|
176
181
|
</span>
|
|
177
182
|
) : null}
|
|
@@ -220,7 +225,7 @@ function SidebarAnnotationGroupChip(props: {
|
|
|
220
225
|
group: SidebarAnnotationBadgeGroup;
|
|
221
226
|
}) {
|
|
222
227
|
return (
|
|
223
|
-
<span className="inline-flex h-5 min-w-0 max-w-60 shrink-0 items-center gap-1 truncate rounded-full border border-
|
|
228
|
+
<span className="inline-flex h-5 min-w-0 max-w-60 shrink-0 items-center gap-1 truncate rounded-full border border-dashboard-border-strong bg-dashboard-control px-1.5 font-sans text-2xs leading-none text-dashboard-text-muted">
|
|
224
229
|
{props.group.annotations.map((annotation) =>
|
|
225
230
|
annotation.objectType ? (
|
|
226
231
|
<ObjectIcon
|
|
@@ -264,7 +269,7 @@ function SidebarAnnotationStatusChip(props: {
|
|
|
264
269
|
// real chips, not floating glyphs. Box-shadow cutout (not border) keeps
|
|
265
270
|
// layout at 18px while punching a surface-colored ring through the chip
|
|
266
271
|
// underneath — classic avatar-facepile silhouette.
|
|
267
|
-
"relative box-border inline-flex size-[18px] shrink-0 items-center justify-center rounded-full border border-
|
|
272
|
+
"relative box-border inline-flex size-[18px] shrink-0 items-center justify-center rounded-full border border-dashboard-border-strong bg-dashboard-control",
|
|
268
273
|
props.stacked && "-ml-1",
|
|
269
274
|
)}
|
|
270
275
|
style={{
|
|
@@ -415,7 +420,7 @@ export function ConversationAnnotations(props: {
|
|
|
415
420
|
className={cn(
|
|
416
421
|
"inline-flex min-w-0 max-w-full shrink-0 items-center gap-2 rounded-md font-sans leading-snug text-dashboard-text no-underline transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus",
|
|
417
422
|
props.layout === "strip"
|
|
418
|
-
? "px-1 py-0.5 text-xs hover:text-
|
|
423
|
+
? "px-1 py-0.5 text-xs hover:text-dashboard-accent-text"
|
|
419
424
|
: "min-h-10 border border-dashboard-border px-3 py-2 text-sm hover:border-dashboard-border-interactive hover:bg-dashboard-surface-hover",
|
|
420
425
|
)}
|
|
421
426
|
href={link.url ?? undefined}
|
|
@@ -466,7 +471,7 @@ function resourceLinkTitle(link: {
|
|
|
466
471
|
function LocationLink(props: { label: string; locationUrl?: string }) {
|
|
467
472
|
return props.locationUrl ? (
|
|
468
473
|
<a
|
|
469
|
-
className=
|
|
474
|
+
className={dashboardInlineLinkClass}
|
|
470
475
|
href={props.locationUrl}
|
|
471
476
|
rel="noreferrer"
|
|
472
477
|
target="_blank"
|
|
@@ -489,7 +494,7 @@ function SourceTask(props: {
|
|
|
489
494
|
const title = props.sourceTask.title?.trim();
|
|
490
495
|
const link = automationId ? (
|
|
491
496
|
<Link
|
|
492
|
-
className=
|
|
497
|
+
className={dashboardInlineLinkClass}
|
|
493
498
|
to={automationPath(automationId)}
|
|
494
499
|
>
|
|
495
500
|
Triggered by {kindLabel}
|
|
@@ -598,6 +603,8 @@ function conversationStatItems(props: {
|
|
|
598
603
|
const live = (props.detail?.status ?? props.conversation.status) === "active";
|
|
599
604
|
const activeModelId = liveModelId(props.detail);
|
|
600
605
|
const sourceTask = props.detail?.sourceTask;
|
|
606
|
+
const childAgentTotals =
|
|
607
|
+
props.detail?.childAgentTotals ?? props.conversation.childAgentTotals;
|
|
601
608
|
const rawStats: Array<MetricListItem | undefined> = [
|
|
602
609
|
location
|
|
603
610
|
? {
|
|
@@ -615,6 +622,8 @@ function conversationStatItems(props: {
|
|
|
615
622
|
? {
|
|
616
623
|
content: (
|
|
617
624
|
<DurationMetric
|
|
625
|
+
childAgentTotals={childAgentTotals}
|
|
626
|
+
durationMs={props.conversation.cumulativeDurationMs}
|
|
618
627
|
endedAt={props.conversation.lastSeenAt}
|
|
619
628
|
label={durationLabel}
|
|
620
629
|
startedAt={props.conversation.startedAt}
|
|
@@ -627,6 +636,8 @@ function conversationStatItems(props: {
|
|
|
627
636
|
? {
|
|
628
637
|
content: (
|
|
629
638
|
<TokenMetric
|
|
639
|
+
detailsHint={variant === "compact"}
|
|
640
|
+
childAgentTotals={childAgentTotals}
|
|
630
641
|
compactionCount={
|
|
631
642
|
completeDetail
|
|
632
643
|
? completeDetail.events.filter(
|
|
@@ -650,10 +661,12 @@ function conversationStatItems(props: {
|
|
|
650
661
|
? {
|
|
651
662
|
content: (
|
|
652
663
|
<CostMetric
|
|
664
|
+
detailsHint={variant === "compact"}
|
|
653
665
|
auxiliaryCosts={
|
|
654
666
|
props.detail?.auxiliaryCosts ??
|
|
655
667
|
props.conversation.auxiliaryCosts
|
|
656
668
|
}
|
|
669
|
+
childAgentTotals={childAgentTotals}
|
|
657
670
|
live={live}
|
|
658
671
|
liveModelId={activeModelId}
|
|
659
672
|
modelUsage={props.detail?.modelUsage}
|
|
@@ -663,6 +676,12 @@ function conversationStatItems(props: {
|
|
|
663
676
|
key: "cost",
|
|
664
677
|
}
|
|
665
678
|
: undefined,
|
|
679
|
+
childAgentTotals
|
|
680
|
+
? {
|
|
681
|
+
content: <SubagentsMetric childAgentTotals={childAgentTotals} />,
|
|
682
|
+
key: "subagents",
|
|
683
|
+
}
|
|
684
|
+
: undefined,
|
|
666
685
|
];
|
|
667
686
|
return rawStats.filter((item): item is MetricListItem => item !== undefined);
|
|
668
687
|
}
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
hasConversationStats,
|
|
38
38
|
PendingAuthorization,
|
|
39
39
|
} from "./ConversationMeta";
|
|
40
|
+
import { ConversationUsageBreakdown } from "./ConversationUsageBreakdown";
|
|
40
41
|
import { PendingMailboxStack } from "./PendingMailboxStack";
|
|
41
42
|
import {
|
|
42
43
|
buildConversations,
|
|
@@ -185,6 +186,7 @@ export function ConversationPage(props: {
|
|
|
185
186
|
conversation: ConversationTranscript;
|
|
186
187
|
}) => {
|
|
187
188
|
setSubagentTarget({
|
|
189
|
+
...(part.agentName ? { agentName: part.agentName } : undefined),
|
|
188
190
|
conversationId: part.childConversationId,
|
|
189
191
|
label: part.title ?? part.agentName,
|
|
190
192
|
status: part.status,
|
|
@@ -300,10 +302,16 @@ export function ConversationPage(props: {
|
|
|
300
302
|
conversation,
|
|
301
303
|
detail: detail.data,
|
|
302
304
|
}) ? (
|
|
303
|
-
<
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
305
|
+
<div className="grid min-w-0 gap-5">
|
|
306
|
+
<ConversationStats
|
|
307
|
+
conversation={conversation}
|
|
308
|
+
detail={detail.data}
|
|
309
|
+
/>
|
|
310
|
+
<ConversationUsageBreakdown
|
|
311
|
+
conversation={conversation}
|
|
312
|
+
detail={detail.data}
|
|
313
|
+
/>
|
|
314
|
+
</div>
|
|
307
315
|
) : null
|
|
308
316
|
}
|
|
309
317
|
title={title}
|
|
@@ -320,7 +328,7 @@ export function ConversationPage(props: {
|
|
|
320
328
|
{detail.isPending ? (
|
|
321
329
|
<TranscriptLoading />
|
|
322
330
|
) : detail.error && !detail.data ? (
|
|
323
|
-
<Card className="border-
|
|
331
|
+
<Card className="border-dashboard-border bg-dashboard-fill-soft p-4 font-sans text-xs leading-relaxed text-dashboard-text-muted">
|
|
324
332
|
{detail.error.message}
|
|
325
333
|
</Card>
|
|
326
334
|
) : (
|
|
@@ -88,8 +88,8 @@ export function ConversationSidebar(props: {
|
|
|
88
88
|
className={cn(
|
|
89
89
|
"relative min-w-0",
|
|
90
90
|
isLanding
|
|
91
|
-
? "border-t border-
|
|
92
|
-
: "grid h-full min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] overflow-hidden border-r border-dashboard-border
|
|
91
|
+
? "border-t border-dashboard-border bg-transparent"
|
|
92
|
+
: "grid h-full min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] overflow-hidden border-r border-dashboard-border bg-dashboard-surface-panel",
|
|
93
93
|
)}
|
|
94
94
|
>
|
|
95
95
|
<div className="px-5 py-3">
|
|
@@ -106,7 +106,7 @@ export function ConversationSidebar(props: {
|
|
|
106
106
|
{isLanding ? null : (
|
|
107
107
|
<button
|
|
108
108
|
aria-label="New conversation"
|
|
109
|
-
className="grid size-7 cursor-pointer place-items-center rounded-md text-dashboard-text-muted transition hover:bg-
|
|
109
|
+
className="grid size-7 cursor-pointer place-items-center rounded-md text-dashboard-text-muted transition hover:bg-dashboard-fill-hover hover:text-dashboard-text focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-dashboard-focus"
|
|
110
110
|
onClick={props.onNewConversation}
|
|
111
111
|
title="New conversation"
|
|
112
112
|
type="button"
|
|
@@ -293,7 +293,7 @@ const ConversationSidebarRow = memo(function ConversationSidebarRow(props: {
|
|
|
293
293
|
<Link
|
|
294
294
|
aria-current={props.selected ? "page" : undefined}
|
|
295
295
|
className={cn(
|
|
296
|
-
"block min-w-0 rounded-lg px-3 py-2 text-inherit no-underline transition-colors hover:bg-dashboard-fill-hover max-sm:pr-10",
|
|
296
|
+
"block min-w-0 rounded-lg px-3 py-2 text-inherit no-underline transition-colors hover:bg-dashboard-fill-hover focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-dashboard-focus max-sm:pr-10",
|
|
297
297
|
props.selected && "bg-dashboard-surface-active",
|
|
298
298
|
)}
|
|
299
299
|
to={conversationPath(props.conversation.id)}
|
|
@@ -323,7 +323,7 @@ const ConversationSidebarRow = memo(function ConversationSidebarRow(props: {
|
|
|
323
323
|
</Link>
|
|
324
324
|
<button
|
|
325
325
|
aria-label={`${props.conversation.archivedAt ? "Restore" : "Archive"} ${title}`}
|
|
326
|
-
className="absolute right-1.5 top-1/2 z-10 grid size-7 -translate-y-1/2 cursor-pointer place-items-center rounded-md bg-dashboard-surface-active text-dashboard-text-muted transition hover:text-dashboard-text focus:outline-
|
|
326
|
+
className="absolute right-1.5 top-1/2 z-10 grid size-7 -translate-y-1/2 cursor-pointer place-items-center rounded-md bg-dashboard-surface-active text-dashboard-text-muted transition hover:text-dashboard-text focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-dashboard-focus sm:pointer-events-none sm:opacity-0 sm:focus:pointer-events-auto sm:focus:opacity-100 sm:group-focus-within:pointer-events-auto sm:group-focus-within:opacity-100 sm:group-hover:pointer-events-auto sm:group-hover:opacity-100 disabled:cursor-not-allowed"
|
|
327
327
|
disabled={archive.isPending}
|
|
328
328
|
onClick={() =>
|
|
329
329
|
archive.mutate({
|
|
@@ -413,7 +413,7 @@ function ArchivedConversationNotice(props: {
|
|
|
413
413
|
>
|
|
414
414
|
{restore.error ? (
|
|
415
415
|
<div
|
|
416
|
-
className="border-t border-rose-300/25 bg-rose-400/[0.12] px-3 py-2 font-
|
|
416
|
+
className="border-t border-rose-300/25 bg-rose-400/[0.12] px-3 py-2 font-sans text-xs text-rose-50/85"
|
|
417
417
|
role="alert"
|
|
418
418
|
>
|
|
419
419
|
Could not restore the conversation.
|