@sentry/junior-dashboard 0.273.0 → 0.275.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.js +76 -76
- package/dist/index.js +3 -3
- package/dist/tailwind.css +1 -1
- package/package.json +4 -4
- package/src/client/App.tsx +11 -0
- package/src/client/components/Metric.tsx +0 -32
- package/src/client/components/ProfileMenu.tsx +56 -4
- package/src/client/components/layout/DashboardChrome.tsx +3 -3
- package/src/client/components/layout/DashboardHeader.tsx +41 -4
- package/src/client/components/layout/NavRail.tsx +43 -40
- package/src/client/conversations/ConversationComposer.tsx +7 -4
- package/src/client/conversations/ConversationDetails.tsx +117 -162
- package/src/client/conversations/ConversationHeader.tsx +119 -133
- package/src/client/conversations/ConversationHeaderActions.tsx +92 -120
- package/src/client/conversations/ConversationMeta.tsx +49 -44
- package/src/client/conversations/ConversationOverflowMenu.tsx +59 -0
- package/src/client/conversations/ConversationPage.tsx +33 -368
- package/src/client/conversations/ConversationReplyFooter.tsx +342 -0
- package/src/client/conversations/ConversationSidebar.tsx +119 -60
- package/src/client/conversations/ConversationWorkspace.tsx +8 -3
- package/src/client/conversations/TelemetryMetrics.tsx +0 -14
- package/src/client/conversations/TranscriptView.tsx +15 -32
- package/src/client/conversations/UsageCard.tsx +1 -15
- package/src/client/conversations/composerAutocorrect.ts +12 -0
- package/src/client/conversations/conversationAge.ts +24 -0
- package/src/client/conversations/conversationRoutes.ts +14 -5
- package/src/client/conversations/conversationSections.ts +66 -48
- package/src/client/conversations/useConversationFinishedIndicators.ts +40 -8
- package/src/client/pages/settings/SettingsPage.tsx +28 -0
- package/src/client/review-desk/ConversationReviewItems.tsx +99 -0
- package/src/client/review-desk/queries.ts +30 -6
- package/src/mock-reporting/routes.ts +1 -1
- package/src/tailwind.css +4 -0
- package/src/client/conversations/ConversationHeaderMeta.tsx +0 -20
- package/src/client/review-desk/ConversationReviewBar.tsx +0 -67
|
@@ -153,13 +153,20 @@ export function useReviewItemAction() {
|
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
/** Newest open Review item title and item count for one waiting Conversation. */
|
|
157
|
+
export type WaitingConversation = { count: number; title: string };
|
|
158
|
+
|
|
159
|
+
const NO_WAITING: ReadonlyMap<string, WaitingConversation> = new Map();
|
|
157
160
|
|
|
158
161
|
/**
|
|
159
|
-
* Return the Conversations that wait on the viewer
|
|
160
|
-
* desk sets this: a linked open action item assigned to the
|
|
162
|
+
* Return the Conversations that wait on the viewer, by Conversation id. Today
|
|
163
|
+
* only the review desk sets this: a linked open action item assigned to the
|
|
164
|
+
* viewer.
|
|
161
165
|
*/
|
|
162
|
-
export function
|
|
166
|
+
export function useWaitingConversations(): ReadonlyMap<
|
|
167
|
+
string,
|
|
168
|
+
WaitingConversation
|
|
169
|
+
> {
|
|
163
170
|
const query = useQuery({
|
|
164
171
|
queryKey: [...REVIEW_ITEMS_QUERY_KEY, "waiting-conversations"],
|
|
165
172
|
queryFn: ({ signal }) =>
|
|
@@ -171,6 +178,23 @@ export function useWaitingConversationIds(): ReadonlySet<string> {
|
|
|
171
178
|
refetchInterval: COUNT_REFRESH_MS,
|
|
172
179
|
retry: false,
|
|
173
180
|
});
|
|
174
|
-
const
|
|
175
|
-
return useMemo(
|
|
181
|
+
const conversations = query.data?.conversations;
|
|
182
|
+
return useMemo(
|
|
183
|
+
() =>
|
|
184
|
+
conversations
|
|
185
|
+
? new Map(
|
|
186
|
+
conversations.map(({ conversationId, count, title }) => [
|
|
187
|
+
conversationId,
|
|
188
|
+
{ count, title },
|
|
189
|
+
]),
|
|
190
|
+
)
|
|
191
|
+
: NO_WAITING,
|
|
192
|
+
[conversations],
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Return the ids of the Conversations that wait on the viewer. */
|
|
197
|
+
export function useWaitingConversationIds(): ReadonlySet<string> {
|
|
198
|
+
const waiting = useWaitingConversations();
|
|
199
|
+
return useMemo(() => new Set(waiting.keys()), [waiting]);
|
|
176
200
|
}
|
|
@@ -331,7 +331,7 @@ export function createMockReportingApi(): Hono<{
|
|
|
331
331
|
jsonResponse(reviewItemCountSchema, { needsViewer: 0 }),
|
|
332
332
|
);
|
|
333
333
|
app.get("/review-items/waiting-conversations", () =>
|
|
334
|
-
jsonResponse(reviewItemWaitingConversationsSchema, {
|
|
334
|
+
jsonResponse(reviewItemWaitingConversationsSchema, { conversations: [] }),
|
|
335
335
|
);
|
|
336
336
|
app.get("/review-items/:id", () =>
|
|
337
337
|
errorResponse("Review item not found.", 404),
|
package/src/tailwind.css
CHANGED
|
@@ -294,6 +294,10 @@
|
|
|
294
294
|
/* Style one-off values that the token and palette mirror cannot cover. */
|
|
295
295
|
@custom-variant light (&:where([data-theme="light"], [data-theme="light"] *));
|
|
296
296
|
|
|
297
|
+
/* Desktop windows tall enough to afford the top bar. Shorter windows, such as
|
|
298
|
+
most laptops, keep the nav rail so conversations get the height. */
|
|
299
|
+
@custom-variant tall (@media (min-height: 62.5rem));
|
|
300
|
+
|
|
297
301
|
@layer base {
|
|
298
302
|
:root {
|
|
299
303
|
color-scheme: var(--dashboard-color-scheme, dark);
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
/** Render the compact owner and runtime line below a conversation title. */
|
|
4
|
-
export function ConversationHeaderMeta(props: {
|
|
5
|
-
identity: ReactNode;
|
|
6
|
-
stats: ReactNode;
|
|
7
|
-
}) {
|
|
8
|
-
if (!props.identity && !props.stats) return null;
|
|
9
|
-
return (
|
|
10
|
-
<div className="flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-1">
|
|
11
|
-
{props.identity ? (
|
|
12
|
-
<span className="min-w-0 max-w-full truncate">{props.identity}</span>
|
|
13
|
-
) : null}
|
|
14
|
-
{props.identity && props.stats ? (
|
|
15
|
-
<span className="text-dashboard-text-muted">·</span>
|
|
16
|
-
) : null}
|
|
17
|
-
{props.stats ? <span className="min-w-0">{props.stats}</span> : null}
|
|
18
|
-
</div>
|
|
19
|
-
);
|
|
20
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { ChevronRight } from "lucide-react";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
|
|
4
|
-
import { Drawer } from "../components/Drawer";
|
|
5
|
-
import { LoadMorePagination } from "../components/Pagination";
|
|
6
|
-
import { ReviewItemCard } from "./ReviewItemCard";
|
|
7
|
-
import { useReviewItemsData } from "./queries";
|
|
8
|
-
|
|
9
|
-
/** `more` marks a count of the loaded pages only, such as "50+". */
|
|
10
|
-
function itemCountLabel(count: number, more: boolean): string {
|
|
11
|
-
if (more) return `${count}+ open review items`;
|
|
12
|
-
return count === 1 ? "1 open review item" : `${count} open review items`;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Show how many open Review items are linked to a Conversation, above its
|
|
17
|
-
* message box. The bar opens a side panel where the viewer can act on each.
|
|
18
|
-
*/
|
|
19
|
-
export function ConversationReviewBar(props: { conversationId: string }) {
|
|
20
|
-
const [open, setOpen] = useState(false);
|
|
21
|
-
const { items, query } = useReviewItemsData({
|
|
22
|
-
conversationId: props.conversationId,
|
|
23
|
-
});
|
|
24
|
-
if (items.length === 0) return null;
|
|
25
|
-
const more = Boolean(query.hasNextPage);
|
|
26
|
-
const label = itemCountLabel(items.length, more);
|
|
27
|
-
return (
|
|
28
|
-
<>
|
|
29
|
-
<button
|
|
30
|
-
className="mb-2 flex w-full cursor-pointer items-center justify-between gap-3 rounded-lg border border-violet-300/25 bg-violet-300/[0.06] px-3 py-2 text-left font-sans text-sm text-dashboard-text transition-colors hover:bg-violet-300/[0.1]"
|
|
31
|
-
onClick={() => setOpen(true)}
|
|
32
|
-
type="button"
|
|
33
|
-
>
|
|
34
|
-
<span className="flex items-center gap-2">
|
|
35
|
-
<span
|
|
36
|
-
aria-hidden="true"
|
|
37
|
-
className="size-2 shrink-0 rounded-full bg-violet-300"
|
|
38
|
-
/>
|
|
39
|
-
{label}
|
|
40
|
-
</span>
|
|
41
|
-
<ChevronRight aria-hidden="true" size={16} />
|
|
42
|
-
</button>
|
|
43
|
-
{open ? (
|
|
44
|
-
<Drawer
|
|
45
|
-
closeLabel="Close review items"
|
|
46
|
-
header={
|
|
47
|
-
<h2 className="m-0 font-sans text-base font-semibold">{label}</h2>
|
|
48
|
-
}
|
|
49
|
-
label="Review items"
|
|
50
|
-
onClose={() => setOpen(false)}
|
|
51
|
-
openKey={props.conversationId}
|
|
52
|
-
>
|
|
53
|
-
<div className="grid gap-3">
|
|
54
|
-
{items.map((item) => (
|
|
55
|
-
<ReviewItemCard item={item} key={item.id} />
|
|
56
|
-
))}
|
|
57
|
-
<LoadMorePagination
|
|
58
|
-
hasMore={more}
|
|
59
|
-
loading={query.isFetchingNextPage}
|
|
60
|
-
onLoadMore={() => void query.fetchNextPage()}
|
|
61
|
-
/>
|
|
62
|
-
</div>
|
|
63
|
-
</Drawer>
|
|
64
|
-
) : null}
|
|
65
|
-
</>
|
|
66
|
-
);
|
|
67
|
-
}
|