camox 0.41.1 → 0.43.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 (93) hide show
  1. package/dist/core/components/lexical/{GradientNode.js → HighlightNode.js} +34 -34
  2. package/dist/core/components/lexical/InlineLexicalEditor.js +14 -14
  3. package/dist/core/components/lexical/InlineStylesPlugin.js +6 -6
  4. package/dist/core/components/lexical/SelectionBroadcaster.js +5 -5
  5. package/dist/core/components/lexical/SidebarLexicalEditor.js +52 -49
  6. package/dist/core/components/lexical/TextLinkPopover.js +191 -208
  7. package/dist/core/components/lexical/editorConfig.js +2 -2
  8. package/dist/core/createApp.d.ts +19 -4
  9. package/dist/core/createApp.js +2 -1
  10. package/dist/core/createLayout.d.ts +16 -3
  11. package/dist/core/createLayout.js +15 -15
  12. package/dist/core/derivedRoutes.js +1 -1
  13. package/dist/core/dom.d.ts +17 -0
  14. package/dist/core/dom.js +22 -0
  15. package/dist/core/editing/createEditableBlock.d.ts +8 -1
  16. package/dist/core/editing/createEditableBlock.js +636 -459
  17. package/dist/core/hooks/useOverlayState.js +11 -0
  18. package/dist/core/lib/fieldTypes.js +5 -5
  19. package/dist/core/lib/lexicalReact.js +4 -4
  20. package/dist/core/lib/lexicalState.js +20 -4
  21. package/dist/core/lib/modifierFormats.js +1 -1
  22. package/dist/core/lib/textLinks.js +5 -2
  23. package/dist/core/lib/textStyles.d.ts +2 -2
  24. package/dist/core/lib/textStyles.js +6 -11
  25. package/dist/core/pageDestinations.js +37 -0
  26. package/dist/features/og/imageResponse.node.js +11 -9
  27. package/dist/features/preview/CamoxPreview.js +108 -124
  28. package/dist/features/preview/commentsEnabled.js +8 -0
  29. package/dist/features/preview/components/AddBlockSidebar.js +80 -90
  30. package/dist/features/preview/components/AssetLightbox.js +4 -11
  31. package/dist/features/preview/components/AttachedComments.js +194 -0
  32. package/dist/features/preview/components/BlockActionsPopover.js +14 -65
  33. package/dist/features/preview/components/CommentHeader.js +122 -0
  34. package/dist/features/preview/components/CommentSidebar.js +29 -0
  35. package/dist/features/preview/components/CommentTargetQuote.js +166 -0
  36. package/dist/features/preview/components/CreatePageModal.js +4 -10
  37. package/dist/features/preview/components/DerivedLayoutSidebar.js +45 -26
  38. package/dist/features/preview/components/DerivedPageInfoSidebar.js +38 -26
  39. package/dist/features/preview/components/FieldToolbar.js +7 -7
  40. package/dist/features/preview/components/ItemFieldsEditor.js +275 -204
  41. package/dist/features/preview/components/LeftSidebar.js +18 -18
  42. package/dist/features/preview/components/LinkFieldEditor.js +212 -209
  43. package/dist/features/preview/components/OverlayTracker.js +14 -20
  44. package/dist/features/preview/components/Overlays.js +26 -35
  45. package/dist/features/preview/components/PageEditorSidebar.js +90 -91
  46. package/dist/features/preview/components/PageInfoSidebar.js +128 -159
  47. package/dist/features/preview/components/PagePicker.js +29 -24
  48. package/dist/features/preview/components/PageTree.js +159 -157
  49. package/dist/features/preview/components/PreviewComments.js +56 -0
  50. package/dist/features/preview/components/PreviewPanel.js +122 -78
  51. package/dist/features/preview/components/PreviewToolbar.js +280 -231
  52. package/dist/features/preview/components/PublicationRow.js +8 -11
  53. package/dist/features/preview/components/RightSidebar.js +14 -11
  54. package/dist/features/preview/components/SidebarSection.js +121 -0
  55. package/dist/features/preview/components/useRepeatableItemActions.js +1 -1
  56. package/dist/features/preview/previewCommentsStore.js +115 -0
  57. package/dist/features/preview/previewSelection.js +75 -0
  58. package/dist/features/preview/previewStore.js +19 -39
  59. package/dist/features/preview/publication.js +10 -0
  60. package/dist/features/provider/AuthenticatedCamoxProvider.js +46 -34
  61. package/dist/features/provider/CoreCamoxProvider.js +1 -1
  62. package/dist/features/provider/components/CommandPalette.js +142 -58
  63. package/dist/features/provider/useAdminShortcuts.js +19 -8
  64. package/dist/features/routes/pageRuntime.js +0 -6
  65. package/dist/features/runtime/RuntimeChrome.js +40 -37
  66. package/dist/features/runtime/runtime.js +20 -21
  67. package/dist/features/studio/CamoxStudio.js +30 -50
  68. package/dist/features/studio/components/EnvironmentMenu.js +3 -2
  69. package/dist/features/studio/components/Navbar.js +53 -80
  70. package/dist/features/vite/layoutGeneration.js +7 -3
  71. package/dist/features/vite/runtimeDev.js +4 -1
  72. package/dist/features/vite/vite.d.ts +3 -2
  73. package/dist/features/vite/vite.js +14 -6
  74. package/dist/hooks/use-file-upload.js +0 -2
  75. package/dist/hooks/use-page-destinations.js +53 -0
  76. package/dist/lib/auth.js +11 -14
  77. package/dist/lib/server-auth-cookie.js +21 -0
  78. package/dist/studio.css +1 -1
  79. package/package.json +9 -7
  80. package/skills/camox/SKILL.md +32 -9
  81. package/skills/camox/references/block-definitions.md +84 -290
  82. package/skills/camox/references/cli-common.md +2 -4
  83. package/skills/camox/references/cli-content.md +147 -0
  84. package/skills/camox/references/cli-environments.md +1 -1
  85. package/skills/camox/references/dom-integrations.md +93 -0
  86. package/skills/camox/references/field-styling.md +50 -0
  87. package/skills/camox/references/layout-definitions.md +33 -147
  88. package/skills/camox/references/routed-layouts.md +71 -0
  89. package/skills/camoxify/SKILL.md +52 -0
  90. package/dist/lib/telemetry-client.js +0 -66
  91. package/dist/lib/telemetry.js +0 -26
  92. package/skills/camox/references/cli-blocks.md +0 -78
  93. package/skills/camox/references/cli-pages.md +0 -53
@@ -1,9 +1,8 @@
1
1
  import { actionsStore } from "../../provider/actionsStore.js";
2
2
  import { usePageBlocks } from "../../../lib/normalized-data.js";
3
+ import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
3
4
  import { blockMutations, repeatableItemMutations } from "../../../lib/queries.js";
4
5
  import { formatShortcut } from "../../../lib/utils.js";
5
- import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
6
- import { trackClientEvent } from "../../../lib/telemetry-client.js";
7
6
  import { previewStore, selectionItemId } from "../previewStore.js";
8
7
  import { useRequireDraftSource } from "../../../core/hooks/useRequireDraftSource.js";
9
8
  import { useUpdateBlockPosition } from "./useUpdateBlockPosition.js";
@@ -13,7 +12,7 @@ import { useMutation } from "@tanstack/react-query";
13
12
  import * as React from "react";
14
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
15
14
  import { useSelector } from "@xstate/store-react";
16
- import { Copy, Pen, Settings, Trash2 } from "lucide-react";
15
+ import { Copy, Trash2 } from "lucide-react";
17
16
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@camox/ui/alert-dialog";
18
17
  import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
19
18
  import { toast } from "@camox/ui/toaster";
@@ -22,7 +21,6 @@ import { Command, CommandGroup, CommandInput, CommandItem, CommandList, CommandS
22
21
  //#region src/features/preview/components/BlockActionsPopover.tsx
23
22
  const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "start", isLayoutBlock, layoutPlacement }) => {
24
23
  const [blockToDelete, setBlockToDelete] = React.useState(null);
25
- const camoxApp = useCamoxApp();
26
24
  const page = usePreviewedPage();
27
25
  const { pageBlocks } = usePageBlocks(page);
28
26
  const deleteBlock = useMutation(blockMutations.delete());
@@ -31,10 +29,6 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
31
29
  const handleDeleteBlock = async (block_0) => {
32
30
  try {
33
31
  await deleteBlock.mutateAsync({ id: block_0.id });
34
- trackClientEvent("block_deleted", {
35
- projectId: page?.page.projectId,
36
- blockType: block_0.type
37
- });
38
32
  toast.success(`Deleted "${block_0.summary || block_0.type}" block`);
39
33
  } catch (error) {
40
34
  console.error("Failed to delete block:", error);
@@ -46,10 +40,6 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
46
40
  const handleDuplicateBlock = async (block_1) => {
47
41
  try {
48
42
  await duplicateBlock.mutateAsync({ id: block_1.id });
49
- trackClientEvent("block_duplicated", {
50
- projectId: page?.page.projectId,
51
- blockType: block_1.type
52
- });
53
43
  toast.success(`Duplicated "${block_1.summary}" block`);
54
44
  } catch (error_0) {
55
45
  console.error("Failed to duplicate block:", error_0);
@@ -62,15 +52,13 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
62
52
  const afterPosition = blockIndex > 0 ? pageBlocks[blockIndex - 1].position : "";
63
53
  previewStore.send({
64
54
  type: "openAddBlockSidebar",
65
- afterPosition,
66
- via: "popover-above"
55
+ afterPosition
67
56
  });
68
57
  };
69
58
  const handleAddBlockBelow = (block_3) => {
70
59
  previewStore.send({
71
60
  type: "openAddBlockSidebar",
72
- afterPosition: block_3.position,
73
- via: "popover-below"
61
+ afterPosition: block_3.position
74
62
  });
75
63
  };
76
64
  const getBlocksAbove = (block_4) => {
@@ -114,46 +102,11 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
114
102
  children: /* @__PURE__ */ jsxs(Command, { children: [/* @__PURE__ */ jsx(CommandInput, { placeholder: "Search actions..." }), /* @__PURE__ */ jsxs(CommandList, {
115
103
  className: "max-h-[350px]",
116
104
  children: [
117
- /* @__PURE__ */ jsxs(CommandGroup, { children: [/* @__PURE__ */ jsxs(CommandItem, {
118
- className: "justify-between",
119
- onSelect: () => {
120
- previewStore.send({
121
- type: "openBlockContentSheet",
122
- blockId: block.id
123
- });
124
- onOpenChange(false);
125
- },
126
- children: [/* @__PURE__ */ jsxs("div", {
127
- className: "flex items-center gap-2",
128
- children: [/* @__PURE__ */ jsx(Pen, { className: "h-4 w-4" }), "Edit in form"]
129
- }), /* @__PURE__ */ jsx(CommandShortcut, { children: formatShortcut({
130
- key: "j",
131
- withMeta: true
132
- }) })]
133
- }), !isLayoutBlock && (() => {
134
- const blockDef = camoxApp.getBlockById(block.type);
135
- if (!(blockDef?._internal.settingsSchema?.properties && Object.keys(blockDef._internal.settingsSchema.properties).length > 0)) return null;
136
- return /* @__PURE__ */ jsx(CommandItem, {
137
- className: "justify-between",
138
- onSelect: () => {
139
- previewStore.send({
140
- type: "openBlockContentSheet",
141
- blockId: block.id
142
- });
143
- onOpenChange(false);
144
- },
145
- children: /* @__PURE__ */ jsxs("div", {
146
- className: "flex items-center gap-2",
147
- children: [/* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }), "Open settings"]
148
- })
149
- });
150
- })()] }),
151
- isLayoutBlock && layoutPlacement === "before" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(CommandSeparator, {}), /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx(CommandItem, {
105
+ isLayoutBlock && layoutPlacement === "before" && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx(CommandItem, {
152
106
  onSelect: () => {
153
107
  previewStore.send({
154
108
  type: "openAddBlockSidebar",
155
- afterPosition: "",
156
- via: "layout-popover-below"
109
+ afterPosition: ""
157
110
  });
158
111
  onOpenChange(false);
159
112
  },
@@ -161,14 +114,13 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
161
114
  className: "flex items-center gap-2",
162
115
  children: [/* @__PURE__ */ jsx("span", { className: "w-4" }), "Add block below"]
163
116
  })
164
- }) })] }),
165
- isLayoutBlock && layoutPlacement === "after" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(CommandSeparator, {}), /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx(CommandItem, {
117
+ }) }) }),
118
+ isLayoutBlock && layoutPlacement === "after" && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx(CommandItem, {
166
119
  onSelect: () => {
167
120
  const lastPageBlock = pageBlocks[pageBlocks.length - 1];
168
121
  previewStore.send({
169
122
  type: "openAddBlockSidebar",
170
- afterPosition: lastPageBlock?.position,
171
- via: "layout-popover-above"
123
+ afterPosition: lastPageBlock?.position
172
124
  });
173
125
  onOpenChange(false);
174
126
  },
@@ -176,9 +128,8 @@ const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "sta
176
128
  className: "flex items-center gap-2",
177
129
  children: [/* @__PURE__ */ jsx("span", { className: "w-4" }), "Add block above"]
178
130
  })
179
- }) })] }),
131
+ }) }) }),
180
132
  !isLayoutBlock && /* @__PURE__ */ jsxs(Fragment, { children: [
181
- /* @__PURE__ */ jsx(CommandSeparator, {}),
182
133
  /* @__PURE__ */ jsxs(CommandGroup, { children: [/* @__PURE__ */ jsxs(CommandItem, {
183
134
  className: "justify-between",
184
135
  onSelect: () => {
@@ -279,9 +230,9 @@ function isLayoutBlockId(page, blockId) {
279
230
  }
280
231
  function useBlockActionsShortcuts() {
281
232
  const $ = c(20);
282
- if ($[0] !== "2439a21a93e7dc68e5e2199bf795bec817fbc1286e567fde9de806e04fd01b64") {
233
+ if ($[0] !== "a91fc105ded90c35296c42adc5eec1823e26e305818bf9026d22b67a24a3ca04") {
283
234
  for (let $i = 0; $i < 20; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
284
- $[0] = "2439a21a93e7dc68e5e2199bf795bec817fbc1286e567fde9de806e04fd01b64";
235
+ $[0] = "a91fc105ded90c35296c42adc5eec1823e26e305818bf9026d22b67a24a3ca04";
285
236
  }
286
237
  const camoxApp = useCamoxApp();
287
238
  const page = usePreviewedPage();
@@ -465,8 +416,7 @@ function useBlockActionsShortcuts() {
465
416
  if (!block_2) return;
466
417
  previewStore.send({
467
418
  type: "openAddBlockSidebar",
468
- afterPosition: block_2.position,
469
- via: "shortcut-below"
419
+ afterPosition: block_2.position
470
420
  });
471
421
  }
472
422
  },
@@ -488,8 +438,7 @@ function useBlockActionsShortcuts() {
488
438
  const afterPosition_1 = blockIndex > 0 ? pageBlocks[blockIndex - 1].position : "";
489
439
  previewStore.send({
490
440
  type: "openAddBlockSidebar",
491
- afterPosition: afterPosition_1,
492
- via: "shortcut-above"
441
+ afterPosition: afterPosition_1
493
442
  });
494
443
  }
495
444
  }
@@ -0,0 +1,122 @@
1
+ import { c } from "react/compiler-runtime";
2
+ import * as React from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { Avatar, AvatarFallback, AvatarImage } from "@camox/ui/avatar";
5
+
6
+ //#region src/features/preview/components/CommentHeader.tsx
7
+ function CommentHeader(t0) {
8
+ const $ = c(27);
9
+ if ($[0] !== "7228323105605d4be0594558d7e4fb389f5d49bc9cb13e6a90c0c2fc6f9ff60f") {
10
+ for (let $i = 0; $i < 27; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
11
+ $[0] = "7228323105605d4be0594558d7e4fb389f5d49bc9cb13e6a90c0c2fc6f9ff60f";
12
+ }
13
+ const { author, createdAt } = t0;
14
+ const [now, setNow] = React.useState(Date.now);
15
+ let t1;
16
+ let t2;
17
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
18
+ t1 = () => {
19
+ const timer = window.setInterval(() => setNow(Date.now()), 6e4);
20
+ return () => window.clearInterval(timer);
21
+ };
22
+ t2 = [];
23
+ $[1] = t1;
24
+ $[2] = t2;
25
+ } else {
26
+ t1 = $[1];
27
+ t2 = $[2];
28
+ }
29
+ React.useEffect(t1, t2);
30
+ const minutes = Math.max(0, Math.floor((now - createdAt) / 6e4));
31
+ const age = minutes < 1 ? "now" : minutes < 60 ? `${minutes}m` : minutes < 1440 ? `${Math.floor(minutes / 60)}h` : `${Math.floor(minutes / 1440)}d`;
32
+ let t3;
33
+ if ($[3] !== author.name) {
34
+ t3 = author.name.trim().split(/\s+/).map(_temp).join("").slice(0, 2).toUpperCase();
35
+ $[3] = author.name;
36
+ $[4] = t3;
37
+ } else t3 = $[4];
38
+ const initials = t3;
39
+ let t4;
40
+ if ($[5] !== author.image || $[6] !== author.name) {
41
+ t4 = author.image && /* @__PURE__ */ jsx(AvatarImage, {
42
+ src: author.image,
43
+ alt: author.name
44
+ });
45
+ $[5] = author.image;
46
+ $[6] = author.name;
47
+ $[7] = t4;
48
+ } else t4 = $[7];
49
+ let t5;
50
+ if ($[8] !== initials) {
51
+ t5 = /* @__PURE__ */ jsx(AvatarFallback, { children: initials });
52
+ $[8] = initials;
53
+ $[9] = t5;
54
+ } else t5 = $[9];
55
+ let t6;
56
+ if ($[10] !== t4 || $[11] !== t5) {
57
+ t6 = /* @__PURE__ */ jsxs(Avatar, {
58
+ size: "sm",
59
+ children: [t4, t5]
60
+ });
61
+ $[10] = t4;
62
+ $[11] = t5;
63
+ $[12] = t6;
64
+ } else t6 = $[12];
65
+ let t7;
66
+ if ($[13] !== author.name) {
67
+ t7 = /* @__PURE__ */ jsx("span", {
68
+ className: "truncate text-sm font-medium",
69
+ title: author.name,
70
+ children: author.name
71
+ });
72
+ $[13] = author.name;
73
+ $[14] = t7;
74
+ } else t7 = $[14];
75
+ let t8;
76
+ if ($[15] !== createdAt) {
77
+ t8 = new Date(createdAt).toISOString();
78
+ $[15] = createdAt;
79
+ $[16] = t8;
80
+ } else t8 = $[16];
81
+ let t9;
82
+ if ($[17] !== createdAt) {
83
+ t9 = new Date(createdAt).toLocaleString();
84
+ $[17] = createdAt;
85
+ $[18] = t9;
86
+ } else t9 = $[18];
87
+ let t10;
88
+ if ($[19] !== age || $[20] !== t8 || $[21] !== t9) {
89
+ t10 = /* @__PURE__ */ jsx("time", {
90
+ className: "text-muted-foreground shrink-0 text-xs",
91
+ dateTime: t8,
92
+ title: t9,
93
+ children: age
94
+ });
95
+ $[19] = age;
96
+ $[20] = t8;
97
+ $[21] = t9;
98
+ $[22] = t10;
99
+ } else t10 = $[22];
100
+ let t11;
101
+ if ($[23] !== t10 || $[24] !== t6 || $[25] !== t7) {
102
+ t11 = /* @__PURE__ */ jsxs("header", {
103
+ className: "mb-2 flex min-w-0 items-center gap-2",
104
+ children: [
105
+ t6,
106
+ t7,
107
+ t10
108
+ ]
109
+ });
110
+ $[23] = t10;
111
+ $[24] = t6;
112
+ $[25] = t7;
113
+ $[26] = t11;
114
+ } else t11 = $[26];
115
+ return t11;
116
+ }
117
+ function _temp(part) {
118
+ return part[0];
119
+ }
120
+
121
+ //#endregion
122
+ export { CommentHeader };
@@ -0,0 +1,29 @@
1
+ import { AttachedComments } from "./AttachedComments.js";
2
+ import { c } from "react/compiler-runtime";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ //#region src/features/preview/components/CommentSidebar.tsx
6
+ function CommentSidebar(t0) {
7
+ const $ = c(3);
8
+ if ($[0] !== "d6df60b689386423d40951e6785b3daf7545c90c2ab947b318a4d6c91e5fdf67") {
9
+ for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
10
+ $[0] = "d6df60b689386423d40951e6785b3daf7545c90c2ab947b318a4d6c91e5fdf67";
11
+ }
12
+ const { pageId } = t0;
13
+ let t1;
14
+ if ($[1] !== pageId) {
15
+ t1 = /* @__PURE__ */ jsx("div", {
16
+ className: "min-h-0 flex-1 overflow-auto",
17
+ children: /* @__PURE__ */ jsx(AttachedComments, {
18
+ pageId,
19
+ allPageComments: true
20
+ })
21
+ });
22
+ $[1] = pageId;
23
+ $[2] = t1;
24
+ } else t1 = $[2];
25
+ return t1;
26
+ }
27
+
28
+ //#endregion
29
+ export { CommentSidebar };
@@ -0,0 +1,166 @@
1
+ import { isLexicalState, lexicalStateToPlainText } from "../../../core/lib/lexicalState.js";
2
+ import { blockQueries, pageQueries } from "../../../lib/queries.js";
3
+ import { c } from "react/compiler-runtime";
4
+ import { useQuery } from "@tanstack/react-query";
5
+ import { jsx } from "react/jsx-runtime";
6
+
7
+ //#region src/features/preview/components/CommentTargetQuote.tsx
8
+ function Quote(t0) {
9
+ const $ = c(3);
10
+ if ($[0] !== "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92") {
11
+ for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
12
+ $[0] = "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92";
13
+ }
14
+ const { children } = t0;
15
+ let t1;
16
+ if ($[1] !== children) {
17
+ t1 = /* @__PURE__ */ jsx("blockquote", {
18
+ className: "text-muted-foreground my-2 border-l-2 border-yellow-600 pl-2 text-sm wrap-break-word whitespace-pre-wrap",
19
+ children
20
+ });
21
+ $[1] = children;
22
+ $[2] = t1;
23
+ } else t1 = $[2];
24
+ return t1;
25
+ }
26
+ function PageQuote(t0) {
27
+ const $ = c(5);
28
+ if ($[0] !== "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92") {
29
+ for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
30
+ $[0] = "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92";
31
+ }
32
+ const { pageId } = t0;
33
+ let t1;
34
+ if ($[1] !== pageId) {
35
+ t1 = pageQueries.getById(pageId);
36
+ $[1] = pageId;
37
+ $[2] = t1;
38
+ } else t1 = $[2];
39
+ const { data: page, isPending } = useQuery(t1);
40
+ const t2 = page?.nickname || (isPending ? "Loading…" : "Page unavailable");
41
+ let t3;
42
+ if ($[3] !== t2) {
43
+ t3 = /* @__PURE__ */ jsx(Quote, { children: t2 });
44
+ $[3] = t2;
45
+ $[4] = t3;
46
+ } else t3 = $[4];
47
+ return t3;
48
+ }
49
+ function BlockQuote(t0) {
50
+ const $ = c(19);
51
+ if ($[0] !== "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92") {
52
+ for (let $i = 0; $i < 19; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
53
+ $[0] = "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92";
54
+ }
55
+ const { target } = t0;
56
+ let t1;
57
+ if ($[1] !== target.blockId) {
58
+ t1 = blockQueries.get(target.blockId);
59
+ $[1] = target.blockId;
60
+ $[2] = t1;
61
+ } else t1 = $[2];
62
+ const { data: bundle, isPending } = useQuery(t1);
63
+ if (!bundle) {
64
+ const t2 = isPending ? "Loading…" : "Content unavailable";
65
+ let t3;
66
+ if ($[3] !== t2) {
67
+ t3 = /* @__PURE__ */ jsx(Quote, { children: t2 });
68
+ $[3] = t2;
69
+ $[4] = t3;
70
+ } else t3 = $[4];
71
+ return t3;
72
+ }
73
+ let t2;
74
+ if ($[5] !== bundle.block || $[6] !== bundle.repeatableItems || $[7] !== target.itemId) {
75
+ t2 = target.itemId == null ? bundle.block : bundle.repeatableItems.find((item) => item.id === target.itemId);
76
+ $[5] = bundle.block;
77
+ $[6] = bundle.repeatableItems;
78
+ $[7] = target.itemId;
79
+ $[8] = t2;
80
+ } else t2 = $[8];
81
+ const subject = t2;
82
+ if (!subject) {
83
+ let t3;
84
+ if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
85
+ t3 = /* @__PURE__ */ jsx(Quote, { children: "Content unavailable" });
86
+ $[9] = t3;
87
+ } else t3 = $[9];
88
+ return t3;
89
+ }
90
+ if (target.fieldName != null) {
91
+ const value = subject.content[target.fieldName];
92
+ if (target.fieldType === "String" || target.fieldType == null) {
93
+ if (typeof value === "string" || isLexicalState(value)) {
94
+ let t3;
95
+ if ($[10] !== value) {
96
+ t3 = lexicalStateToPlainText(value) || "Empty text";
97
+ $[10] = value;
98
+ $[11] = t3;
99
+ } else t3 = $[11];
100
+ let t4;
101
+ if ($[12] !== t3) {
102
+ t4 = /* @__PURE__ */ jsx(Quote, { children: t3 });
103
+ $[12] = t3;
104
+ $[13] = t4;
105
+ } else t4 = $[13];
106
+ return t4;
107
+ }
108
+ if (value == null && target.fieldType === "String") {
109
+ let t3;
110
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
111
+ t3 = /* @__PURE__ */ jsx(Quote, { children: "Empty text" });
112
+ $[14] = t3;
113
+ } else t3 = $[14];
114
+ return t3;
115
+ }
116
+ }
117
+ if (target.fieldType === "Link" && value && typeof value === "object" && "text" in value && typeof value.text === "string") {
118
+ const t3 = value.text || "Empty link text";
119
+ let t4;
120
+ if ($[15] !== t3) {
121
+ t4 = /* @__PURE__ */ jsx(Quote, { children: t3 });
122
+ $[15] = t3;
123
+ $[16] = t4;
124
+ } else t4 = $[16];
125
+ return t4;
126
+ }
127
+ }
128
+ const t3 = subject.summary || (target.itemId == null ? "Untitled block" : "Untitled item");
129
+ let t4;
130
+ if ($[17] !== t3) {
131
+ t4 = /* @__PURE__ */ jsx(Quote, { children: t3 });
132
+ $[17] = t3;
133
+ $[18] = t4;
134
+ } else t4 = $[18];
135
+ return t4;
136
+ }
137
+ function CommentTargetQuote(t0) {
138
+ const $ = c(5);
139
+ if ($[0] !== "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92") {
140
+ for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
141
+ $[0] = "c7d7da293bb0be577af3f96a804786ef95d893a2ac7e10598c27ec5225cf9e92";
142
+ }
143
+ const { pageId, target } = t0;
144
+ if (target.blockId == null) {
145
+ let t1;
146
+ if ($[1] !== pageId) {
147
+ t1 = /* @__PURE__ */ jsx(PageQuote, { pageId });
148
+ $[1] = pageId;
149
+ $[2] = t1;
150
+ } else t1 = $[2];
151
+ return t1;
152
+ }
153
+ let t1;
154
+ if ($[3] !== target) {
155
+ t1 = /* @__PURE__ */ jsx(BlockQuote, { target: {
156
+ ...target,
157
+ blockId: target.blockId
158
+ } });
159
+ $[3] = target;
160
+ $[4] = t1;
161
+ } else t1 = $[4];
162
+ return t1;
163
+ }
164
+
165
+ //#endregion
166
+ export { CommentTargetQuote };
@@ -1,8 +1,7 @@
1
1
  import { useNavigate } from "../../navigation/navigation.js";
2
2
  import { useProjectSlug } from "../../../lib/auth.js";
3
- import { layoutQueries, pageMutations, pageQueries, projectQueries } from "../../../lib/queries.js";
4
3
  import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
5
- import { trackClientEvent } from "../../../lib/telemetry-client.js";
4
+ import { layoutQueries, pageMutations, pageQueries, projectQueries } from "../../../lib/queries.js";
6
5
  import { previewStore } from "../previewStore.js";
7
6
  import { PageLocationFieldset } from "./PageLocationFieldset.js";
8
7
  import { PageNicknameField } from "./PageNicknameField.js";
@@ -27,9 +26,9 @@ const slugifyPathSegment = (nickname) => {
27
26
  };
28
27
  const CreatePageModal = () => {
29
28
  const $ = c(59);
30
- if ($[0] !== "a489bee2c2bcec31c62ddabbd93e62c3a08c94905cfefce5cfe8476f2f60182f") {
29
+ if ($[0] !== "7d9f627f2fd6df9193c55db2f9612514acd4807aab2e5cc3fbd5bdd5aaf23672") {
31
30
  for (let $i = 0; $i < 59; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
32
- $[0] = "a489bee2c2bcec31c62ddabbd93e62c3a08c94905cfefce5cfe8476f2f60182f";
31
+ $[0] = "7d9f627f2fd6df9193c55db2f9612514acd4807aab2e5cc3fbd5bdd5aaf23672";
33
32
  }
34
33
  const projectSlug = useProjectSlug();
35
34
  const open = useSelector(previewStore, _temp);
@@ -85,7 +84,7 @@ const CreatePageModal = () => {
85
84
  const camoxApp = useCamoxApp();
86
85
  let t8;
87
86
  if ($[14] !== allLayouts || $[15] !== camoxApp) {
88
- t8 = allLayouts?.filter((layout) => camoxApp.getLayoutById(layout.layoutId)?._internal.kind !== "derived");
87
+ t8 = allLayouts?.filter((layout) => camoxApp.getLayoutById(layout.layoutId)?._internal.kind === "curated");
89
88
  $[14] = allLayouts;
90
89
  $[15] = camoxApp;
91
90
  $[16] = t8;
@@ -128,11 +127,6 @@ const CreatePageModal = () => {
128
127
  error: "Failed to create page"
129
128
  });
130
129
  const { fullPath } = await createPagePromise;
131
- trackClientEvent("page_created", {
132
- projectId: project.id,
133
- pathSegment: values.value.pathSegment,
134
- layoutId: values.value.layoutId
135
- });
136
130
  previewStore.send({ type: "closeCreatePageModal" });
137
131
  form.reset();
138
132
  await new Promise(_temp2);
@@ -1,7 +1,7 @@
1
1
  import { useProjectSlug } from "../../../lib/auth.js";
2
2
  import { usePageBlocks } from "../../../lib/normalized-data.js";
3
- import { layoutQueries, projectQueries } from "../../../lib/queries.js";
4
3
  import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
4
+ import { layoutQueries, projectQueries } from "../../../lib/queries.js";
5
5
  import { previewStore, selectPreviewSource } from "../previewStore.js";
6
6
  import { PagePicker } from "./PagePicker.js";
7
7
  import { LayoutBlockItem } from "./PageTree.js";
@@ -16,10 +16,10 @@ import { PanelContent, PanelHeader } from "@camox/ui/panel";
16
16
  //#region src/features/preview/components/DerivedLayoutSidebar.tsx
17
17
  const EMPTY_PAGE = { blockIds: [] };
18
18
  function DerivedLayoutSidebar(t0) {
19
- const $ = c(32);
20
- if ($[0] !== "2c7da8bd37fd1558e1c31149d4435d439cdd1425cb374116d681960617531266") {
21
- for (let $i = 0; $i < 32; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
22
- $[0] = "2c7da8bd37fd1558e1c31149d4435d439cdd1425cb374116d681960617531266";
19
+ const $ = c(39);
20
+ if ($[0] !== "c2b47a0ded5e80952966193136846d2771f48746af4a761ba4e0ef778f954b27") {
21
+ for (let $i = 0; $i < 39; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
22
+ $[0] = "c2b47a0ded5e80952966193136846d2771f48746af4a761ba4e0ef778f954b27";
23
23
  }
24
24
  const { layout } = t0;
25
25
  const source = useSelector(previewStore, selectPreviewSource);
@@ -36,12 +36,14 @@ function DerivedLayoutSidebar(t0) {
36
36
  const app = useCamoxApp();
37
37
  let t2;
38
38
  if ($[3] !== app || $[4] !== layout.layoutId) {
39
- t2 = app.getLayoutById(layout.layoutId)?._internal.title ?? layout.layoutId;
39
+ t2 = app.getLayoutById(layout.layoutId);
40
40
  $[3] = app;
41
41
  $[4] = layout.layoutId;
42
42
  $[5] = t2;
43
43
  } else t2 = $[5];
44
- const layoutName = t2;
44
+ const definition = t2;
45
+ const layoutName = definition?._internal.title ?? layout.layoutId;
46
+ const singleton = definition?._internal.kind === "singleton";
45
47
  const projectSlug = useProjectSlug();
46
48
  let t3;
47
49
  if ($[6] !== projectSlug) {
@@ -132,28 +134,45 @@ function DerivedLayoutSidebar(t0) {
132
134
  $[24] = layoutName;
133
135
  $[25] = t11;
134
136
  } else t11 = $[25];
135
- let t12;
136
- if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
137
- t12 = /* @__PURE__ */ jsxs(Alert, { children: [/* @__PURE__ */ jsx(AlertTitle, { children: "Shared layout blocks" }), /* @__PURE__ */ jsx(AlertDescription, { children: "Changes apply to every page using this layout. The generated page content is managed outside the studio." })] });
138
- $[26] = t12;
139
- } else t12 = $[26];
137
+ const t12 = singleton ? "Code-owned page" : "Shared layout blocks";
140
138
  let t13;
141
- if ($[27] !== t11) {
142
- t13 = /* @__PURE__ */ jsxs(PanelContent, {
139
+ if ($[26] !== t12) {
140
+ t13 = /* @__PURE__ */ jsx(AlertTitle, { children: t12 });
141
+ $[26] = t12;
142
+ $[27] = t13;
143
+ } else t13 = $[27];
144
+ const t14 = singleton ? "Edit and publish this page’s blocks here. Its URL and structure are defined in code. Synced blocks share content with their other instances." : "Changes apply to every page using this layout. The generated page content is managed outside the studio.";
145
+ let t15;
146
+ if ($[28] !== t14) {
147
+ t15 = /* @__PURE__ */ jsx(AlertDescription, { children: t14 });
148
+ $[28] = t14;
149
+ $[29] = t15;
150
+ } else t15 = $[29];
151
+ let t16;
152
+ if ($[30] !== t13 || $[31] !== t15) {
153
+ t16 = /* @__PURE__ */ jsxs(Alert, { children: [t13, t15] });
154
+ $[30] = t13;
155
+ $[31] = t15;
156
+ $[32] = t16;
157
+ } else t16 = $[32];
158
+ let t17;
159
+ if ($[33] !== t11 || $[34] !== t16) {
160
+ t17 = /* @__PURE__ */ jsxs(PanelContent, {
143
161
  className: "flex grow basis-0 flex-col gap-4 overflow-auto p-2",
144
- children: [t11, t12]
162
+ children: [t11, t16]
145
163
  });
146
- $[27] = t11;
147
- $[28] = t13;
148
- } else t13 = $[28];
149
- let t14;
150
- if ($[29] !== t10 || $[30] !== t13) {
151
- t14 = /* @__PURE__ */ jsxs(Fragment, { children: [t10, t13] });
152
- $[29] = t10;
153
- $[30] = t13;
154
- $[31] = t14;
155
- } else t14 = $[31];
156
- return t14;
164
+ $[33] = t11;
165
+ $[34] = t16;
166
+ $[35] = t17;
167
+ } else t17 = $[35];
168
+ let t18;
169
+ if ($[36] !== t10 || $[37] !== t17) {
170
+ t18 = /* @__PURE__ */ jsxs(Fragment, { children: [t10, t17] });
171
+ $[36] = t10;
172
+ $[37] = t17;
173
+ $[38] = t18;
174
+ } else t18 = $[38];
175
+ return t18;
157
176
  }
158
177
 
159
178
  //#endregion