@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
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { ObjectType } from "@sentry/junior-plugin-api";
|
|
2
|
+
import type { ConversationDetailReport } from "@sentry/junior/api/schema";
|
|
3
|
+
|
|
4
|
+
import { ObjectIcon } from "../components/ObjectIcon";
|
|
5
|
+
import { DetailsList, DetailsRow, DetailsRowLine } from "./DetailsList";
|
|
6
|
+
|
|
7
|
+
type ConversationAnnotation = NonNullable<
|
|
8
|
+
ConversationDetailReport["annotations"]
|
|
9
|
+
>[number];
|
|
10
|
+
|
|
11
|
+
/** One annotation that links to work outside Junior. */
|
|
12
|
+
export type ConversationLink = {
|
|
13
|
+
description?: string;
|
|
14
|
+
facts?: { type: string };
|
|
15
|
+
key: string;
|
|
16
|
+
label: string;
|
|
17
|
+
objectType: ObjectType;
|
|
18
|
+
plugin: string;
|
|
19
|
+
status?: string;
|
|
20
|
+
url: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const resourceLinkStatusLabels: Record<string, string> = {
|
|
24
|
+
closed: "Closed",
|
|
25
|
+
draft: "Draft",
|
|
26
|
+
merged: "Merged",
|
|
27
|
+
open: "Open",
|
|
28
|
+
warning: "Needs attention",
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** Name a link status for a reader, such as "Merged" for `merged`. */
|
|
32
|
+
export function linkStatusLabel(status: string | undefined): string {
|
|
33
|
+
if (!status) return "";
|
|
34
|
+
return (
|
|
35
|
+
resourceLinkStatusLabels[status] ??
|
|
36
|
+
status.charAt(0).toUpperCase() + status.slice(1)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Pick the annotations that link to outside work, newest first as saved. A
|
|
42
|
+
* resource link without an object type takes the type of its sidebar
|
|
43
|
+
* annotation.
|
|
44
|
+
*/
|
|
45
|
+
export function conversationLinks(
|
|
46
|
+
detail: ConversationDetailReport | undefined,
|
|
47
|
+
): ConversationLink[] {
|
|
48
|
+
return (detail?.annotations ?? []).flatMap(
|
|
49
|
+
(annotation: ConversationAnnotation): ConversationLink[] => {
|
|
50
|
+
if (!annotation.url) return [];
|
|
51
|
+
const objectType =
|
|
52
|
+
annotation.objectType ??
|
|
53
|
+
detail?.sidebarAnnotations?.find(
|
|
54
|
+
(sidebar) => sidebar.key === annotation.key,
|
|
55
|
+
)?.objectType ??
|
|
56
|
+
"item";
|
|
57
|
+
const description =
|
|
58
|
+
annotation.kind === "object"
|
|
59
|
+
? annotation.title !== annotation.label
|
|
60
|
+
? annotation.title
|
|
61
|
+
: annotation.description
|
|
62
|
+
: annotation.description;
|
|
63
|
+
return [
|
|
64
|
+
{
|
|
65
|
+
...(description ? { description } : undefined),
|
|
66
|
+
...(annotation.kind === "object" && annotation.facts
|
|
67
|
+
? { facts: annotation.facts }
|
|
68
|
+
: undefined),
|
|
69
|
+
key: `${annotation.plugin}:${annotation.key}`,
|
|
70
|
+
label: annotation.label,
|
|
71
|
+
objectType,
|
|
72
|
+
plugin: annotation.plugin,
|
|
73
|
+
...(annotation.status ? { status: annotation.status } : undefined),
|
|
74
|
+
url: annotation.url,
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Show the outside work that a Conversation links to, one row each. */
|
|
82
|
+
export function ConversationLinkedWork(props: { links: ConversationLink[] }) {
|
|
83
|
+
return (
|
|
84
|
+
<DetailsList
|
|
85
|
+
itemKey={(link) => link.key}
|
|
86
|
+
items={props.links}
|
|
87
|
+
renderItem={(link) => {
|
|
88
|
+
const status = linkStatusLabel(link.status);
|
|
89
|
+
return (
|
|
90
|
+
<DetailsRow
|
|
91
|
+
href={link.url}
|
|
92
|
+
icon={
|
|
93
|
+
// The row text names the status, so the icon stays silent.
|
|
94
|
+
<ObjectIcon
|
|
95
|
+
decorative
|
|
96
|
+
facts={link.facts}
|
|
97
|
+
objectType={link.objectType}
|
|
98
|
+
size={14}
|
|
99
|
+
status={link.status}
|
|
100
|
+
/>
|
|
101
|
+
}
|
|
102
|
+
meta={status}
|
|
103
|
+
title={link.label}
|
|
104
|
+
tooltip={[link.label, link.plugin, status, link.description]
|
|
105
|
+
.filter(Boolean)
|
|
106
|
+
.join(" · ")}
|
|
107
|
+
>
|
|
108
|
+
{link.description ? (
|
|
109
|
+
<DetailsRowLine className="line-clamp-2 break-words">
|
|
110
|
+
{link.description}
|
|
111
|
+
</DetailsRowLine>
|
|
112
|
+
) : null}
|
|
113
|
+
</DetailsRow>
|
|
114
|
+
);
|
|
115
|
+
}}
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
@@ -24,7 +24,12 @@ import {
|
|
|
24
24
|
summarizeUsage,
|
|
25
25
|
automationPath,
|
|
26
26
|
} from "../format";
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
Tooltip,
|
|
29
|
+
TooltipContent,
|
|
30
|
+
TooltipTitle,
|
|
31
|
+
TooltipTrigger,
|
|
32
|
+
} from "../components/ui/tooltip";
|
|
28
33
|
import { MetricList, type MetricListItem } from "../components/Metric";
|
|
29
34
|
import { cn, dashboardInlineLinkClass } from "../styles";
|
|
30
35
|
import {
|
|
@@ -39,6 +44,7 @@ import {
|
|
|
39
44
|
type SidebarAnnotation,
|
|
40
45
|
type SidebarAnnotationBadgeGroup,
|
|
41
46
|
} from "./sidebarAnnotationBadges";
|
|
47
|
+
import { conversationLinks, linkStatusLabel } from "./ConversationLinkedWork";
|
|
42
48
|
|
|
43
49
|
const MOBILE_MEDIA_QUERY = "(max-width: 767px)";
|
|
44
50
|
|
|
@@ -100,13 +106,6 @@ export function ConversationPrivacyChip(props: {
|
|
|
100
106
|
);
|
|
101
107
|
}
|
|
102
108
|
|
|
103
|
-
type ResourceLinkStatus = NonNullable<
|
|
104
|
-
Extract<
|
|
105
|
-
NonNullable<ConversationDetailReport["annotations"]>[number],
|
|
106
|
-
{ kind: "resource_link" }
|
|
107
|
-
>["status"]
|
|
108
|
-
>;
|
|
109
|
-
|
|
110
109
|
/** True when the conversation has at least one resource-link annotation. */
|
|
111
110
|
export function hasConversationAnnotations(
|
|
112
111
|
annotations: ConversationDetailReport["annotations"] | undefined,
|
|
@@ -136,9 +135,36 @@ export function ConversationSidebarAnnotations(props: {
|
|
|
136
135
|
: [];
|
|
137
136
|
|
|
138
137
|
return (
|
|
139
|
-
<Tooltip
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
<Tooltip>
|
|
139
|
+
<TooltipTrigger
|
|
140
|
+
render={
|
|
141
|
+
<span
|
|
142
|
+
aria-label={`Linked work, newest first: ${details.join(", ")}`}
|
|
143
|
+
className="inline-flex min-w-0 max-w-full items-center"
|
|
144
|
+
>
|
|
145
|
+
{useMobileFacepile ? (
|
|
146
|
+
<SidebarAnnotationIconFacepile
|
|
147
|
+
annotations={mobileFacepileAnnotations}
|
|
148
|
+
// Discs sit on the sidebar panel / row surface.
|
|
149
|
+
cutoutColor="var(--color-dashboard-surface-panel)"
|
|
150
|
+
/>
|
|
151
|
+
) : (
|
|
152
|
+
<span className="inline-flex min-w-0 items-center gap-1">
|
|
153
|
+
{badges.labeledGroups.map((group) => (
|
|
154
|
+
<SidebarAnnotationGroupChip group={group} key={group.label} />
|
|
155
|
+
))}
|
|
156
|
+
{badges.overflowGroupCount > 0 ? (
|
|
157
|
+
<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">
|
|
158
|
+
+{badges.overflowGroupCount}
|
|
159
|
+
</span>
|
|
160
|
+
) : null}
|
|
161
|
+
</span>
|
|
162
|
+
)}
|
|
163
|
+
</span>
|
|
164
|
+
}
|
|
165
|
+
/>
|
|
166
|
+
<TooltipContent align="start">
|
|
167
|
+
<TooltipTitle>Linked work</TooltipTitle>
|
|
142
168
|
<ul className="m-0 list-none space-y-1 p-0">
|
|
143
169
|
{annotations.map((annotation, index) => (
|
|
144
170
|
<li
|
|
@@ -158,33 +184,7 @@ export function ConversationSidebarAnnotations(props: {
|
|
|
158
184
|
</li>
|
|
159
185
|
))}
|
|
160
186
|
</ul>
|
|
161
|
-
|
|
162
|
-
label="Linked work"
|
|
163
|
-
triggerClassName="min-w-0"
|
|
164
|
-
>
|
|
165
|
-
<span
|
|
166
|
-
aria-label={`Linked work, newest first: ${details.join(", ")}`}
|
|
167
|
-
className="inline-flex min-w-0 max-w-full items-center"
|
|
168
|
-
>
|
|
169
|
-
{useMobileFacepile ? (
|
|
170
|
-
<SidebarAnnotationIconFacepile
|
|
171
|
-
annotations={mobileFacepileAnnotations}
|
|
172
|
-
// Discs sit on the sidebar panel / row surface.
|
|
173
|
-
cutoutColor="var(--color-dashboard-surface-panel)"
|
|
174
|
-
/>
|
|
175
|
-
) : (
|
|
176
|
-
<span className="inline-flex min-w-0 items-center gap-1">
|
|
177
|
-
{badges.labeledGroups.map((group) => (
|
|
178
|
-
<SidebarAnnotationGroupChip group={group} key={group.label} />
|
|
179
|
-
))}
|
|
180
|
-
{badges.overflowGroupCount > 0 ? (
|
|
181
|
-
<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">
|
|
182
|
-
+{badges.overflowGroupCount}
|
|
183
|
-
</span>
|
|
184
|
-
) : null}
|
|
185
|
-
</span>
|
|
186
|
-
)}
|
|
187
|
-
</span>
|
|
187
|
+
</TooltipContent>
|
|
188
188
|
</Tooltip>
|
|
189
189
|
);
|
|
190
190
|
}
|
|
@@ -412,48 +412,35 @@ function SidebarAnnotationIcon(props: {
|
|
|
412
412
|
);
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
-
/** Render
|
|
415
|
+
/** Render linked work as a compact strip under the conversation title. */
|
|
416
416
|
export function ConversationAnnotations(props: {
|
|
417
417
|
detail: ConversationDetailReport | undefined;
|
|
418
|
-
layout?: "list" | "strip";
|
|
419
418
|
}) {
|
|
420
|
-
const links =
|
|
421
|
-
props.detail?.annotations?.filter(
|
|
422
|
-
(annotation) => annotation.url !== null,
|
|
423
|
-
) ?? [];
|
|
419
|
+
const links = conversationLinks(props.detail);
|
|
424
420
|
if (links.length === 0) return null;
|
|
425
421
|
return (
|
|
426
|
-
<div
|
|
427
|
-
className={cn(
|
|
428
|
-
"flex gap-x-4 gap-y-2",
|
|
429
|
-
props.layout === "strip" ? "overflow-x-auto" : "flex-col",
|
|
430
|
-
)}
|
|
431
|
-
>
|
|
422
|
+
<div className="flex gap-x-4 gap-y-2 overflow-x-auto">
|
|
432
423
|
{links.map((link) => (
|
|
433
424
|
<a
|
|
434
|
-
className=
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
? "px-1 py-0.5 text-xs hover:text-dashboard-accent-text"
|
|
438
|
-
: "min-h-10 border border-dashboard-border px-3 py-2 text-sm hover:border-dashboard-border-interactive hover:bg-dashboard-surface-hover",
|
|
439
|
-
)}
|
|
440
|
-
href={link.url ?? undefined}
|
|
441
|
-
key={`${link.plugin}:${link.key}`}
|
|
425
|
+
className="inline-flex min-w-0 max-w-full shrink-0 items-center gap-2 rounded-md px-1 py-0.5 font-sans text-xs leading-snug text-dashboard-text no-underline transition-colors hover:text-dashboard-accent-text focus-visible:outline focus-visible:outline-2 focus-visible:outline-dashboard-focus"
|
|
426
|
+
href={link.url}
|
|
427
|
+
key={link.key}
|
|
442
428
|
rel="noreferrer"
|
|
443
429
|
target="_blank"
|
|
444
|
-
title={
|
|
430
|
+
title={[
|
|
431
|
+
link.label,
|
|
432
|
+
link.plugin,
|
|
433
|
+
linkStatusLabel(link.status),
|
|
434
|
+
link.description,
|
|
435
|
+
]
|
|
436
|
+
.filter(Boolean)
|
|
437
|
+
.join(" · ")}
|
|
445
438
|
>
|
|
446
439
|
<ObjectIcon
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
props.detail?.sidebarAnnotations?.find(
|
|
450
|
-
(annotation) => annotation.key === link.key,
|
|
451
|
-
)?.objectType ??
|
|
452
|
-
"item"
|
|
453
|
-
}
|
|
454
|
-
status={link.status}
|
|
455
|
-
facts={link.kind === "object" ? link.facts : undefined}
|
|
440
|
+
facts={link.facts}
|
|
441
|
+
objectType={link.objectType}
|
|
456
442
|
size={16}
|
|
443
|
+
status={link.status}
|
|
457
444
|
/>
|
|
458
445
|
<span className="min-w-0 break-words">{link.label}</span>
|
|
459
446
|
</a>
|
|
@@ -462,26 +449,6 @@ export function ConversationAnnotations(props: {
|
|
|
462
449
|
);
|
|
463
450
|
}
|
|
464
451
|
|
|
465
|
-
function resourceLinkTitle(link: {
|
|
466
|
-
description?: string;
|
|
467
|
-
label: string;
|
|
468
|
-
plugin: string;
|
|
469
|
-
status?: ResourceLinkStatus;
|
|
470
|
-
}): string {
|
|
471
|
-
const statusLabel = link.status
|
|
472
|
-
? {
|
|
473
|
-
open: "Open",
|
|
474
|
-
draft: "Draft",
|
|
475
|
-
closed: "Closed",
|
|
476
|
-
merged: "Merged",
|
|
477
|
-
warning: "Needs attention",
|
|
478
|
-
}[link.status]
|
|
479
|
-
: undefined;
|
|
480
|
-
return [link.label, link.plugin, statusLabel, link.description]
|
|
481
|
-
.filter(Boolean)
|
|
482
|
-
.join(" · ");
|
|
483
|
-
}
|
|
484
|
-
|
|
485
452
|
function LocationLink(props: { label: string; locationUrl?: string }) {
|
|
486
453
|
return props.locationUrl ? (
|
|
487
454
|
<a
|