@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.
Files changed (36) hide show
  1. package/dist/app.js +3 -3
  2. package/dist/client.js +76 -76
  3. package/dist/index.js +3 -3
  4. package/dist/tailwind.css +1 -1
  5. package/package.json +4 -4
  6. package/src/client/App.tsx +11 -0
  7. package/src/client/components/Metric.tsx +0 -32
  8. package/src/client/components/ProfileMenu.tsx +56 -4
  9. package/src/client/components/layout/DashboardChrome.tsx +3 -3
  10. package/src/client/components/layout/DashboardHeader.tsx +41 -4
  11. package/src/client/components/layout/NavRail.tsx +43 -40
  12. package/src/client/conversations/ConversationComposer.tsx +7 -4
  13. package/src/client/conversations/ConversationDetails.tsx +117 -162
  14. package/src/client/conversations/ConversationHeader.tsx +119 -133
  15. package/src/client/conversations/ConversationHeaderActions.tsx +92 -120
  16. package/src/client/conversations/ConversationMeta.tsx +49 -44
  17. package/src/client/conversations/ConversationOverflowMenu.tsx +59 -0
  18. package/src/client/conversations/ConversationPage.tsx +33 -368
  19. package/src/client/conversations/ConversationReplyFooter.tsx +342 -0
  20. package/src/client/conversations/ConversationSidebar.tsx +119 -60
  21. package/src/client/conversations/ConversationWorkspace.tsx +8 -3
  22. package/src/client/conversations/TelemetryMetrics.tsx +0 -14
  23. package/src/client/conversations/TranscriptView.tsx +15 -32
  24. package/src/client/conversations/UsageCard.tsx +1 -15
  25. package/src/client/conversations/composerAutocorrect.ts +12 -0
  26. package/src/client/conversations/conversationAge.ts +24 -0
  27. package/src/client/conversations/conversationRoutes.ts +14 -5
  28. package/src/client/conversations/conversationSections.ts +66 -48
  29. package/src/client/conversations/useConversationFinishedIndicators.ts +40 -8
  30. package/src/client/pages/settings/SettingsPage.tsx +28 -0
  31. package/src/client/review-desk/ConversationReviewItems.tsx +99 -0
  32. package/src/client/review-desk/queries.ts +30 -6
  33. package/src/mock-reporting/routes.ts +1 -1
  34. package/src/tailwind.css +4 -0
  35. package/src/client/conversations/ConversationHeaderMeta.tsx +0 -20
  36. package/src/client/review-desk/ConversationReviewBar.tsx +0 -67
@@ -153,13 +153,20 @@ export function useReviewItemAction() {
153
153
  });
154
154
  }
155
155
 
156
- const NO_CONVERSATIONS: ReadonlySet<string> = new Set();
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. Today only the review
160
- * desk sets this: a linked open action item assigned to the viewer.
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 useWaitingConversationIds(): ReadonlySet<string> {
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 ids = query.data?.conversationIds;
175
- return useMemo(() => (ids ? new Set(ids) : NO_CONVERSATIONS), [ids]);
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, { conversationIds: [] }),
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
- }