camox 0.65.1 → 0.67.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 (42) hide show
  1. package/dist/features/canvas/CamoxCanvas.js +195 -173
  2. package/dist/features/canvas/canvasFrameCapture.js +5 -12
  3. package/dist/features/canvas/canvasFrameDocument.js +90 -29
  4. package/dist/features/canvas/canvasItems.js +22 -6
  5. package/dist/features/canvas/sidebar/ContentSidebar.js +19 -21
  6. package/dist/features/canvas/sidebar/LayoutPageOverview.js +22 -49
  7. package/dist/features/canvas/sidebar/LayoutPageSeo.js +73 -76
  8. package/dist/features/canvas/sidebar/PageInspector.js +61 -50
  9. package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +4 -4
  10. package/dist/features/canvas/useCanvasCamera.js +22 -5
  11. package/dist/features/content/components/MissingFromLocale.js +1 -1
  12. package/dist/features/page/UnplacedLayoutContent.js +141 -0
  13. package/dist/features/preview/components/ItemFieldsEditor.js +50 -44
  14. package/dist/features/preview/components/PageInfo.js +103 -100
  15. package/dist/features/preview/components/SelectionEditor.js +284 -231
  16. package/dist/features/preview/components/contentFieldSchema.js +5 -1
  17. package/dist/features/runtime/RuntimeChrome.js +66 -40
  18. package/dist/features/runtime/pageApp.js +24 -10
  19. package/dist/features/runtime/runtime.d.ts +13 -0
  20. package/dist/features/runtime/runtime.js +58 -2
  21. package/dist/features/studio/components/AgentSidebar.js +3 -3
  22. package/dist/features/studio/components/ChatWidget.js +34 -29
  23. package/dist/features/studio/components/ContentFindings.js +397 -0
  24. package/dist/features/studio/components/DraftsControl.js +172 -159
  25. package/dist/features/studio/components/Patrol.js +449 -426
  26. package/dist/features/studio/components/ReviewDraftSheet.js +231 -192
  27. package/dist/features/studio/components/Squareling.js +0 -9
  28. package/dist/features/studio/components/ThreadComposer.js +183 -121
  29. package/dist/features/studio/components/ThreadMessages.js +19 -11
  30. package/dist/features/studio/components/UnnamedDraftBar.js +349 -0
  31. package/dist/features/studio/findingSentence.js +3 -5
  32. package/dist/features/studio/patrollerBio.js +39 -0
  33. package/dist/features/studio/reportSentence.js +0 -5
  34. package/dist/features/studio/studioStore.js +13 -0
  35. package/dist/features/studio/workingSentence.js +2 -11
  36. package/dist/lib/revisions.js +25 -3
  37. package/dist/lib/use-thread.js +1 -1
  38. package/dist/package.js +1 -1
  39. package/dist/studio.css +1 -1
  40. package/package.json +4 -4
  41. package/dist/features/canvas/sidebar/DerivedPageInspector.js +0 -49
  42. package/dist/features/canvas/sidebar/SingletonPageInspector.js +0 -39
@@ -0,0 +1,397 @@
1
+ import { useCurrentDraftId } from "../../../lib/draft-scope.js";
2
+ import { useViewLocale } from "../../../lib/view-locale-context.js";
3
+ import { AuthContext } from "../../../lib/auth.js";
4
+ import { reads, useReadQuery } from "../../../lib/studio-reads.js";
5
+ import { patrolMutations } from "../../../lib/queries.js";
6
+ import { studioStore } from "../studioStore.js";
7
+ import { askAgentMessage, dismissLabel, findingSentenceInPlace, fixLabel } from "../findingSentence.js";
8
+ import { useShowInCanvas } from "../showInCanvas.js";
9
+ import { c } from "react/compiler-runtime";
10
+ import * as React from "react";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ import { useMutation } from "@tanstack/react-query";
13
+ import { Button } from "@camox/ui/button";
14
+ import { CircleAlert } from "lucide-react";
15
+ import { toast } from "@camox/ui/toaster";
16
+ import { Alert, AlertDescription, AlertTitle } from "@camox/ui/alert";
17
+
18
+ //#region src/features/studio/components/ContentFindings.tsx
19
+ /** The open findings of the Patrol viewed in a subject, in the locale viewed. */
20
+ function useContentFindings(subject) {
21
+ const $ = c(22);
22
+ const { projectUuid } = React.useContext(AuthContext);
23
+ let t0;
24
+ if ($[0] !== projectUuid) {
25
+ t0 = reads.project({ projectUuid });
26
+ $[0] = projectUuid;
27
+ $[1] = t0;
28
+ } else t0 = $[1];
29
+ const { data: project } = useReadQuery(t0);
30
+ let t1;
31
+ if ($[2] !== project?.id) {
32
+ t1 = reads.patrol({ projectId: project?.id ?? 0 });
33
+ $[2] = project?.id;
34
+ $[3] = t1;
35
+ } else t1 = $[3];
36
+ const t2 = project !== void 0 && subject !== null;
37
+ let t3;
38
+ if ($[4] !== t2) {
39
+ t3 = { enabled: t2 };
40
+ $[4] = t2;
41
+ $[5] = t3;
42
+ } else t3 = $[5];
43
+ const { data: view } = useReadQuery(t1, t3);
44
+ const viewed = useViewLocale().locale;
45
+ let t4;
46
+ if ($[6] !== project?.id) {
47
+ t4 = reads.localeList({ projectId: project?.id ?? 0 });
48
+ $[6] = project?.id;
49
+ $[7] = t4;
50
+ } else t4 = $[7];
51
+ const t5 = project !== void 0 && subject !== null;
52
+ let t6;
53
+ if ($[8] !== t5) {
54
+ t6 = { enabled: t5 };
55
+ $[8] = t5;
56
+ $[9] = t6;
57
+ } else t6 = $[9];
58
+ const { data: locales } = useReadQuery(t4, t6);
59
+ let t7;
60
+ if ($[10] !== locales || $[11] !== viewed.isDefault || $[12] !== viewed.tag) {
61
+ t7 = viewed.isDefault ? locales?.find(_temp)?.tag ?? viewed.tag : viewed.tag;
62
+ $[10] = locales;
63
+ $[11] = viewed.isDefault;
64
+ $[12] = viewed.tag;
65
+ $[13] = t7;
66
+ } else t7 = $[13];
67
+ const tag = t7;
68
+ let t8;
69
+ if ($[14] !== subject || $[15] !== tag || $[16] !== view?.patrollers) {
70
+ t8 = subject === null ? [] : (view?.patrollers ?? []).flatMap((patroller) => patroller.findings.filter((finding) => finding.subject.entity === subject.entity && finding.subject.id === subject.id && finding.locale === tag).map((finding_0) => ({
71
+ ...finding_0,
72
+ role: patroller.role
73
+ })));
74
+ $[14] = subject;
75
+ $[15] = tag;
76
+ $[16] = view?.patrollers;
77
+ $[17] = t8;
78
+ } else t8 = $[17];
79
+ const findings = t8;
80
+ const t9 = project?.id;
81
+ const t10 = view?.patrolDraft ?? null;
82
+ let t11;
83
+ if ($[18] !== findings || $[19] !== t10 || $[20] !== t9) {
84
+ t11 = {
85
+ projectId: t9,
86
+ patrolDraft: t10,
87
+ findings
88
+ };
89
+ $[18] = findings;
90
+ $[19] = t10;
91
+ $[20] = t9;
92
+ $[21] = t11;
93
+ } else t11 = $[21];
94
+ return t11;
95
+ }
96
+ function _temp(locale) {
97
+ return locale.isDefault;
98
+ }
99
+ /** What a field's row says of its findings, such as "2 findings", or nothing without any. */
100
+ function findingsHint(view, field) {
101
+ const count = view.findings.filter((finding) => finding.field === field).length;
102
+ if (count === 0) return void 0;
103
+ return count === 1 ? "1 finding" : `${count} findings`;
104
+ }
105
+ /**
106
+ * The findings in one field of a subject, as `useContentFindings` reads them, under that field's
107
+ * editor. Without `field`, those in none of `fields`: about the subject as a whole.
108
+ */
109
+ function ContentFindings(t0) {
110
+ const $ = c(20);
111
+ const { view, field, fields, className } = t0;
112
+ const { projectId, patrolDraft, findings } = view;
113
+ let t1;
114
+ let t2;
115
+ let t3;
116
+ let t4;
117
+ if ($[0] !== className || $[1] !== field || $[2] !== fields || $[3] !== findings || $[4] !== patrolDraft || $[5] !== projectId) {
118
+ t4 = Symbol.for("react.early_return_sentinel");
119
+ bb0: {
120
+ let t5;
121
+ if ($[10] !== field || $[11] !== fields) {
122
+ t5 = (finding) => field === void 0 ? !fields.includes(finding.field) : finding.field === field;
123
+ $[10] = field;
124
+ $[11] = fields;
125
+ $[12] = t5;
126
+ } else t5 = $[12];
127
+ const shown = findings.filter(t5);
128
+ if (projectId === void 0 || shown.length === 0) {
129
+ t4 = null;
130
+ break bb0;
131
+ }
132
+ t1 = true;
133
+ t2 = className ?? "space-y-2 px-2 pb-4";
134
+ let t6;
135
+ if ($[13] !== patrolDraft || $[14] !== projectId) {
136
+ t6 = (finding_0) => /* @__PURE__ */ jsx(FindingAlert, {
137
+ projectId,
138
+ finding: finding_0,
139
+ patrolDraft
140
+ }, finding_0.id);
141
+ $[13] = patrolDraft;
142
+ $[14] = projectId;
143
+ $[15] = t6;
144
+ } else t6 = $[15];
145
+ t3 = shown.map(t6);
146
+ }
147
+ $[0] = className;
148
+ $[1] = field;
149
+ $[2] = fields;
150
+ $[3] = findings;
151
+ $[4] = patrolDraft;
152
+ $[5] = projectId;
153
+ $[6] = t1;
154
+ $[7] = t2;
155
+ $[8] = t3;
156
+ $[9] = t4;
157
+ } else {
158
+ t1 = $[6];
159
+ t2 = $[7];
160
+ t3 = $[8];
161
+ t4 = $[9];
162
+ }
163
+ if (t4 !== Symbol.for("react.early_return_sentinel")) return t4;
164
+ let t5;
165
+ if ($[16] !== t1 || $[17] !== t2 || $[18] !== t3) {
166
+ t5 = /* @__PURE__ */ jsx("div", {
167
+ "data-content-findings": t1,
168
+ className: t2,
169
+ children: t3
170
+ });
171
+ $[16] = t1;
172
+ $[17] = t2;
173
+ $[18] = t3;
174
+ $[19] = t5;
175
+ } else t5 = $[19];
176
+ return t5;
177
+ }
178
+ function FindingAlert(t0) {
179
+ const $ = c(44);
180
+ const { projectId, finding, patrolDraft } = t0;
181
+ const draftId = useCurrentDraftId();
182
+ let t1;
183
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
184
+ t1 = {
185
+ ...patrolMutations.applyFix(),
186
+ onSuccess: _temp2,
187
+ onError: _temp3
188
+ };
189
+ $[0] = t1;
190
+ } else t1 = $[0];
191
+ const applyFix = useMutation(t1);
192
+ let t2;
193
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
194
+ t2 = {
195
+ ...patrolMutations.dismissFinding(),
196
+ onError: _temp4
197
+ };
198
+ $[1] = t2;
199
+ } else t2 = $[1];
200
+ const dismiss = useMutation(t2);
201
+ const busy = applyFix.isPending || dismiss.isPending;
202
+ const fixesHere = draftId !== null && (!finding.live || draftId === patrolDraft?.id);
203
+ let t3;
204
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
205
+ t3 = /* @__PURE__ */ jsx(CircleAlert, {});
206
+ $[2] = t3;
207
+ } else t3 = $[2];
208
+ let t4;
209
+ if ($[3] !== finding) {
210
+ t4 = findingSentenceInPlace(finding);
211
+ $[3] = finding;
212
+ $[4] = t4;
213
+ } else t4 = $[4];
214
+ let t5;
215
+ if ($[5] !== t4) {
216
+ t5 = /* @__PURE__ */ jsx(AlertTitle, {
217
+ className: "text-xs font-normal",
218
+ children: t4
219
+ });
220
+ $[5] = t4;
221
+ $[6] = t5;
222
+ } else t5 = $[6];
223
+ let t6;
224
+ if ($[7] !== finding.role) {
225
+ t6 = /* @__PURE__ */ jsx("p", { children: finding.role });
226
+ $[7] = finding.role;
227
+ $[8] = t6;
228
+ } else t6 = $[8];
229
+ let t7;
230
+ if ($[9] !== applyFix || $[10] !== busy || $[11] !== finding.fix || $[12] !== finding.id || $[13] !== fixesHere || $[14] !== projectId) {
231
+ t7 = fixesHere && finding.fix && /* @__PURE__ */ jsx(Button, {
232
+ variant: "outline",
233
+ size: "xs",
234
+ disabled: busy,
235
+ onClick: () => applyFix.mutate({
236
+ projectId,
237
+ findingId: finding.id
238
+ }),
239
+ children: fixLabel(finding.fix)
240
+ });
241
+ $[9] = applyFix;
242
+ $[10] = busy;
243
+ $[11] = finding.fix;
244
+ $[12] = finding.id;
245
+ $[13] = fixesHere;
246
+ $[14] = projectId;
247
+ $[15] = t7;
248
+ } else t7 = $[15];
249
+ let t8;
250
+ if ($[16] !== finding || $[17] !== fixesHere) {
251
+ t8 = fixesHere && /* @__PURE__ */ jsx(Button, {
252
+ variant: "outline",
253
+ size: "xs",
254
+ onClick: () => studioStore.trigger.askAgent({ text: askAgentMessage(finding, finding.role) }),
255
+ children: "Ask the agent"
256
+ });
257
+ $[16] = finding;
258
+ $[17] = fixesHere;
259
+ $[18] = t8;
260
+ } else t8 = $[18];
261
+ let t9;
262
+ if ($[19] !== draftId || $[20] !== finding || $[21] !== patrolDraft) {
263
+ t9 = draftId === null && patrolDraft && /* @__PURE__ */ jsx(OpenInPatrolDraft, {
264
+ finding,
265
+ patrolDraft
266
+ });
267
+ $[19] = draftId;
268
+ $[20] = finding;
269
+ $[21] = patrolDraft;
270
+ $[22] = t9;
271
+ } else t9 = $[22];
272
+ let t10;
273
+ if ($[23] !== dismiss || $[24] !== finding.id || $[25] !== projectId) {
274
+ t10 = () => dismiss.mutate({
275
+ projectId,
276
+ findingId: finding.id
277
+ });
278
+ $[23] = dismiss;
279
+ $[24] = finding.id;
280
+ $[25] = projectId;
281
+ $[26] = t10;
282
+ } else t10 = $[26];
283
+ let t11;
284
+ if ($[27] !== finding.about) {
285
+ t11 = dismissLabel(finding.about);
286
+ $[27] = finding.about;
287
+ $[28] = t11;
288
+ } else t11 = $[28];
289
+ let t12;
290
+ if ($[29] !== busy || $[30] !== t10 || $[31] !== t11) {
291
+ t12 = /* @__PURE__ */ jsx(Button, {
292
+ variant: "ghost",
293
+ size: "xs",
294
+ disabled: busy,
295
+ onClick: t10,
296
+ children: t11
297
+ });
298
+ $[29] = busy;
299
+ $[30] = t10;
300
+ $[31] = t11;
301
+ $[32] = t12;
302
+ } else t12 = $[32];
303
+ let t13;
304
+ if ($[33] !== t12 || $[34] !== t7 || $[35] !== t8 || $[36] !== t9) {
305
+ t13 = /* @__PURE__ */ jsxs("span", {
306
+ className: "mt-1.5 flex flex-wrap gap-1",
307
+ children: [
308
+ t7,
309
+ t8,
310
+ t9,
311
+ t12
312
+ ]
313
+ });
314
+ $[33] = t12;
315
+ $[34] = t7;
316
+ $[35] = t8;
317
+ $[36] = t9;
318
+ $[37] = t13;
319
+ } else t13 = $[37];
320
+ let t14;
321
+ if ($[38] !== t13 || $[39] !== t6) {
322
+ t14 = /* @__PURE__ */ jsxs(AlertDescription, {
323
+ className: "text-xs",
324
+ children: [t6, t13]
325
+ });
326
+ $[38] = t13;
327
+ $[39] = t6;
328
+ $[40] = t14;
329
+ } else t14 = $[40];
330
+ let t15;
331
+ if ($[41] !== t14 || $[42] !== t5) {
332
+ t15 = /* @__PURE__ */ jsxs(Alert, {
333
+ "data-content-finding": true,
334
+ variant: "warning",
335
+ className: "px-3 py-2",
336
+ children: [
337
+ t3,
338
+ t5,
339
+ t14
340
+ ]
341
+ });
342
+ $[41] = t14;
343
+ $[42] = t5;
344
+ $[43] = t15;
345
+ } else t15 = $[43];
346
+ return t15;
347
+ }
348
+ function _temp4(error_0) {
349
+ return toast.error(error_0.message || "Could not dismiss it");
350
+ }
351
+ function _temp3(error) {
352
+ return toast.error(error.message || "Could not apply the fix");
353
+ }
354
+ function _temp2(t0) {
355
+ const { applied } = t0;
356
+ if (!applied) toast.info("The link changed since it was checked, so it's being checked again.");
357
+ }
358
+ /** Opens the Patrol Draft on a Live finding's field, as the Canvas shows it there. */
359
+ function OpenInPatrolDraft(t0) {
360
+ const $ = c(9);
361
+ const { finding, patrolDraft } = t0;
362
+ const showInCanvas = useShowInCanvas();
363
+ const { place } = finding;
364
+ if (place?.kind !== "page") return null;
365
+ let t1;
366
+ if ($[0] !== finding.field || $[1] !== finding.fieldKind || $[2] !== finding.locale || $[3] !== patrolDraft.id || $[4] !== place.blockId || $[5] !== place.itemId || $[6] !== place.pageId || $[7] !== showInCanvas) {
367
+ t1 = /* @__PURE__ */ jsx(Button, {
368
+ variant: "outline",
369
+ size: "xs",
370
+ onClick: () => void showInCanvas({
371
+ pageId: place.pageId,
372
+ locale: finding.locale,
373
+ blockId: place.blockId,
374
+ itemId: place.itemId,
375
+ field: {
376
+ name: finding.field,
377
+ kind: finding.fieldKind
378
+ },
379
+ draft: patrolDraft.id
380
+ }),
381
+ children: "Open the Patrol Draft"
382
+ });
383
+ $[0] = finding.field;
384
+ $[1] = finding.fieldKind;
385
+ $[2] = finding.locale;
386
+ $[3] = patrolDraft.id;
387
+ $[4] = place.blockId;
388
+ $[5] = place.itemId;
389
+ $[6] = place.pageId;
390
+ $[7] = showInCanvas;
391
+ $[8] = t1;
392
+ } else t1 = $[8];
393
+ return t1;
394
+ }
395
+
396
+ //#endregion
397
+ export { ContentFindings, findingsHint, useContentFindings };