camox 0.63.0 → 0.65.1

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 (41) hide show
  1. package/dist/core/createApp.d.ts +28 -28
  2. package/dist/core/createLayout.d.ts +1 -1
  3. package/dist/core/derivedRoutes.js +3 -30
  4. package/dist/core/editing/createEditableBlock.d.ts +604 -604
  5. package/dist/features/canvas/canvasCamera.js +11 -2
  6. package/dist/features/canvas/useCanvasCamera.js +14 -10
  7. package/dist/features/page/CuratedPageContent.js +2 -1
  8. package/dist/features/page/UnplacedBlockContent.js +52 -0
  9. package/dist/features/preview/components/PreviewPanel.js +40 -12
  10. package/dist/features/preview/components/SidebarStack.js +78 -9
  11. package/dist/features/preview/strayCaretGuard.js +34 -0
  12. package/dist/features/provider/CoreCamoxProvider.js +5 -3
  13. package/dist/features/routes/pageRuntime.d.ts +2 -0
  14. package/dist/features/routes/pageRuntime.js +8 -5
  15. package/dist/features/runtime/pageApp.js +111 -74
  16. package/dist/features/runtime/pageClient.js +22 -2
  17. package/dist/features/runtime/runtime.d.ts +10 -0
  18. package/dist/features/runtime/runtime.js +314 -4
  19. package/dist/features/runtime/runtimeRoutes.d.ts +5 -0
  20. package/dist/features/runtime/runtimeRoutes.js +5 -0
  21. package/dist/features/studio/components/ChatWidget.js +88 -62
  22. package/dist/features/studio/components/ConnectAgent.js +313 -0
  23. package/dist/features/studio/components/Patrol.js +455 -205
  24. package/dist/features/studio/components/ReviewDraftSheet.js +431 -334
  25. package/dist/features/studio/components/Squareling.js +74 -41
  26. package/dist/features/studio/components/ThreadComposer.js +130 -107
  27. package/dist/features/studio/components/ThreadMessages.js +82 -13
  28. package/dist/features/studio/components/clientLogoPaths.js +10 -0
  29. package/dist/features/studio/findingSentence.js +37 -0
  30. package/dist/features/studio/reportSentence.js +15 -0
  31. package/dist/features/studio/studioStore.js +23 -1
  32. package/dist/features/studio/workingSentence.js +8 -0
  33. package/dist/lib/api-client.d.ts +1 -0
  34. package/dist/lib/auth.js +34 -32
  35. package/dist/lib/queries.js +9 -1
  36. package/dist/lib/server-auth-cookie.js +17 -4
  37. package/dist/lib/studio-reads.d.ts +1 -1
  38. package/dist/lib/studio-reads.js +5 -1
  39. package/dist/package.js +1 -1
  40. package/dist/studio.css +1 -1
  41. package/package.json +15 -4
@@ -5,20 +5,25 @@ import { useNavigate } from "../../navigation/navigation.js";
5
5
  import { AuthContext } from "../../../lib/auth.js";
6
6
  import { reads, useReadQuery } from "../../../lib/studio-reads.js";
7
7
  import { cn } from "../../../lib/utils.js";
8
+ import { patrolMutations } from "../../../lib/queries.js";
8
9
  import { AssetLightbox } from "../../preview/components/AssetLightbox.js";
9
10
  import { BOTTOM_CARD_EDGES, CARD_BODY_EDGES } from "../../preview/components/SidebarStack.js";
10
11
  import { editCollectionItemPath } from "../routes.js";
12
+ import { studioStore } from "../studioStore.js";
11
13
  import { timeAgo } from "../draftLabel.js";
14
+ import { askAgentMessage, dismissLabel, dismissedSentence, findingSentence, fixLabel } from "../findingSentence.js";
12
15
  import { useShowInCanvas } from "../showInCanvas.js";
13
16
  import { Squareling } from "./Squareling.js";
14
17
  import { moreSentence, reportSentence, shortTimeAgo, whereReportLeads } from "../reportSentence.js";
15
18
  import { singleLocaleSentence, workingSentence } from "../workingSentence.js";
16
19
  import { c } from "react/compiler-runtime";
17
20
  import * as React from "react";
18
- import { jsx, jsxs } from "react/jsx-runtime";
21
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
22
+ import { reportLocale } from "@camox/api-contract/patrol";
23
+ import { useMutation } from "@tanstack/react-query";
24
+ import { Button } from "@camox/ui/button";
19
25
  import { Popover, PopoverContent, PopoverTitle, PopoverTrigger } from "@camox/ui/popover";
20
26
  import { Badge } from "@camox/ui/badge";
21
- import { reportLocale } from "@camox/api-contract/patrol";
22
27
 
23
28
  //#region src/features/studio/components/Patrol.tsx
24
29
  /**
@@ -95,7 +100,7 @@ function Patrol(t0) {
95
100
  return t7;
96
101
  }
97
102
  function ProjectPatrol(t0) {
98
- const $ = c(36);
103
+ const $ = c(53);
99
104
  const { projectId, inDraft } = t0;
100
105
  let t1;
101
106
  if ($[0] !== projectId) {
@@ -132,103 +137,166 @@ function ProjectPatrol(t0) {
132
137
  const roster = useMovingRows(t4);
133
138
  const [openFileId, setOpenFileId] = React.useState(null);
134
139
  const showReport = useShowReport(inDraft, setOpenFileId);
135
- if (!shown) return null;
140
+ const navigate = useNavigate();
136
141
  let t5;
137
- if ($[9] !== shown) {
138
- t5 = () => setHeldOrder((held) => held ?? shown.patrollers.map(_temp2));
139
- $[9] = shown;
140
- $[10] = t5;
141
- } else t5 = $[10];
142
- const hold = t5;
142
+ if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
143
+ t5 = patrolMutations.applyFix();
144
+ $[9] = t5;
145
+ } else t5 = $[9];
146
+ const applyFix = useMutation(t5);
143
147
  let t6;
144
- if ($[11] !== hold) {
145
- t6 = (id_1) => {
148
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
149
+ t6 = patrolMutations.dismissFinding();
150
+ $[10] = t6;
151
+ } else t6 = $[10];
152
+ const dismissFinding = useMutation(t6);
153
+ if (!shown) return null;
154
+ let t7;
155
+ if ($[11] !== shown) {
156
+ t7 = () => setHeldOrder((held) => held ?? shown.patrollers.map(_temp2));
157
+ $[11] = shown;
158
+ $[12] = t7;
159
+ } else t7 = $[12];
160
+ const hold = t7;
161
+ let t8;
162
+ if ($[13] !== hold) {
163
+ t8 = (id_1) => {
146
164
  setOpen(id_1);
147
165
  if (id_1) hold();
148
166
  else if (!pointerIn.current) setHeldOrder(null);
149
167
  };
150
- $[11] = hold;
151
- $[12] = t6;
152
- } else t6 = $[12];
153
- const openReports = t6;
154
- let t7;
155
- if ($[13] !== hold) {
156
- t7 = () => {
168
+ $[13] = hold;
169
+ $[14] = t8;
170
+ } else t8 = $[14];
171
+ const openReports = t8;
172
+ let t9;
173
+ if ($[15] !== hold) {
174
+ t9 = () => {
157
175
  pointerIn.current = true;
158
176
  hold();
159
177
  };
160
- $[13] = hold;
161
- $[14] = t7;
162
- } else t7 = $[14];
163
- let t8;
164
- if ($[15] !== open) {
165
- t8 = () => {
178
+ $[15] = hold;
179
+ $[16] = t9;
180
+ } else t9 = $[16];
181
+ let t10;
182
+ if ($[17] !== open) {
183
+ t10 = () => {
166
184
  pointerIn.current = false;
167
185
  if (!open) setHeldOrder(null);
168
186
  };
169
- $[15] = open;
170
- $[16] = t8;
171
- } else t8 = $[16];
172
- const t9 = locales?.length === 1;
173
- let t10;
174
- if ($[17] !== openReports || $[18] !== showReport) {
175
- t10 = (report) => {
187
+ $[17] = open;
188
+ $[18] = t10;
189
+ } else t10 = $[18];
190
+ const t11 = locales?.length === 1;
191
+ let t12;
192
+ if ($[19] !== openReports || $[20] !== showReport) {
193
+ t12 = (shown_0) => {
176
194
  openReports(null);
177
- showReport(report);
195
+ showReport(shown_0);
178
196
  };
179
- $[17] = openReports;
180
- $[18] = showReport;
181
- $[19] = t10;
182
- } else t10 = $[19];
183
- let t11;
184
- if ($[20] !== inDraft || $[21] !== now || $[22] !== open || $[23] !== openReports || $[24] !== shown || $[25] !== t10 || $[26] !== t9) {
185
- t11 = /* @__PURE__ */ jsx(PatrolRoster, {
197
+ $[19] = openReports;
198
+ $[20] = showReport;
199
+ $[21] = t12;
200
+ } else t12 = $[21];
201
+ let t13;
202
+ if ($[22] !== applyFix || $[23] !== projectId) {
203
+ t13 = (finding) => applyFix.mutate({
204
+ projectId,
205
+ findingId: finding.id
206
+ });
207
+ $[22] = applyFix;
208
+ $[23] = projectId;
209
+ $[24] = t13;
210
+ } else t13 = $[24];
211
+ let t14;
212
+ if ($[25] !== openReports) {
213
+ t14 = (patroller, finding_0) => {
214
+ openReports(null);
215
+ studioStore.trigger.askAgent({ text: askAgentMessage(finding_0, patroller.role) });
216
+ };
217
+ $[25] = openReports;
218
+ $[26] = t14;
219
+ } else t14 = $[26];
220
+ let t15;
221
+ if ($[27] !== dismissFinding || $[28] !== projectId) {
222
+ t15 = (finding_1) => dismissFinding.mutate({
223
+ projectId,
224
+ findingId: finding_1.id
225
+ });
226
+ $[27] = dismissFinding;
227
+ $[28] = projectId;
228
+ $[29] = t15;
229
+ } else t15 = $[29];
230
+ let t16;
231
+ if ($[30] !== navigate || $[31] !== openReports) {
232
+ t16 = (draft) => {
233
+ openReports(null);
234
+ navigate({
235
+ to: window.location.href,
236
+ draft: draft.id
237
+ });
238
+ };
239
+ $[30] = navigate;
240
+ $[31] = openReports;
241
+ $[32] = t16;
242
+ } else t16 = $[32];
243
+ let t17;
244
+ if ($[33] !== inDraft || $[34] !== now || $[35] !== open || $[36] !== openReports || $[37] !== shown || $[38] !== t11 || $[39] !== t12 || $[40] !== t13 || $[41] !== t14 || $[42] !== t15 || $[43] !== t16) {
245
+ t17 = /* @__PURE__ */ jsx(PatrolRoster, {
186
246
  view: shown,
187
247
  now,
188
248
  inDraft,
189
- singleLocale: t9,
249
+ singleLocale: t11,
190
250
  open,
191
251
  onOpenChange: openReports,
192
- onShow: t10
252
+ onShow: t12,
253
+ onApply: t13,
254
+ onAsk: t14,
255
+ onDismiss: t15,
256
+ onOpenPatrolDraft: t16
193
257
  });
194
- $[20] = inDraft;
195
- $[21] = now;
196
- $[22] = open;
197
- $[23] = openReports;
198
- $[24] = shown;
199
- $[25] = t10;
200
- $[26] = t9;
201
- $[27] = t11;
202
- } else t11 = $[27];
203
- let t12;
204
- if ($[28] !== openFileId) {
205
- t12 = openFileId && /* @__PURE__ */ jsx(AssetLightbox, {
258
+ $[33] = inDraft;
259
+ $[34] = now;
260
+ $[35] = open;
261
+ $[36] = openReports;
262
+ $[37] = shown;
263
+ $[38] = t11;
264
+ $[39] = t12;
265
+ $[40] = t13;
266
+ $[41] = t14;
267
+ $[42] = t15;
268
+ $[43] = t16;
269
+ $[44] = t17;
270
+ } else t17 = $[44];
271
+ let t18;
272
+ if ($[45] !== openFileId) {
273
+ t18 = openFileId && /* @__PURE__ */ jsx(AssetLightbox, {
206
274
  open: true,
207
275
  onOpenChange: (open_0) => {
208
276
  if (!open_0) setOpenFileId(null);
209
277
  },
210
278
  fileId: openFileId
211
279
  });
212
- $[28] = openFileId;
213
- $[29] = t12;
214
- } else t12 = $[29];
215
- let t13;
216
- if ($[30] !== roster || $[31] !== t11 || $[32] !== t12 || $[33] !== t7 || $[34] !== t8) {
217
- t13 = /* @__PURE__ */ jsxs("div", {
280
+ $[45] = openFileId;
281
+ $[46] = t18;
282
+ } else t18 = $[46];
283
+ let t19;
284
+ if ($[47] !== roster || $[48] !== t10 || $[49] !== t17 || $[50] !== t18 || $[51] !== t9) {
285
+ t19 = /* @__PURE__ */ jsxs("div", {
218
286
  ref: roster,
219
287
  className: "relative",
220
- onPointerEnter: t7,
221
- onPointerLeave: t8,
222
- children: [t11, t12]
288
+ onPointerEnter: t9,
289
+ onPointerLeave: t10,
290
+ children: [t17, t18]
223
291
  });
224
- $[30] = roster;
225
- $[31] = t11;
226
- $[32] = t12;
227
- $[33] = t7;
228
- $[34] = t8;
229
- $[35] = t13;
230
- } else t13 = $[35];
231
- return t13;
292
+ $[47] = roster;
293
+ $[48] = t10;
294
+ $[49] = t17;
295
+ $[50] = t18;
296
+ $[51] = t9;
297
+ $[52] = t19;
298
+ } else t19 = $[52];
299
+ return t19;
232
300
  }
233
301
  function _temp2(t0) {
234
302
  const { id: id_0 } = t0;
@@ -238,10 +306,15 @@ function _temp(t0) {
238
306
  const { id } = t0;
239
307
  return id;
240
308
  }
309
+ /** A report, as the Patrol shows its subject. */
310
+ const shownOf = (report) => ({
311
+ ...report,
312
+ locale: reportLocale(report.summary)
313
+ });
241
314
  /**
242
- * Shows a report's subject where it is, in the report's locale, and on Live for a Live report seen
243
- * from a draft: a page, block or item selected on the Canvas, a record in its collection, or a
244
- * file, opened over the Canvas.
315
+ * Shows a report's or a finding's subject where it is, in its locale, and on Live for a Live one
316
+ * seen from a draft: a page, block or item selected on the Canvas, a record in its collection, or
317
+ * a file, opened over the Canvas.
245
318
  */
246
319
  function useShowReport(inDraft, openFile) {
247
320
  const $ = c(6);
@@ -254,7 +327,7 @@ function useShowReport(inDraft, openFile) {
254
327
  const { place } = report;
255
328
  if (!place) return;
256
329
  const toLive = inDraft && report.live ? { draft: null } : {};
257
- const tag = reportLocale(report.summary);
330
+ const tag = report.locale;
258
331
  if (place.kind === "page") {
259
332
  const { pageId, blockId, itemId } = place;
260
333
  showInCanvas({
@@ -381,12 +454,12 @@ function _temp4() {
381
454
  * project with a single locale, the Translator invites the editor to add a language instead.
382
455
  */
383
456
  function PatrolRoster(t0) {
384
- const $ = c(17);
385
- const { view, now, inDraft, singleLocale, open, onOpenChange, onShow } = t0;
457
+ const $ = c(27);
458
+ const { view, now, inDraft, singleLocale, open, onOpenChange, onShow, onApply, onAsk, onDismiss, onOpenPatrolDraft } = t0;
386
459
  let t1;
387
- if ($[0] !== inDraft || $[1] !== now || $[2] !== onOpenChange || $[3] !== onShow || $[4] !== open || $[5] !== singleLocale || $[6] !== view.patrollers) {
460
+ if ($[0] !== inDraft || $[1] !== now || $[2] !== onApply || $[3] !== onAsk || $[4] !== onDismiss || $[5] !== onOpenChange || $[6] !== onOpenPatrolDraft || $[7] !== onShow || $[8] !== open || $[9] !== singleLocale || $[10] !== view.patrolDraft || $[11] !== view.patrollers) {
388
461
  let t2;
389
- if ($[8] !== inDraft || $[9] !== now || $[10] !== onOpenChange || $[11] !== onShow || $[12] !== open || $[13] !== singleLocale) {
462
+ if ($[13] !== inDraft || $[14] !== now || $[15] !== onApply || $[16] !== onAsk || $[17] !== onDismiss || $[18] !== onOpenChange || $[19] !== onOpenPatrolDraft || $[20] !== onShow || $[21] !== open || $[22] !== singleLocale || $[23] !== view.patrolDraft) {
390
463
  t2 = (patroller) => /* @__PURE__ */ jsx(PatrollerRow, {
391
464
  patroller,
392
465
  now,
@@ -394,35 +467,50 @@ function PatrolRoster(t0) {
394
467
  idle: singleLocale ? singleLocaleSentence(patroller.id) : void 0,
395
468
  open: open === patroller.id,
396
469
  onOpenChange: (next) => onOpenChange(next ? patroller.id : null),
397
- onShow
470
+ onShow,
471
+ onApply,
472
+ onAsk,
473
+ onDismiss,
474
+ patrolDraft: view.patrolDraft,
475
+ onOpenPatrolDraft
398
476
  }, patroller.id);
399
- $[8] = inDraft;
400
- $[9] = now;
401
- $[10] = onOpenChange;
402
- $[11] = onShow;
403
- $[12] = open;
404
- $[13] = singleLocale;
405
- $[14] = t2;
406
- } else t2 = $[14];
477
+ $[13] = inDraft;
478
+ $[14] = now;
479
+ $[15] = onApply;
480
+ $[16] = onAsk;
481
+ $[17] = onDismiss;
482
+ $[18] = onOpenChange;
483
+ $[19] = onOpenPatrolDraft;
484
+ $[20] = onShow;
485
+ $[21] = open;
486
+ $[22] = singleLocale;
487
+ $[23] = view.patrolDraft;
488
+ $[24] = t2;
489
+ } else t2 = $[24];
407
490
  t1 = view.patrollers.map(t2);
408
491
  $[0] = inDraft;
409
492
  $[1] = now;
410
- $[2] = onOpenChange;
411
- $[3] = onShow;
412
- $[4] = open;
413
- $[5] = singleLocale;
414
- $[6] = view.patrollers;
415
- $[7] = t1;
416
- } else t1 = $[7];
493
+ $[2] = onApply;
494
+ $[3] = onAsk;
495
+ $[4] = onDismiss;
496
+ $[5] = onOpenChange;
497
+ $[6] = onOpenPatrolDraft;
498
+ $[7] = onShow;
499
+ $[8] = open;
500
+ $[9] = singleLocale;
501
+ $[10] = view.patrolDraft;
502
+ $[11] = view.patrollers;
503
+ $[12] = t1;
504
+ } else t1 = $[12];
417
505
  let t2;
418
- if ($[15] !== t1) {
506
+ if ($[25] !== t1) {
419
507
  t2 = /* @__PURE__ */ jsx("ul", {
420
508
  className: "flex flex-col gap-px p-1",
421
509
  children: t1
422
510
  });
423
- $[15] = t1;
424
- $[16] = t2;
425
- } else t2 = $[16];
511
+ $[25] = t1;
512
+ $[26] = t2;
513
+ } else t2 = $[26];
426
514
  return t2;
427
515
  }
428
516
  /**
@@ -455,8 +543,8 @@ function WorkingArc() {
455
543
  return t0;
456
544
  }
457
545
  function PatrollerRow(t0) {
458
- const $ = c(53);
459
- const { patroller, now, inDraft, idle, open, onOpenChange, onShow } = t0;
546
+ const $ = c(65);
547
+ const { patroller, now, inDraft, idle, open, onOpenChange, onShow, onApply, onAsk, onDismiss, patrolDraft, onOpenPatrolDraft } = t0;
460
548
  const statusId = React.useId();
461
549
  let t1;
462
550
  if ($[0] !== patroller.id || $[1] !== patroller.working) {
@@ -467,173 +555,334 @@ function PatrollerRow(t0) {
467
555
  } else t1 = $[2];
468
556
  const working = t1;
469
557
  let t2;
470
- if ($[3] !== idle || $[4] !== now || $[5] !== patroller.lastActivityAt || $[6] !== working) {
471
- t2 = working ?? idle ?? (patroller.lastActivityAt === null ? "" : timeAgo(patroller.lastActivityAt, now));
558
+ if ($[3] !== idle || $[4] !== now || $[5] !== patroller.duty || $[6] !== patroller.lastActivityAt || $[7] !== working) {
559
+ t2 = working ?? idle ?? (patroller.duty === "atPublish" ? "Checks when you publish" : void 0) ?? (patroller.lastActivityAt === null ? "" : timeAgo(patroller.lastActivityAt, now));
472
560
  $[3] = idle;
473
561
  $[4] = now;
474
- $[5] = patroller.lastActivityAt;
475
- $[6] = working;
476
- $[7] = t2;
477
- } else t2 = $[7];
562
+ $[5] = patroller.duty;
563
+ $[6] = patroller.lastActivityAt;
564
+ $[7] = working;
565
+ $[8] = t2;
566
+ } else t2 = $[8];
478
567
  const subtitle = t2;
568
+ const count = patroller.findings.length;
479
569
  const t3 = open || void 0;
480
570
  const t4 = working ? statusId : void 0;
481
- const t5 = working ? "working" : "idle";
571
+ const t5 = working ? "working" : patroller.duty === "off" ? "asleep" : "idle";
482
572
  let t6;
483
- if ($[8] !== patroller.id || $[9] !== t5) {
573
+ if ($[9] !== patroller.id || $[10] !== t5) {
484
574
  t6 = /* @__PURE__ */ jsx(Squareling, {
485
575
  variant: patroller.id,
486
576
  status: t5,
487
577
  className: "size-5"
488
578
  });
489
- $[8] = patroller.id;
490
- $[9] = t5;
491
- $[10] = t6;
492
- } else t6 = $[10];
579
+ $[9] = patroller.id;
580
+ $[10] = t5;
581
+ $[11] = t6;
582
+ } else t6 = $[11];
493
583
  let t7;
494
- if ($[11] !== working) {
584
+ if ($[12] !== working) {
495
585
  t7 = working && /* @__PURE__ */ jsx(WorkingArc, {});
496
- $[11] = working;
497
- $[12] = t7;
498
- } else t7 = $[12];
586
+ $[12] = working;
587
+ $[13] = t7;
588
+ } else t7 = $[13];
499
589
  let t8;
500
- if ($[13] !== t6 || $[14] !== t7) {
590
+ if ($[14] !== t6 || $[15] !== t7) {
501
591
  t8 = /* @__PURE__ */ jsxs("span", {
502
592
  className: "bg-muted relative flex size-8 shrink-0 items-center justify-center rounded-full",
503
593
  children: [t6, t7]
504
594
  });
505
- $[13] = t6;
506
- $[14] = t7;
507
- $[15] = t8;
508
- } else t8 = $[15];
595
+ $[14] = t6;
596
+ $[15] = t7;
597
+ $[16] = t8;
598
+ } else t8 = $[16];
509
599
  let t9;
510
- if ($[16] !== patroller.role) {
600
+ if ($[17] !== patroller.role) {
511
601
  t9 = /* @__PURE__ */ jsx("span", {
512
602
  "data-patroller-role": true,
513
603
  className: "truncate text-sm font-medium",
514
604
  children: patroller.role
515
605
  });
516
- $[16] = patroller.role;
517
- $[17] = t9;
518
- } else t9 = $[17];
606
+ $[17] = patroller.role;
607
+ $[18] = t9;
608
+ } else t9 = $[18];
519
609
  const t10 = working ? true : void 0;
520
610
  let t11;
521
- if ($[18] !== subtitle || $[19] !== t10) {
611
+ if ($[19] !== subtitle || $[20] !== t10) {
522
612
  t11 = /* @__PURE__ */ jsx("span", {
523
613
  "data-patroller-subtitle": true,
524
614
  "aria-hidden": t10,
525
615
  className: "text-muted-foreground truncate text-xs",
526
616
  children: subtitle
527
617
  });
528
- $[18] = subtitle;
529
- $[19] = t10;
530
- $[20] = t11;
531
- } else t11 = $[20];
618
+ $[19] = subtitle;
619
+ $[20] = t10;
620
+ $[21] = t11;
621
+ } else t11 = $[21];
532
622
  let t12;
533
- if ($[21] !== t11 || $[22] !== t9) {
623
+ if ($[22] !== t11 || $[23] !== t9) {
534
624
  t12 = /* @__PURE__ */ jsxs("span", {
535
625
  className: "flex min-w-0 flex-col",
536
626
  children: [t9, t11]
537
627
  });
538
- $[21] = t11;
539
- $[22] = t9;
540
- $[23] = t12;
541
- } else t12 = $[23];
628
+ $[22] = t11;
629
+ $[23] = t9;
630
+ $[24] = t12;
631
+ } else t12 = $[24];
542
632
  let t13;
543
- if ($[24] !== t12 || $[25] !== t4 || $[26] !== t8) {
544
- t13 = /* @__PURE__ */ jsxs(PopoverTrigger, {
633
+ if ($[25] !== count) {
634
+ t13 = count > 0 && /* @__PURE__ */ jsx("span", {
635
+ "data-findings-count": true,
636
+ "aria-label": `${count} open ${count === 1 ? "finding" : "findings"}`,
637
+ className: "bg-foreground text-background ml-auto flex h-5 min-w-5 shrink-0 items-center justify-center rounded-full px-1.5 text-xs font-medium tabular-nums",
638
+ children: count
639
+ });
640
+ $[25] = count;
641
+ $[26] = t13;
642
+ } else t13 = $[26];
643
+ let t14;
644
+ if ($[27] !== t12 || $[28] !== t13 || $[29] !== t4 || $[30] !== t8) {
645
+ t14 = /* @__PURE__ */ jsxs(PopoverTrigger, {
545
646
  "aria-describedby": t4,
546
647
  className: "hover:bg-muted/60 data-popup-open:bg-muted/60 focus-visible:ring-ring/50 flex cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1.5 text-left outline-none focus-visible:ring-[3px]",
547
- children: [t8, t12]
648
+ children: [
649
+ t8,
650
+ t12,
651
+ t13
652
+ ]
548
653
  });
549
- $[24] = t12;
550
- $[25] = t4;
551
- $[26] = t8;
552
- $[27] = t13;
553
- } else t13 = $[27];
554
- let t14;
555
- if ($[28] !== patroller.role) {
556
- t14 = /* @__PURE__ */ jsx(PopoverTitle, {
654
+ $[27] = t12;
655
+ $[28] = t13;
656
+ $[29] = t4;
657
+ $[30] = t8;
658
+ $[31] = t14;
659
+ } else t14 = $[31];
660
+ let t15;
661
+ if ($[32] !== patroller.role) {
662
+ t15 = /* @__PURE__ */ jsx(PopoverTitle, {
557
663
  className: "text-sm",
558
664
  children: patroller.role
559
665
  });
560
- $[28] = patroller.role;
561
- $[29] = t14;
562
- } else t14 = $[29];
563
- let t15;
564
- if ($[30] !== inDraft || $[31] !== now || $[32] !== onShow || $[33] !== patroller) {
565
- t15 = /* @__PURE__ */ jsx(PatrollerReports, {
666
+ $[32] = patroller.role;
667
+ $[33] = t15;
668
+ } else t15 = $[33];
669
+ let t16;
670
+ if ($[34] !== onAsk || $[35] !== patroller) {
671
+ t16 = (finding) => onAsk(patroller, finding);
672
+ $[34] = onAsk;
673
+ $[35] = patroller;
674
+ $[36] = t16;
675
+ } else t16 = $[36];
676
+ let t17;
677
+ if ($[37] !== inDraft || $[38] !== now || $[39] !== onApply || $[40] !== onDismiss || $[41] !== onOpenPatrolDraft || $[42] !== onShow || $[43] !== patrolDraft || $[44] !== patroller || $[45] !== t16) {
678
+ t17 = /* @__PURE__ */ jsx(PatrollerDetails, {
566
679
  patroller,
567
680
  now,
568
681
  inDraft,
569
- onShow
682
+ onShow,
683
+ onApply,
684
+ onAsk: t16,
685
+ onDismiss,
686
+ patrolDraft,
687
+ onOpenPatrolDraft
570
688
  });
571
- $[30] = inDraft;
572
- $[31] = now;
573
- $[32] = onShow;
574
- $[33] = patroller;
575
- $[34] = t15;
576
- } else t15 = $[34];
577
- let t16;
578
- if ($[35] !== t14 || $[36] !== t15) {
579
- t16 = /* @__PURE__ */ jsxs(PopoverContent, {
689
+ $[37] = inDraft;
690
+ $[38] = now;
691
+ $[39] = onApply;
692
+ $[40] = onDismiss;
693
+ $[41] = onOpenPatrolDraft;
694
+ $[42] = onShow;
695
+ $[43] = patrolDraft;
696
+ $[44] = patroller;
697
+ $[45] = t16;
698
+ $[46] = t17;
699
+ } else t17 = $[46];
700
+ let t18;
701
+ if ($[47] !== t15 || $[48] !== t17) {
702
+ t18 = /* @__PURE__ */ jsxs(PopoverContent, {
580
703
  side: "left",
581
704
  align: "start",
582
705
  sideOffset: 12,
583
706
  className: "w-80 gap-2 p-3",
584
- children: [t14, t15]
707
+ children: [t15, t17]
585
708
  });
586
- $[35] = t14;
587
- $[36] = t15;
588
- $[37] = t16;
589
- } else t16 = $[37];
590
- let t17;
591
- if ($[38] !== onOpenChange || $[39] !== open || $[40] !== t13 || $[41] !== t16) {
592
- t17 = /* @__PURE__ */ jsxs(Popover, {
709
+ $[47] = t15;
710
+ $[48] = t17;
711
+ $[49] = t18;
712
+ } else t18 = $[49];
713
+ let t19;
714
+ if ($[50] !== onOpenChange || $[51] !== open || $[52] !== t14 || $[53] !== t18) {
715
+ t19 = /* @__PURE__ */ jsxs(Popover, {
593
716
  open,
594
717
  onOpenChange,
595
- children: [t13, t16]
718
+ children: [t14, t18]
596
719
  });
597
- $[38] = onOpenChange;
598
- $[39] = open;
599
- $[40] = t13;
600
- $[41] = t16;
601
- $[42] = t17;
602
- } else t17 = $[42];
603
- let t18;
604
- if ($[43] !== working) {
605
- t18 = working && `Working: ${working.charAt(0).toLowerCase()}${working.slice(1)}`;
606
- $[43] = working;
607
- $[44] = t18;
608
- } else t18 = $[44];
609
- let t19;
610
- if ($[45] !== statusId || $[46] !== t18) {
611
- t19 = /* @__PURE__ */ jsx("span", {
720
+ $[50] = onOpenChange;
721
+ $[51] = open;
722
+ $[52] = t14;
723
+ $[53] = t18;
724
+ $[54] = t19;
725
+ } else t19 = $[54];
726
+ let t20;
727
+ if ($[55] !== working) {
728
+ t20 = working && `Working: ${working.charAt(0).toLowerCase()}${working.slice(1)}`;
729
+ $[55] = working;
730
+ $[56] = t20;
731
+ } else t20 = $[56];
732
+ let t21;
733
+ if ($[57] !== statusId || $[58] !== t20) {
734
+ t21 = /* @__PURE__ */ jsx("span", {
612
735
  id: statusId,
613
736
  "data-working-status": true,
614
737
  role: "status",
615
738
  className: "sr-only",
616
- children: t18
739
+ children: t20
617
740
  });
618
- $[45] = statusId;
619
- $[46] = t18;
620
- $[47] = t19;
621
- } else t19 = $[47];
622
- let t20;
623
- if ($[48] !== patroller.id || $[49] !== t17 || $[50] !== t19 || $[51] !== t3) {
624
- t20 = /* @__PURE__ */ jsxs("li", {
741
+ $[57] = statusId;
742
+ $[58] = t20;
743
+ $[59] = t21;
744
+ } else t21 = $[59];
745
+ let t22;
746
+ if ($[60] !== patroller.id || $[61] !== t19 || $[62] !== t21 || $[63] !== t3) {
747
+ t22 = /* @__PURE__ */ jsxs("li", {
625
748
  "data-patroller": patroller.id,
626
749
  "data-open": t3,
627
750
  className: "flex flex-col",
628
- children: [t17, t19]
751
+ children: [t19, t21]
629
752
  });
630
- $[48] = patroller.id;
631
- $[49] = t17;
632
- $[50] = t19;
633
- $[51] = t3;
634
- $[52] = t20;
635
- } else t20 = $[52];
636
- return t20;
753
+ $[60] = patroller.id;
754
+ $[61] = t19;
755
+ $[62] = t21;
756
+ $[63] = t3;
757
+ $[64] = t22;
758
+ } else t22 = $[64];
759
+ return t22;
760
+ }
761
+ /**
762
+ * What a patroller's popover shows: its open findings with their actions, then its reports, then
763
+ * the history of its dismissals.
764
+ */
765
+ function PatrollerDetails(t0) {
766
+ const $ = c(23);
767
+ const { patroller, now, inDraft, onShow, onApply, onAsk, onDismiss, patrolDraft, onOpenPatrolDraft } = t0;
768
+ let t1;
769
+ if ($[0] !== inDraft || $[1] !== onApply || $[2] !== onAsk || $[3] !== onDismiss || $[4] !== onOpenPatrolDraft || $[5] !== onShow || $[6] !== patrolDraft || $[7] !== patroller.findings || $[8] !== patroller.id) {
770
+ t1 = patroller.findings.length > 0 && /* @__PURE__ */ jsx("ul", {
771
+ "data-findings": patroller.id,
772
+ className: "flex flex-col gap-2 text-xs",
773
+ children: patroller.findings.map((finding) => /* @__PURE__ */ jsxs("li", {
774
+ "data-finding": true,
775
+ className: "flex flex-col gap-1",
776
+ children: [/* @__PURE__ */ jsxs("span", {
777
+ className: "flex items-baseline gap-2",
778
+ children: [/* @__PURE__ */ jsx("span", {
779
+ "data-finding-sentence": true,
780
+ className: "min-w-0 flex-1",
781
+ children: findingSentence(finding)
782
+ }), inDraft && finding.live && /* @__PURE__ */ jsx(Badge, {
783
+ variant: "outline",
784
+ size: "sm",
785
+ children: "Live"
786
+ })]
787
+ }), /* @__PURE__ */ jsxs("span", {
788
+ className: "flex flex-wrap gap-1",
789
+ children: [
790
+ finding.place && /* @__PURE__ */ jsx(Button, {
791
+ variant: "outline",
792
+ size: "xs",
793
+ onClick: () => onShow(finding),
794
+ children: "Show"
795
+ }),
796
+ finding.fix && !finding.live && /* @__PURE__ */ jsx(Button, {
797
+ variant: "outline",
798
+ size: "xs",
799
+ onClick: () => onApply(finding),
800
+ children: fixLabel(finding.fix)
801
+ }),
802
+ inDraft && !finding.live && /* @__PURE__ */ jsx(Button, {
803
+ variant: "outline",
804
+ size: "xs",
805
+ onClick: () => onAsk(finding),
806
+ children: "Ask the agent"
807
+ }),
808
+ !inDraft && patrolDraft && /* @__PURE__ */ jsx(Button, {
809
+ variant: "outline",
810
+ size: "xs",
811
+ onClick: () => onOpenPatrolDraft(patrolDraft),
812
+ children: "Open the Patrol Draft"
813
+ }),
814
+ /* @__PURE__ */ jsx(Button, {
815
+ variant: "ghost",
816
+ size: "xs",
817
+ onClick: () => onDismiss(finding),
818
+ children: dismissLabel(finding.about)
819
+ })
820
+ ]
821
+ })]
822
+ }, finding.id))
823
+ });
824
+ $[0] = inDraft;
825
+ $[1] = onApply;
826
+ $[2] = onAsk;
827
+ $[3] = onDismiss;
828
+ $[4] = onOpenPatrolDraft;
829
+ $[5] = onShow;
830
+ $[6] = patrolDraft;
831
+ $[7] = patroller.findings;
832
+ $[8] = patroller.id;
833
+ $[9] = t1;
834
+ } else t1 = $[9];
835
+ let t2;
836
+ if ($[10] !== inDraft || $[11] !== now || $[12] !== onShow || $[13] !== patroller) {
837
+ t2 = /* @__PURE__ */ jsx(PatrollerReports, {
838
+ patroller,
839
+ now,
840
+ inDraft,
841
+ onShow
842
+ });
843
+ $[10] = inDraft;
844
+ $[11] = now;
845
+ $[12] = onShow;
846
+ $[13] = patroller;
847
+ $[14] = t2;
848
+ } else t2 = $[14];
849
+ let t3;
850
+ if ($[15] !== now || $[16] !== patroller.dismissals || $[17] !== patroller.id) {
851
+ t3 = patroller.dismissals.length > 0 && /* @__PURE__ */ jsx("ul", {
852
+ "data-dismissals": patroller.id,
853
+ "aria-label": "Dismissed",
854
+ className: "text-muted-foreground flex flex-col gap-1 border-t pt-2 text-xs",
855
+ children: patroller.dismissals.map((dismissal) => /* @__PURE__ */ jsxs("li", {
856
+ "data-dismissal": true,
857
+ className: "flex items-baseline gap-2",
858
+ children: [/* @__PURE__ */ jsx("span", {
859
+ className: "min-w-0 flex-1",
860
+ children: `${dismissedSentence(dismissal.about)}: dismissed by ${dismissal.by.name}`
861
+ }), /* @__PURE__ */ jsx("time", {
862
+ dateTime: new Date(dismissal.at).toISOString(),
863
+ className: "shrink-0",
864
+ children: shortTimeAgo(dismissal.at, now)
865
+ })]
866
+ }, dismissal.id))
867
+ });
868
+ $[15] = now;
869
+ $[16] = patroller.dismissals;
870
+ $[17] = patroller.id;
871
+ $[18] = t3;
872
+ } else t3 = $[18];
873
+ let t4;
874
+ if ($[19] !== t1 || $[20] !== t2 || $[21] !== t3) {
875
+ t4 = /* @__PURE__ */ jsxs(Fragment, { children: [
876
+ t1,
877
+ t2,
878
+ t3
879
+ ] });
880
+ $[19] = t1;
881
+ $[20] = t2;
882
+ $[21] = t3;
883
+ $[22] = t4;
884
+ } else t4 = $[22];
885
+ return t4;
637
886
  }
638
887
  /**
639
888
  * A patroller's reports, latest first, each with a Live tag when a draft is viewed and how long
@@ -643,6 +892,7 @@ function PatrollerReports(t0) {
643
892
  const $ = c(16);
644
893
  const { patroller, now, inDraft, onShow } = t0;
645
894
  if (patroller.reports.length === 0 && patroller.more.length === 0) {
895
+ if (patroller.findings.length > 0 || patroller.dismissals.length > 0) return null;
646
896
  let t1;
647
897
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
648
898
  t1 = /* @__PURE__ */ jsx("p", {
@@ -753,7 +1003,7 @@ function ReportSentence(t0) {
753
1003
  const t3 = `${sentence}: ${leads}`;
754
1004
  let t4;
755
1005
  if ($[8] !== onShow || $[9] !== report) {
756
- t4 = () => onShow(report);
1006
+ t4 = () => onShow(shownOf(report));
757
1007
  $[8] = onShow;
758
1008
  $[9] = report;
759
1009
  $[10] = t4;
@@ -776,4 +1026,4 @@ function ReportSentence(t0) {
776
1026
  }
777
1027
 
778
1028
  //#endregion
779
- export { Patrol, PatrolRoster, PatrollerReports, inHeldOrder };
1029
+ export { Patrol, PatrolRoster, PatrollerDetails, PatrollerReports, inHeldOrder };