camox 0.58.1 → 0.60.2

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 (102) hide show
  1. package/dist/core/createBlock.js +1 -1
  2. package/dist/core/editing/createEditableBlock.js +2 -2
  3. package/dist/core/lib/recordScope.js +1 -1
  4. package/dist/features/canvas/CamoxCanvas.js +2 -2
  5. package/dist/features/canvas/CanvasOverlays.js +1 -1
  6. package/dist/features/canvas/sidebar/LayoutPageSeo.js +1 -1
  7. package/dist/features/canvas/sidebar/PageInspector.js +1 -1
  8. package/dist/features/content/CamoxContent.js +1 -1
  9. package/dist/features/content/components/MissingFromLocale.js +1 -1
  10. package/dist/features/page/CuratedPageContent.js +1 -1
  11. package/dist/features/preview/CamoxPreview.js +3 -3
  12. package/dist/features/preview/components/AddBlockSheet.js +1 -1
  13. package/dist/features/preview/components/AssetLightbox.js +1 -1
  14. package/dist/features/preview/components/BlockActionsPopover.js +1 -1
  15. package/dist/features/preview/components/CreatePageModal.js +2 -2
  16. package/dist/features/preview/components/FieldOverlayStyles.js +1 -1
  17. package/dist/features/preview/components/MobilePreviewDrawer.js +1 -1
  18. package/dist/features/preview/components/Overlays.js +1 -1
  19. package/dist/features/preview/components/PageInfo.js +1 -1
  20. package/dist/features/preview/components/PagePicker.js +1 -1
  21. package/dist/features/preview/components/PageTree.js +1 -1
  22. package/dist/features/preview/components/PreviewPanel.js +1 -1
  23. package/dist/features/preview/components/PreviewToolbar.js +1 -1
  24. package/dist/features/preview/components/SelectionEditor.js +2 -2
  25. package/dist/features/preview/components/StudioEditingFallback.js +1 -1
  26. package/dist/features/provider/AuthenticatedCamoxProvider.js +1 -1
  27. package/dist/features/provider/CamoxProvider.js +1 -1
  28. package/dist/features/provider/CoreCamoxProvider.js +3 -3
  29. package/dist/features/provider/components/CommandPalette.js +1 -1
  30. package/dist/features/renderer/RendererApp.js +187 -103
  31. package/dist/features/renderer/rendererHost.js +3 -7
  32. package/dist/features/routes/pageRuntime.d.ts +2 -5
  33. package/dist/features/routes/pageRuntime.js +1 -2
  34. package/dist/features/runtime/RuntimeChrome.js +1 -1
  35. package/dist/features/runtime/loopbackFetch.d.ts +8 -0
  36. package/dist/features/runtime/navigationTarget.js +1 -2
  37. package/dist/features/runtime/pageApp.js +1 -1
  38. package/dist/features/runtime/publicCache.d.ts +21 -0
  39. package/dist/features/runtime/publishingDraft.d.ts +4 -0
  40. package/dist/features/runtime/rendererClient.js +1 -1
  41. package/dist/features/runtime/runtime.d.ts +0 -5
  42. package/dist/features/runtime/runtime.js +80 -33
  43. package/dist/features/runtime/worker.js +4 -7
  44. package/dist/features/runtime/workerRequest.d.ts +8 -0
  45. package/dist/features/runtime/workerRuntime.d.ts +5 -0
  46. package/dist/features/runtime/workerRuntime.js +6 -0
  47. package/dist/features/sdkBundle/buildSdkBundle.d.ts +40 -0
  48. package/dist/features/sdkBundle/buildSdkBundle.js +323 -0
  49. package/dist/features/sdkBundle/localSdkBundle.d.ts +44 -0
  50. package/dist/features/sdkBundle/localSdkBundle.js +162 -0
  51. package/dist/features/sdkBundle/sdkBundle.d.ts +3 -0
  52. package/dist/features/sdkBundle/sdkBundle.js +4 -0
  53. package/dist/features/sdkBundle/sdkBundleName.d.ts +59 -0
  54. package/dist/features/sdkBundle/sdkBundleName.js +164 -0
  55. package/dist/features/sdkBundle/specifiers.d.ts +34 -0
  56. package/dist/features/sdkBundle/specifiers.js +146 -0
  57. package/dist/features/settings/FaviconSettings.js +1 -1
  58. package/dist/features/settings/SocialProfilesSettings.js +284 -151
  59. package/dist/features/studio/CamoxStudio.js +1 -1
  60. package/dist/features/studio/FollowAgentProvider.js +72 -13
  61. package/dist/features/studio/components/ChatWidget.js +86 -44
  62. package/dist/features/studio/components/DraftsControl.js +232 -201
  63. package/dist/features/studio/components/LocalePicker.js +2 -2
  64. package/dist/features/studio/components/Navbar.js +3 -3
  65. package/dist/features/studio/components/Patrol.js +312 -209
  66. package/dist/features/studio/components/ProjectMenu.js +2 -2
  67. package/dist/features/studio/components/ReviewDraftSheet.js +9 -15
  68. package/dist/features/studio/components/Squareling.js +164 -66
  69. package/dist/features/studio/components/ThreadComposer.js +139 -69
  70. package/dist/features/studio/components/ThreadMessages.js +216 -64
  71. package/dist/features/studio/components/UserButton.js +2 -2
  72. package/dist/features/studio/draftLabel.js +1 -2
  73. package/dist/features/studio/draftNotice.js +0 -1
  74. package/dist/features/studio/editorWhereContext.js +11 -0
  75. package/dist/features/studio/showInCanvas.js +1 -1
  76. package/dist/features/studio/useEditorSelection.js +135 -0
  77. package/dist/features/vite/definitionsSync.js +14 -60
  78. package/dist/features/vite/devSignIn.js +1 -1
  79. package/dist/features/vite/hostedChecks.js +1 -1
  80. package/dist/features/vite/runtimeDev.js +2 -2
  81. package/dist/features/vite/sdkBundleBuild.js +74 -0
  82. package/dist/features/vite/staticAssetHeaders.js +7 -4
  83. package/dist/features/vite/vite.d.ts +8 -7
  84. package/dist/features/vite/vite.js +67 -28
  85. package/dist/lib/api-client-server.js +25 -8
  86. package/dist/lib/api-client.js +2 -6
  87. package/dist/lib/auth.js +25 -59
  88. package/dist/lib/draft-scope.js +5 -25
  89. package/dist/lib/preview-handoff.js +1 -1
  90. package/dist/lib/server-auth-cookie.js +23 -11
  91. package/dist/lib/stored-auth-cookies.js +76 -0
  92. package/dist/lib/studio-reads.js +1 -1
  93. package/dist/lib/use-thread.js +40 -40
  94. package/dist/package.js +1 -1
  95. package/dist/studio.css +1 -1
  96. package/package.json +17 -4
  97. package/skills/camox/references/block-definitions.md +1 -1
  98. package/dist/features/vite/publishSeededContent.js +0 -30
  99. package/skills/camox-cli/SKILL.md +0 -15
  100. package/skills/camox-cli/references/cli-common.md +0 -58
  101. package/skills/camox-cli/references/cli-content.md +0 -181
  102. package/skills/camox-cli/references/cli-publishing.md +0 -26
@@ -1,8 +1,8 @@
1
- import { AuthContext } from "../../../lib/auth.js";
2
1
  import { localizedPath } from "../../../lib/locale-path.js";
3
2
  import { useCurrentDraftId } from "../../../lib/draft-scope.js";
4
3
  import { useViewLocale } from "../../../lib/view-locale-context.js";
5
4
  import { useNavigate } from "../../navigation/navigation.js";
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
8
  import { AssetLightbox } from "../../preview/components/AssetLightbox.js";
@@ -16,6 +16,7 @@ import { singleLocaleSentence, workingSentence } from "../workingSentence.js";
16
16
  import { c } from "react/compiler-runtime";
17
17
  import * as React from "react";
18
18
  import { jsx, jsxs } from "react/jsx-runtime";
19
+ import { Popover, PopoverContent, PopoverTitle, PopoverTrigger } from "@camox/ui/popover";
19
20
  import { Badge } from "@camox/ui/badge";
20
21
  import { reportLocale } from "@camox/api-contract/patrol";
21
22
 
@@ -23,7 +24,7 @@ import { reportLocale } from "@camox/api-contract/patrol";
23
24
  /**
24
25
  * The Agent Sidebar's Patrol, over the Chat widget: every patroller of the project, and what each
25
26
  * did without being asked in the draft viewed, or on Live (ADR 0024). It fetches the Patrol of the
26
- * scope viewed, and holds which patrollers are expanded.
27
+ * scope viewed, and holds which patroller's reports are open.
27
28
  */
28
29
  function Patrol(t0) {
29
30
  const $ = c(14);
@@ -94,7 +95,7 @@ function Patrol(t0) {
94
95
  return t7;
95
96
  }
96
97
  function ProjectPatrol(t0) {
97
- const $ = c(28);
98
+ const $ = c(36);
98
99
  const { projectId, inDraft } = t0;
99
100
  let t1;
100
101
  if ($[0] !== projectId) {
@@ -110,110 +111,133 @@ function ProjectPatrol(t0) {
110
111
  $[3] = t2;
111
112
  } else t2 = $[3];
112
113
  const { data: locales } = useReadQuery(t2);
113
- let t3;
114
- if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
115
- t3 = /* @__PURE__ */ new Set();
116
- $[4] = t3;
117
- } else t3 = $[4];
118
- const [expanded, setExpanded] = React.useState(t3);
119
- let t4;
120
- if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
121
- t4 = (id) => setExpanded((previous) => {
122
- const next = new Set(previous);
123
- if (!next.delete(id)) next.add(id);
124
- return next;
125
- });
126
- $[5] = t4;
127
- } else t4 = $[5];
128
- const toggle = t4;
114
+ const [open, setOpen] = React.useState(null);
129
115
  const now = useNow(3e4);
130
116
  const [heldOrder, setHeldOrder] = React.useState(null);
131
- let t5;
132
- if ($[6] !== heldOrder || $[7] !== view) {
133
- t5 = view && inHeldOrder(view, heldOrder);
134
- $[6] = heldOrder;
135
- $[7] = view;
136
- $[8] = t5;
137
- } else t5 = $[8];
138
- const shown = t5;
139
- let t6;
140
- if ($[9] !== shown?.patrollers) {
141
- t6 = shown?.patrollers.map(_temp).join(" ");
142
- $[9] = shown?.patrollers;
143
- $[10] = t6;
144
- } else t6 = $[10];
145
- const roster = useMovingRows(t6);
117
+ const pointerIn = React.useRef(false);
118
+ let t3;
119
+ if ($[4] !== heldOrder || $[5] !== view) {
120
+ t3 = view && inHeldOrder(view, heldOrder);
121
+ $[4] = heldOrder;
122
+ $[5] = view;
123
+ $[6] = t3;
124
+ } else t3 = $[6];
125
+ const shown = t3;
126
+ let t4;
127
+ if ($[7] !== shown?.patrollers) {
128
+ t4 = shown?.patrollers.map(_temp).join(" ");
129
+ $[7] = shown?.patrollers;
130
+ $[8] = t4;
131
+ } else t4 = $[8];
132
+ const roster = useMovingRows(t4);
146
133
  const [openFileId, setOpenFileId] = React.useState(null);
147
- const show = useShowReport(inDraft, setOpenFileId);
134
+ const showReport = useShowReport(inDraft, setOpenFileId);
148
135
  if (!shown) return null;
136
+ 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;
143
+ let t6;
144
+ if ($[11] !== hold) {
145
+ t6 = (id_1) => {
146
+ setOpen(id_1);
147
+ if (id_1) hold();
148
+ else if (!pointerIn.current) setHeldOrder(null);
149
+ };
150
+ $[11] = hold;
151
+ $[12] = t6;
152
+ } else t6 = $[12];
153
+ const openReports = t6;
149
154
  let t7;
150
- if ($[11] !== shown.patrollers) {
151
- t7 = () => setHeldOrder(shown.patrollers.map(_temp2));
152
- $[11] = shown.patrollers;
153
- $[12] = t7;
154
- } else t7 = $[12];
155
+ if ($[13] !== hold) {
156
+ t7 = () => {
157
+ pointerIn.current = true;
158
+ hold();
159
+ };
160
+ $[13] = hold;
161
+ $[14] = t7;
162
+ } else t7 = $[14];
155
163
  let t8;
156
- if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
157
- t8 = () => setHeldOrder(null);
158
- $[13] = t8;
159
- } else t8 = $[13];
164
+ if ($[15] !== open) {
165
+ t8 = () => {
166
+ pointerIn.current = false;
167
+ if (!open) setHeldOrder(null);
168
+ };
169
+ $[15] = open;
170
+ $[16] = t8;
171
+ } else t8 = $[16];
160
172
  const t9 = locales?.length === 1;
161
173
  let t10;
162
- if ($[14] !== expanded || $[15] !== inDraft || $[16] !== now || $[17] !== show || $[18] !== shown || $[19] !== t9) {
163
- t10 = /* @__PURE__ */ jsx(PatrolRoster, {
174
+ if ($[17] !== openReports || $[18] !== showReport) {
175
+ t10 = (report) => {
176
+ openReports(null);
177
+ showReport(report);
178
+ };
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, {
164
186
  view: shown,
165
187
  now,
166
188
  inDraft,
167
189
  singleLocale: t9,
168
- expanded,
169
- onToggle: toggle,
170
- onShow: show
190
+ open,
191
+ onOpenChange: openReports,
192
+ onShow: t10
171
193
  });
172
- $[14] = expanded;
173
- $[15] = inDraft;
174
- $[16] = now;
175
- $[17] = show;
176
- $[18] = shown;
177
- $[19] = t9;
178
- $[20] = t10;
179
- } else t10 = $[20];
180
- let t11;
181
- if ($[21] !== openFileId) {
182
- t11 = openFileId && /* @__PURE__ */ jsx(AssetLightbox, {
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, {
183
206
  open: true,
184
- onOpenChange: (open) => {
185
- if (!open) setOpenFileId(null);
207
+ onOpenChange: (open_0) => {
208
+ if (!open_0) setOpenFileId(null);
186
209
  },
187
210
  fileId: openFileId
188
211
  });
189
- $[21] = openFileId;
190
- $[22] = t11;
191
- } else t11 = $[22];
192
- let t12;
193
- if ($[23] !== roster || $[24] !== t10 || $[25] !== t11 || $[26] !== t7) {
194
- t12 = /* @__PURE__ */ jsxs("div", {
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", {
195
218
  ref: roster,
196
219
  className: "relative",
197
220
  onPointerEnter: t7,
198
221
  onPointerLeave: t8,
199
- children: [t10, t11]
222
+ children: [t11, t12]
200
223
  });
201
- $[23] = roster;
202
- $[24] = t10;
203
- $[25] = t11;
204
- $[26] = t7;
205
- $[27] = t12;
206
- } else t12 = $[27];
207
- return t12;
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;
208
232
  }
209
233
  function _temp2(t0) {
210
- const { id: id_1 } = t0;
211
- return id_1;
212
- }
213
- function _temp(t0) {
214
234
  const { id: id_0 } = t0;
215
235
  return id_0;
216
236
  }
237
+ function _temp(t0) {
238
+ const { id } = t0;
239
+ return id;
240
+ }
217
241
  /**
218
242
  * Shows a report's subject where it is, in the report's locale, and on Live for a Live report seen
219
243
  * from a draft: a page, block or item selected on the Canvas, a record in its collection, or a
@@ -353,39 +377,39 @@ function _temp4() {
353
377
  }
354
378
  /**
355
379
  * A `PatrolView`, in the order it gives: each patroller's avatar, role, and when it last worked,
356
- * and the reports of the expanded ones. Live's reports carry a tag when a draft is viewed. In a
380
+ * opening its reports in a popover to the left. Live's reports carry a tag when a draft is viewed. In a
357
381
  * project with a single locale, the Translator invites the editor to add a language instead.
358
382
  */
359
383
  function PatrolRoster(t0) {
360
384
  const $ = c(17);
361
- const { view, now, inDraft, singleLocale, expanded, onToggle, onShow } = t0;
385
+ const { view, now, inDraft, singleLocale, open, onOpenChange, onShow } = t0;
362
386
  let t1;
363
- if ($[0] !== expanded || $[1] !== inDraft || $[2] !== now || $[3] !== onShow || $[4] !== onToggle || $[5] !== singleLocale || $[6] !== view.patrollers) {
387
+ if ($[0] !== inDraft || $[1] !== now || $[2] !== onOpenChange || $[3] !== onShow || $[4] !== open || $[5] !== singleLocale || $[6] !== view.patrollers) {
364
388
  let t2;
365
- if ($[8] !== expanded || $[9] !== inDraft || $[10] !== now || $[11] !== onShow || $[12] !== onToggle || $[13] !== singleLocale) {
389
+ if ($[8] !== inDraft || $[9] !== now || $[10] !== onOpenChange || $[11] !== onShow || $[12] !== open || $[13] !== singleLocale) {
366
390
  t2 = (patroller) => /* @__PURE__ */ jsx(PatrollerRow, {
367
391
  patroller,
368
392
  now,
369
393
  inDraft,
370
394
  idle: singleLocale ? singleLocaleSentence(patroller.id) : void 0,
371
- expanded: expanded.has(patroller.id),
372
- onToggle: () => onToggle(patroller.id),
395
+ open: open === patroller.id,
396
+ onOpenChange: (next) => onOpenChange(next ? patroller.id : null),
373
397
  onShow
374
398
  }, patroller.id);
375
- $[8] = expanded;
376
- $[9] = inDraft;
377
- $[10] = now;
399
+ $[8] = inDraft;
400
+ $[9] = now;
401
+ $[10] = onOpenChange;
378
402
  $[11] = onShow;
379
- $[12] = onToggle;
403
+ $[12] = open;
380
404
  $[13] = singleLocale;
381
405
  $[14] = t2;
382
406
  } else t2 = $[14];
383
407
  t1 = view.patrollers.map(t2);
384
- $[0] = expanded;
385
- $[1] = inDraft;
386
- $[2] = now;
408
+ $[0] = inDraft;
409
+ $[1] = now;
410
+ $[2] = onOpenChange;
387
411
  $[3] = onShow;
388
- $[4] = onToggle;
412
+ $[4] = open;
389
413
  $[5] = singleLocale;
390
414
  $[6] = view.patrollers;
391
415
  $[7] = t1;
@@ -393,7 +417,7 @@ function PatrolRoster(t0) {
393
417
  let t2;
394
418
  if ($[15] !== t1) {
395
419
  t2 = /* @__PURE__ */ jsx("ul", {
396
- className: "flex flex-col py-1",
420
+ className: "flex flex-col gap-px p-1",
397
421
  children: t1
398
422
  });
399
423
  $[15] = t1;
@@ -431,9 +455,8 @@ function WorkingArc() {
431
455
  return t0;
432
456
  }
433
457
  function PatrollerRow(t0) {
434
- const $ = c(49);
435
- const { patroller, now, inDraft, idle, expanded, onToggle, onShow } = t0;
436
- const reportsId = React.useId();
458
+ const $ = c(53);
459
+ const { patroller, now, inDraft, idle, open, onOpenChange, onShow } = t0;
437
460
  const statusId = React.useId();
438
461
  let t1;
439
462
  if ($[0] !== patroller.id || $[1] !== patroller.working) {
@@ -453,114 +476,191 @@ function PatrollerRow(t0) {
453
476
  $[7] = t2;
454
477
  } else t2 = $[7];
455
478
  const subtitle = t2;
456
- const t3 = working ? statusId : void 0;
457
- const t4 = working ? "working" : "idle";
458
- let t5;
459
- if ($[8] !== patroller.id || $[9] !== t4) {
460
- t5 = /* @__PURE__ */ jsx(Squareling, {
479
+ const t3 = open || void 0;
480
+ const t4 = working ? statusId : void 0;
481
+ const t5 = working ? "working" : "idle";
482
+ let t6;
483
+ if ($[8] !== patroller.id || $[9] !== t5) {
484
+ t6 = /* @__PURE__ */ jsx(Squareling, {
461
485
  variant: patroller.id,
462
- status: t4,
486
+ status: t5,
463
487
  className: "size-5"
464
488
  });
465
489
  $[8] = patroller.id;
466
- $[9] = t4;
467
- $[10] = t5;
468
- } else t5 = $[10];
469
- let t6;
490
+ $[9] = t5;
491
+ $[10] = t6;
492
+ } else t6 = $[10];
493
+ let t7;
470
494
  if ($[11] !== working) {
471
- t6 = working && /* @__PURE__ */ jsx(WorkingArc, {});
495
+ t7 = working && /* @__PURE__ */ jsx(WorkingArc, {});
472
496
  $[11] = working;
473
- $[12] = t6;
474
- } else t6 = $[12];
475
- let t7;
476
- if ($[13] !== t5 || $[14] !== t6) {
477
- t7 = /* @__PURE__ */ jsxs("span", {
497
+ $[12] = t7;
498
+ } else t7 = $[12];
499
+ let t8;
500
+ if ($[13] !== t6 || $[14] !== t7) {
501
+ t8 = /* @__PURE__ */ jsxs("span", {
478
502
  className: "bg-muted relative flex size-8 shrink-0 items-center justify-center rounded-full",
479
- children: [t5, t6]
503
+ children: [t6, t7]
480
504
  });
481
- $[13] = t5;
482
- $[14] = t6;
483
- $[15] = t7;
484
- } else t7 = $[15];
485
- let t8;
505
+ $[13] = t6;
506
+ $[14] = t7;
507
+ $[15] = t8;
508
+ } else t8 = $[15];
509
+ let t9;
486
510
  if ($[16] !== patroller.role) {
487
- t8 = /* @__PURE__ */ jsx("span", {
511
+ t9 = /* @__PURE__ */ jsx("span", {
488
512
  "data-patroller-role": true,
489
513
  className: "truncate text-sm font-medium",
490
514
  children: patroller.role
491
515
  });
492
516
  $[16] = patroller.role;
493
- $[17] = t8;
494
- } else t8 = $[17];
495
- const t9 = working ? true : void 0;
496
- let t10;
497
- if ($[18] !== subtitle || $[19] !== t9) {
498
- t10 = /* @__PURE__ */ jsx("span", {
517
+ $[17] = t9;
518
+ } else t9 = $[17];
519
+ const t10 = working ? true : void 0;
520
+ let t11;
521
+ if ($[18] !== subtitle || $[19] !== t10) {
522
+ t11 = /* @__PURE__ */ jsx("span", {
499
523
  "data-patroller-subtitle": true,
500
- "aria-hidden": t9,
524
+ "aria-hidden": t10,
501
525
  className: "text-muted-foreground truncate text-xs",
502
526
  children: subtitle
503
527
  });
504
528
  $[18] = subtitle;
505
- $[19] = t9;
506
- $[20] = t10;
507
- } else t10 = $[20];
508
- let t11;
509
- if ($[21] !== t10 || $[22] !== t8) {
510
- t11 = /* @__PURE__ */ jsxs("span", {
511
- className: "flex min-w-0 flex-col",
512
- children: [t8, t10]
513
- });
514
- $[21] = t10;
515
- $[22] = t8;
516
- $[23] = t11;
517
- } else t11 = $[23];
529
+ $[19] = t10;
530
+ $[20] = t11;
531
+ } else t11 = $[20];
518
532
  let t12;
519
- if ($[24] !== expanded || $[25] !== onToggle || $[26] !== reportsId || $[27] !== t11 || $[28] !== t3 || $[29] !== t7) {
520
- t12 = /* @__PURE__ */ jsxs("button", {
521
- type: "button",
522
- "aria-expanded": expanded,
523
- "aria-controls": reportsId,
524
- "aria-describedby": t3,
525
- onClick: onToggle,
526
- className: "hover:bg-muted/60 focus-visible:ring-ring/50 flex items-center gap-2.5 px-3 py-1.5 text-left outline-none focus-visible:ring-[3px]",
527
- children: [t7, t11]
533
+ if ($[21] !== t11 || $[22] !== t9) {
534
+ t12 = /* @__PURE__ */ jsxs("span", {
535
+ className: "flex min-w-0 flex-col",
536
+ children: [t9, t11]
528
537
  });
529
- $[24] = expanded;
530
- $[25] = onToggle;
531
- $[26] = reportsId;
532
- $[27] = t11;
533
- $[28] = t3;
534
- $[29] = t7;
535
- $[30] = t12;
536
- } else t12 = $[30];
538
+ $[21] = t11;
539
+ $[22] = t9;
540
+ $[23] = t12;
541
+ } else t12 = $[23];
537
542
  let t13;
538
- if ($[31] !== working) {
539
- t13 = working && `Working: ${working.charAt(0).toLowerCase()}${working.slice(1)}`;
540
- $[31] = working;
541
- $[32] = t13;
542
- } else t13 = $[32];
543
+ if ($[24] !== t12 || $[25] !== t4 || $[26] !== t8) {
544
+ t13 = /* @__PURE__ */ jsxs(PopoverTrigger, {
545
+ "aria-describedby": t4,
546
+ 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]
548
+ });
549
+ $[24] = t12;
550
+ $[25] = t4;
551
+ $[26] = t8;
552
+ $[27] = t13;
553
+ } else t13 = $[27];
543
554
  let t14;
544
- if ($[33] !== statusId || $[34] !== t13) {
545
- t14 = /* @__PURE__ */ jsx("span", {
555
+ if ($[28] !== patroller.role) {
556
+ t14 = /* @__PURE__ */ jsx(PopoverTitle, {
557
+ className: "text-sm",
558
+ children: patroller.role
559
+ });
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, {
566
+ patroller,
567
+ now,
568
+ inDraft,
569
+ onShow
570
+ });
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, {
580
+ side: "left",
581
+ align: "start",
582
+ sideOffset: 12,
583
+ className: "w-80 gap-2 p-3",
584
+ children: [t14, t15]
585
+ });
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, {
593
+ open,
594
+ onOpenChange,
595
+ children: [t13, t16]
596
+ });
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", {
546
612
  id: statusId,
547
613
  "data-working-status": true,
548
614
  role: "status",
549
615
  className: "sr-only",
550
- children: t13
616
+ children: t18
551
617
  });
552
- $[33] = statusId;
553
- $[34] = t13;
554
- $[35] = t14;
555
- } else t14 = $[35];
556
- let t15;
557
- if ($[36] !== expanded || $[37] !== inDraft || $[38] !== now || $[39] !== onShow || $[40] !== patroller.more || $[41] !== patroller.reports || $[42] !== reportsId) {
558
- t15 = expanded && /* @__PURE__ */ jsxs("ul", {
559
- id: reportsId,
560
- className: "flex flex-col gap-1 pt-0.5 pr-3 pb-2 pl-[3.375rem] text-xs",
561
- children: [patroller.reports.map((report) => /* @__PURE__ */ jsxs("li", {
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", {
625
+ "data-patroller": patroller.id,
626
+ "data-open": t3,
627
+ className: "flex flex-col",
628
+ children: [t17, t19]
629
+ });
630
+ $[48] = patroller.id;
631
+ $[49] = t17;
632
+ $[50] = t19;
633
+ $[51] = t3;
634
+ $[52] = t20;
635
+ } else t20 = $[52];
636
+ return t20;
637
+ }
638
+ /**
639
+ * A patroller's reports, latest first, each with a Live tag when a draft is viewed and how long
640
+ * ago, then how many more there are, by locale.
641
+ */
642
+ function PatrollerReports(t0) {
643
+ const $ = c(16);
644
+ const { patroller, now, inDraft, onShow } = t0;
645
+ if (patroller.reports.length === 0 && patroller.more.length === 0) {
646
+ let t1;
647
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
648
+ t1 = /* @__PURE__ */ jsx("p", {
649
+ className: "text-muted-foreground text-xs",
650
+ children: "Nothing yet."
651
+ });
652
+ $[0] = t1;
653
+ } else t1 = $[0];
654
+ return t1;
655
+ }
656
+ const t1 = patroller.id;
657
+ let t2;
658
+ if ($[1] !== inDraft || $[2] !== now || $[3] !== onShow || $[4] !== patroller.reports) {
659
+ let t3;
660
+ if ($[6] !== inDraft || $[7] !== now || $[8] !== onShow) {
661
+ t3 = (report) => /* @__PURE__ */ jsxs("li", {
562
662
  "data-report": true,
563
- className: "has-focus-visible:ring-ring/50 has-[button:hover]:bg-muted/60 relative -mx-1.5 flex items-baseline gap-2 rounded-sm px-1.5 has-focus-visible:ring-[3px]",
663
+ className: "has-focus-visible:ring-ring/50 has-[button:hover]:bg-muted/60 relative -mx-1.5 flex items-baseline gap-2 rounded-sm px-1.5 py-0.5 has-focus-visible:ring-[3px]",
564
664
  children: [
565
665
  /* @__PURE__ */ jsx(ReportSentence, {
566
666
  report,
@@ -578,39 +678,42 @@ function PatrollerRow(t0) {
578
678
  children: shortTimeAgo(report.at, now)
579
679
  })
580
680
  ]
581
- }, report.id)), patroller.more.length > 0 && /* @__PURE__ */ jsx("li", {
582
- "data-more": true,
583
- className: "text-muted-foreground",
584
- children: moreSentence(patroller.more)
585
- })]
681
+ }, report.id);
682
+ $[6] = inDraft;
683
+ $[7] = now;
684
+ $[8] = onShow;
685
+ $[9] = t3;
686
+ } else t3 = $[9];
687
+ t2 = patroller.reports.map(t3);
688
+ $[1] = inDraft;
689
+ $[2] = now;
690
+ $[3] = onShow;
691
+ $[4] = patroller.reports;
692
+ $[5] = t2;
693
+ } else t2 = $[5];
694
+ let t3;
695
+ if ($[10] !== patroller.more) {
696
+ t3 = patroller.more.length > 0 && /* @__PURE__ */ jsx("li", {
697
+ "data-more": true,
698
+ className: "text-muted-foreground",
699
+ children: moreSentence(patroller.more)
586
700
  });
587
- $[36] = expanded;
588
- $[37] = inDraft;
589
- $[38] = now;
590
- $[39] = onShow;
591
- $[40] = patroller.more;
592
- $[41] = patroller.reports;
593
- $[42] = reportsId;
594
- $[43] = t15;
595
- } else t15 = $[43];
596
- let t16;
597
- if ($[44] !== patroller.id || $[45] !== t12 || $[46] !== t14 || $[47] !== t15) {
598
- t16 = /* @__PURE__ */ jsxs("li", {
599
- "data-patroller": patroller.id,
600
- className: "flex flex-col",
601
- children: [
602
- t12,
603
- t14,
604
- t15
605
- ]
701
+ $[10] = patroller.more;
702
+ $[11] = t3;
703
+ } else t3 = $[11];
704
+ let t4;
705
+ if ($[12] !== patroller.id || $[13] !== t2 || $[14] !== t3) {
706
+ t4 = /* @__PURE__ */ jsxs("ul", {
707
+ "data-reports": t1,
708
+ className: "flex flex-col gap-1 text-xs",
709
+ children: [t2, t3]
606
710
  });
607
- $[44] = patroller.id;
608
- $[45] = t12;
609
- $[46] = t14;
610
- $[47] = t15;
611
- $[48] = t16;
612
- } else t16 = $[48];
613
- return t16;
711
+ $[12] = patroller.id;
712
+ $[13] = t2;
713
+ $[14] = t3;
714
+ $[15] = t4;
715
+ } else t4 = $[15];
716
+ return t4;
614
717
  }
615
718
  /**
616
719
  * A report's sentence: a button showing its subject where it is, over the whole row, named for
@@ -673,4 +776,4 @@ function ReportSentence(t0) {
673
776
  }
674
777
 
675
778
  //#endregion
676
- export { Patrol, PatrolRoster, inHeldOrder };
779
+ export { Patrol, PatrolRoster, PatrollerReports, inHeldOrder };
@@ -1,7 +1,7 @@
1
- import { AuthContext } from "../../../lib/auth.js";
2
- import { getApiUrl } from "../../../lib/api-client.js";
3
1
  import { Link as Link$1 } from "../../navigation/navigation.js";
2
+ import { AuthContext } from "../../../lib/auth.js";
4
3
  import { reads, useReadQuery } from "../../../lib/studio-reads.js";
4
+ import { getApiUrl } from "../../../lib/api-client.js";
5
5
  import { useLocalizedPath } from "../../../lib/view-locale.js";
6
6
  import { version } from "../../../package.js";
7
7
  import { STUDIO_SETTINGS_PATH } from "../routes.js";