@sentry/junior-dashboard 0.290.0 → 0.291.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 +3 -3
- package/dist/client-manifest.json +1 -1
- package/dist/index.js +3 -3
- package/dist/public/chunks/{AdminPage-htjffg0n.js → AdminPage-nus5ycri.js} +1 -1
- package/dist/public/chunks/{Area-hr2tz6ad.js → Area-gt1sdk4c.js} +1 -1
- package/dist/public/chunks/{AutomationPage-eihr9acm.js → AutomationPage-gkkuw17m.js} +1 -1
- package/dist/public/chunks/{AutomationRunDetails-op6rfaji.js → AutomationRunDetails-najm4x1j.js} +1 -1
- package/dist/public/chunks/{AutomationRunsPage-sx9tdkxv.js → AutomationRunsPage-bx3nhkyu.js} +1 -1
- package/dist/public/chunks/{AutomationsPage-mnstyn9j.js → AutomationsPage-o1gvds5a.js} +1 -1
- package/dist/public/chunks/{BarChart-cg02osy4.js → BarChart-nm91dx0i.js} +1 -1
- package/dist/public/chunks/{BoardPage-mbypholh.js → BoardPage-bnp4bh2y.js} +1 -1
- package/dist/public/chunks/{CodeChangeRow-oyge0uo2.js → CodeChangeRow-l7msz02v.js} +1 -1
- package/dist/public/chunks/{CodePage-ojiokuht.js → CodePage-eb9xfehg.js} +1 -1
- package/dist/public/chunks/{CodeSummaryCards-gikkczl6.js → CodeSummaryCards-ko46g18h.js} +1 -1
- package/dist/public/chunks/{ConnectionsPage-l2d6sesm.js → ConnectionsPage-bs0trwlu.js} +1 -1
- package/dist/public/chunks/{DrawerContent-jt25bpic.js → DrawerContent-clt2v4h5.js} +1 -1
- package/dist/public/chunks/{FilterBar-h4ab22b1.js → FilterBar-k012tagh.js} +1 -1
- package/dist/public/chunks/{FormNotice-oukmcfaj.js → FormNotice-ndbxjxml.js} +1 -1
- package/dist/public/chunks/{LocationDetailPage-gldsmom2.js → LocationDetailPage-lmq3fzwb.js} +1 -1
- package/dist/public/chunks/{LocationsPage-glec25wm.js → LocationsPage-iuycwgrk.js} +1 -1
- package/dist/public/chunks/{McpSettingsPage-nfv7qia1.js → McpSettingsPage-jt621pk7.js} +1 -1
- package/dist/public/chunks/{PeoplePage-kd1ad63d.js → PeoplePage-cq7tlf7s.js} +1 -1
- package/dist/public/chunks/{PersonProfilePage-diqz6hmw.js → PersonProfilePage-k6z8ayic.js} +1 -1
- package/dist/public/chunks/{PersonalTokensPage-mwkwnlc7.js → PersonalTokensPage-f3zhm3px.js} +1 -1
- package/dist/public/chunks/{PluginReportRecordSet-ea6phh3k.js → PluginReportRecordSet-ovmfoi5x.js} +1 -1
- package/dist/public/chunks/{PluginUserPage-l7q0ylyz.js → PluginUserPage-mjr7t9js.js} +1 -1
- package/dist/public/chunks/{RepositoryPage-f61pzf0s.js → RepositoryPage-miaqb63z.js} +1 -1
- package/dist/public/chunks/{SettingsPage-oqgh66n1.js → SettingsPage-ocko5gzs.js} +1 -1
- package/dist/public/chunks/{SystemPage-mpp6dtwm.js → SystemPage-f9sgyr71.js} +1 -1
- package/dist/public/chunks/{WorkspaceFormPage-o74u0sno.js → WorkspaceFormPage-ovra0hwr.js} +1 -1
- package/dist/public/chunks/{WorkspacesPage-kfphmgpt.js → WorkspacesPage-m9o335es.js} +1 -1
- package/dist/public/chunks/{automationFormat-bhjz2hx6.js → automationFormat-f3vjb9y9.js} +1 -1
- package/dist/public/chunks/{chart-mxqu3c8e.js → chart-peynklgr.js} +1 -1
- package/dist/public/chunks/{code-highlighter-dd09ntlw.js → code-highlighter-jcl4p6jg.js} +1 -1
- package/dist/public/chunks/{format-eev8is9c.js → format-li35oiyp.js} +2 -2
- package/dist/public/chunks/{junior-btnqqkq5.js → junior-g9xga7oj.js} +2 -2
- package/dist/public/chunks/{workspaceQueries-i5xdl0za.js → workspaceQueries-ocke5763.js} +1 -1
- package/dist/public/{client-ll3qwj84.js → client-h0cvcz8x.js} +17 -17
- package/dist/public/styles-6XAAC7O5.css +2 -0
- package/dist/tailwind.css +1 -1
- package/package.json +4 -4
- package/src/client/conversations/ConversationMeta.tsx +127 -34
- package/src/client/conversations/conversationSections.ts +3 -2
- package/src/client/format.ts +1 -0
- package/src/client/types.ts +2 -0
- package/dist/public/styles-GFFU7LPU.css +0 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-dashboard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.291.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"remark-gfm": "^4.0.1",
|
|
46
46
|
"shiki": "4.1.0",
|
|
47
47
|
"zod": "^4.5.4",
|
|
48
|
-
"@sentry/junior-plugin-api": "0.
|
|
48
|
+
"@sentry/junior-plugin-api": "0.291.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@sentry/junior": "0.
|
|
51
|
+
"@sentry/junior": "0.291.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@fontsource-variable/inter": "^5.3.0",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"typescript": "^7.0.2",
|
|
73
73
|
"unrun": "^0.3.1",
|
|
74
74
|
"vitest": "^4.1.12",
|
|
75
|
-
"@sentry/junior": "0.
|
|
75
|
+
"@sentry/junior": "0.291.0"
|
|
76
76
|
},
|
|
77
77
|
"scripts": {
|
|
78
78
|
"build": "pnpm --filter @sentry/junior-plugin-api build && pnpm --filter @sentry/junior build && pnpm run build:css && pnpm run build:client && pnpm run build:server",
|
|
@@ -9,7 +9,13 @@ import {
|
|
|
9
9
|
LockKeyhole,
|
|
10
10
|
TriangleAlert,
|
|
11
11
|
} from "lucide-react";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
useLayoutEffect,
|
|
14
|
+
useRef,
|
|
15
|
+
useState,
|
|
16
|
+
useSyncExternalStore,
|
|
17
|
+
type ReactNode,
|
|
18
|
+
} from "react";
|
|
13
19
|
import { Link } from "react-router";
|
|
14
20
|
import type { ConversationDetailReport } from "@sentry/junior/api/schema";
|
|
15
21
|
|
|
@@ -184,50 +190,137 @@ function SidebarAnnotationIconFacepile(props: {
|
|
|
184
190
|
<span
|
|
185
191
|
className={cn(
|
|
186
192
|
// Isolate stacking context so z-index only orders chips inside the pile.
|
|
187
|
-
|
|
188
|
-
"relative isolate inline-flex h-[18px] items-center pr-0.5",
|
|
193
|
+
"relative isolate inline-flex h-[18px] min-w-0 items-center",
|
|
189
194
|
props.className,
|
|
190
195
|
)}
|
|
191
196
|
>
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
197
|
+
<FittingIcons
|
|
198
|
+
// The padding keeps the cutout rings inside the clipped row.
|
|
199
|
+
className="-m-0.5 h-[22px] min-w-[22px] p-0.5"
|
|
200
|
+
icons={props.annotations.map((annotation, index) => (
|
|
201
|
+
<SidebarAnnotationStatusChip
|
|
202
|
+
annotation={annotation}
|
|
203
|
+
cutoutColor={props.cutoutColor}
|
|
204
|
+
key={annotation.key}
|
|
205
|
+
// Each chip to the right layers above the chip before it.
|
|
206
|
+
stacked={index > 0}
|
|
207
|
+
zIndex={index + 1}
|
|
208
|
+
/>
|
|
209
|
+
))}
|
|
210
|
+
overflow={(count) => (
|
|
211
|
+
<span
|
|
212
|
+
aria-hidden="true"
|
|
213
|
+
className="relative -ml-0.5 box-border inline-flex h-[18px] min-w-[18px] shrink-0 items-center justify-center rounded-full border border-dashboard-border-strong bg-dashboard-control px-1 font-sans text-2xs tabular-nums leading-none text-dashboard-text-muted"
|
|
214
|
+
style={{
|
|
215
|
+
boxShadow: `0 0 0 2px ${props.cutoutColor}`,
|
|
216
|
+
zIndex: props.annotations.length + 1,
|
|
217
|
+
}}
|
|
218
|
+
>
|
|
219
|
+
+{count}
|
|
220
|
+
</span>
|
|
221
|
+
)}
|
|
222
|
+
/>
|
|
202
223
|
</span>
|
|
203
224
|
);
|
|
204
225
|
}
|
|
205
226
|
|
|
206
|
-
/**
|
|
227
|
+
/**
|
|
228
|
+
* Show the icons that fit in the row and a +N count for the rest. Icons that
|
|
229
|
+
* do not fit wrap onto lines that the row clips, so the count follows the
|
|
230
|
+
* real width.
|
|
231
|
+
*/
|
|
232
|
+
function FittingIcons(props: {
|
|
233
|
+
className: string;
|
|
234
|
+
icons: ReactNode[];
|
|
235
|
+
overflow(count: number): ReactNode;
|
|
236
|
+
}) {
|
|
237
|
+
const rowRef = useRef<HTMLSpanElement>(null);
|
|
238
|
+
const overflowRef = useRef<HTMLSpanElement>(null);
|
|
239
|
+
const total = props.icons.length;
|
|
240
|
+
const [shown, setShown] = useState(total);
|
|
241
|
+
|
|
242
|
+
useLayoutEffect(() => {
|
|
243
|
+
const row = rowRef.current;
|
|
244
|
+
if (!row) return;
|
|
245
|
+
const countFirstLine = () => {
|
|
246
|
+
const items = Array.from(row.children);
|
|
247
|
+
const bottom = items[0]?.getBoundingClientRect().bottom ?? 0;
|
|
248
|
+
return items.filter((item) => item.getBoundingClientRect().top < bottom)
|
|
249
|
+
.length;
|
|
250
|
+
};
|
|
251
|
+
const measure = () => {
|
|
252
|
+
// Measure without the +N first. Otherwise its own width keeps the
|
|
253
|
+
// last icons hidden after the row grows wide enough for all of them.
|
|
254
|
+
const overflow = overflowRef.current;
|
|
255
|
+
if (overflow) overflow.style.display = "none";
|
|
256
|
+
const fitting = countFirstLine();
|
|
257
|
+
if (overflow) overflow.style.display = "";
|
|
258
|
+
setShown(fitting === total || !overflow ? fitting : countFirstLine());
|
|
259
|
+
};
|
|
260
|
+
measure();
|
|
261
|
+
const observer = new ResizeObserver(measure);
|
|
262
|
+
observer.observe(row);
|
|
263
|
+
return () => observer.disconnect();
|
|
264
|
+
// Run again when `shown` changes: the +N that mounts takes width, and
|
|
265
|
+
// this pass counts it before paint. The observer would run after paint.
|
|
266
|
+
}, [shown, total]);
|
|
267
|
+
|
|
268
|
+
return (
|
|
269
|
+
<>
|
|
270
|
+
<span
|
|
271
|
+
className={cn(
|
|
272
|
+
// The row gap pushes wrapped lines fully outside the clip.
|
|
273
|
+
"flex flex-wrap items-center gap-y-6 overflow-hidden",
|
|
274
|
+
props.className,
|
|
275
|
+
)}
|
|
276
|
+
ref={rowRef}
|
|
277
|
+
>
|
|
278
|
+
{props.icons}
|
|
279
|
+
</span>
|
|
280
|
+
{shown < total ? (
|
|
281
|
+
<span className="contents" ref={overflowRef}>
|
|
282
|
+
{props.overflow(total - shown)}
|
|
283
|
+
</span>
|
|
284
|
+
) : null}
|
|
285
|
+
</>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** One shared label with the status icons that fit and a count of the rest. */
|
|
207
290
|
function SidebarAnnotationGroupChip(props: {
|
|
208
291
|
group: SidebarAnnotationBadgeGroup;
|
|
209
292
|
}) {
|
|
210
293
|
return (
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
294
|
+
// No min-w-0: a chip shrinks only to one icon and its label, so the
|
|
295
|
+
// longest group gives up icons before a shorter one loses its label.
|
|
296
|
+
<span className="inline-flex h-5 items-center gap-1 rounded-full border border-dashboard-border-strong bg-dashboard-control px-1.5 font-sans text-2xs leading-none text-dashboard-text-muted">
|
|
297
|
+
<FittingIcons
|
|
298
|
+
className="h-3.5 min-w-3.5 gap-x-1"
|
|
299
|
+
icons={props.group.annotations.flatMap((annotation) =>
|
|
300
|
+
annotation.objectType ? (
|
|
301
|
+
<ObjectIcon
|
|
302
|
+
{...annotation}
|
|
303
|
+
objectType={annotation.objectType}
|
|
304
|
+
key={annotation.key}
|
|
305
|
+
decorative
|
|
306
|
+
size={14}
|
|
307
|
+
/>
|
|
308
|
+
) : annotation.icon ? (
|
|
309
|
+
<SidebarAnnotationIcon
|
|
310
|
+
decorative
|
|
311
|
+
icon={annotation.icon}
|
|
312
|
+
key={annotation.key}
|
|
313
|
+
size={11}
|
|
314
|
+
/>
|
|
315
|
+
) : (
|
|
316
|
+
[]
|
|
317
|
+
),
|
|
318
|
+
)}
|
|
319
|
+
overflow={(count) => (
|
|
320
|
+
<span className="shrink-0 tabular-nums">+{count}</span>
|
|
321
|
+
)}
|
|
322
|
+
/>
|
|
323
|
+
<span className="max-w-40 shrink-0 truncate whitespace-nowrap">
|
|
231
324
|
{props.group.label}
|
|
232
325
|
</span>
|
|
233
326
|
</span>
|
|
@@ -65,8 +65,8 @@ export function buildConversationSections(
|
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* True when the conversation waits on a person: its id is in `attentionIds`,
|
|
68
|
-
*
|
|
69
|
-
* not running in it.
|
|
68
|
+
* a Turn waits on a person to finish an authorization, or it has unfinished
|
|
69
|
+
* work, such as an open pull request, while Junior is not running in it.
|
|
70
70
|
*/
|
|
71
71
|
function needsAttention(
|
|
72
72
|
conversation: Conversation,
|
|
@@ -74,6 +74,7 @@ function needsAttention(
|
|
|
74
74
|
): boolean {
|
|
75
75
|
return (
|
|
76
76
|
attentionIds.has(conversation.id) ||
|
|
77
|
+
conversation.awaitingAuthorization === true ||
|
|
77
78
|
(conversation.unfinishedWork === true && conversation.status !== "active")
|
|
78
79
|
);
|
|
79
80
|
}
|
package/src/client/format.ts
CHANGED
|
@@ -910,6 +910,7 @@ export function buildConversations(
|
|
|
910
910
|
parentConversationId: summary.parentConversationId,
|
|
911
911
|
threads: summary.threads && buildConversations(summary.threads),
|
|
912
912
|
unfinishedWork: summary.unfinishedWork,
|
|
913
|
+
awaitingAuthorization: summary.awaitingAuthorization,
|
|
913
914
|
visibility: summary.visibility,
|
|
914
915
|
}))
|
|
915
916
|
.sort((a, b) => compareTimeDesc(a.lastSeenAt, b.lastSeenAt));
|
package/src/client/types.ts
CHANGED
|
@@ -199,6 +199,8 @@ export type Conversation = {
|
|
|
199
199
|
/** Visible Threads under this row, newest first. */
|
|
200
200
|
threads?: Conversation[];
|
|
201
201
|
unfinishedWork?: boolean;
|
|
202
|
+
/** A Turn waits on a person to finish an authorization. Server-owned. */
|
|
203
|
+
awaitingAuthorization?: boolean;
|
|
202
204
|
visibility?: ConversationSummaryReport["visibility"];
|
|
203
205
|
};
|
|
204
206
|
|