camox 0.24.1 → 0.26.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.
- package/dist/core/hooks/useRequireDraftSource.js +27 -0
- package/dist/features/preview/CamoxPreview.d.ts +4 -0
- package/dist/features/preview/CamoxPreview.js +454 -181
- package/dist/features/preview/components/AddBlockSheet.js +79 -75
- package/dist/features/preview/components/AssetLightbox.js +1 -1
- package/dist/features/preview/components/BlockActionsPopover.js +39 -22
- package/dist/features/preview/components/DraftSwitchDialog.js +66 -0
- package/dist/features/preview/components/EditPageModal.js +9 -9
- package/dist/features/preview/components/LinkFieldEditor.js +1 -1
- package/dist/features/preview/components/Overlays.js +6 -2
- package/dist/features/preview/components/PageContentSheet.js +222 -190
- package/dist/features/preview/components/PagePicker.js +81 -3
- package/dist/features/preview/components/PageTree.js +418 -327
- package/dist/features/preview/components/PreviewToolbar.js +172 -158
- package/dist/features/preview/components/PublishDialog.js +111 -0
- package/dist/features/preview/components/useRepeatableItemActions.js +26 -20
- package/dist/features/preview/components/useUpdateBlockPosition.js +10 -9
- package/dist/features/preview/previewStore.js +38 -1
- package/dist/features/provider/useAdminShortcuts.js +7 -2
- package/dist/features/routes/pageRoute.d.ts +6 -2
- package/dist/features/routes/pageRoute.js +10 -6
- package/dist/features/vite/vite.js +6 -5
- package/dist/lib/normalized-data.js +87 -88
- package/dist/lib/queries.js +12 -6
- package/dist/studio.css +1 -1
- package/package.json +4 -4
|
@@ -4,7 +4,7 @@ import { cn, getActionShortcut } from "../../../lib/utils.js";
|
|
|
4
4
|
import { c } from "react/compiler-runtime";
|
|
5
5
|
import { Kbd } from "@camox/ui/kbd";
|
|
6
6
|
import { useSelector } from "@xstate/store-react";
|
|
7
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Button } from "@camox/ui/button";
|
|
9
9
|
import * as Tooltip$1 from "@camox/ui/tooltip";
|
|
10
10
|
import { Lock, MonitorPlay, PanelRight, TabletSmartphone } from "lucide-react";
|
|
@@ -14,20 +14,21 @@ import { Toggle } from "@camox/ui/toggle";
|
|
|
14
14
|
|
|
15
15
|
//#region src/features/preview/components/PreviewToolbar.tsx
|
|
16
16
|
const PreviewToolbar = () => {
|
|
17
|
-
const $ = c(
|
|
18
|
-
if ($[0] !== "
|
|
19
|
-
for (let $i = 0; $i <
|
|
20
|
-
$[0] = "
|
|
17
|
+
const $ = c(70);
|
|
18
|
+
if ($[0] !== "3f4ab1b23a0c71433f448a6d697143e0a49bc26edf45de5fcefe147aab349d48") {
|
|
19
|
+
for (let $i = 0; $i < 70; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
20
|
+
$[0] = "3f4ab1b23a0c71433f448a6d697143e0a49bc26edf45de5fcefe147aab349d48";
|
|
21
21
|
}
|
|
22
22
|
const isEditingLocked = useSelector(previewStore, _temp);
|
|
23
23
|
const isEditingPanelOpen = useSelector(previewStore, _temp2);
|
|
24
24
|
const isPresentationMode = useSelector(previewStore, _temp3);
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
25
|
+
const isPreviewingNonDraft = useSelector(previewStore, _temp4) !== "draft";
|
|
26
|
+
const isPageContentSheetOpen = useSelector(previewStore, _temp5);
|
|
27
|
+
const isAddBlockSheetOpen = useSelector(previewStore, _temp6);
|
|
28
|
+
const isAgentChatSheetOpen = useSelector(previewStore, _temp7);
|
|
28
29
|
const isAnySideSheetOpen = isPageContentSheetOpen || isAddBlockSheetOpen || isAgentChatSheetOpen;
|
|
29
|
-
const actions = useSelector(actionsStore,
|
|
30
|
-
const isMobileMode = useSelector(previewStore,
|
|
30
|
+
const actions = useSelector(actionsStore, _temp8);
|
|
31
|
+
const isMobileMode = useSelector(previewStore, _temp9);
|
|
31
32
|
const t0 = isAnySideSheetOpen && "opacity-0 pointer-events-none translate-y-full";
|
|
32
33
|
let t1;
|
|
33
34
|
if ($[1] !== t0) {
|
|
@@ -43,7 +44,7 @@ const PreviewToolbar = () => {
|
|
|
43
44
|
"data-state": t2,
|
|
44
45
|
pressed: t3,
|
|
45
46
|
variant: "outline",
|
|
46
|
-
onClick:
|
|
47
|
+
onClick: _temp0
|
|
47
48
|
});
|
|
48
49
|
$[3] = t2;
|
|
49
50
|
$[4] = t3;
|
|
@@ -84,185 +85,195 @@ const PreviewToolbar = () => {
|
|
|
84
85
|
} else t9 = $[15];
|
|
85
86
|
const t10 = isEditingLocked ? "on" : "off";
|
|
86
87
|
let t11;
|
|
87
|
-
if ($[16] !== isEditingLocked || $[17] !== t10) {
|
|
88
|
+
if ($[16] !== isEditingLocked || $[17] !== isPreviewingNonDraft || $[18] !== t10) {
|
|
88
89
|
t11 = /* @__PURE__ */ jsx(Toggle, {
|
|
89
90
|
"data-state": t10,
|
|
90
91
|
pressed: isEditingLocked,
|
|
91
|
-
|
|
92
|
+
disabled: isPreviewingNonDraft,
|
|
93
|
+
onPressedChange: _temp1,
|
|
92
94
|
variant: "outline"
|
|
93
95
|
});
|
|
94
96
|
$[16] = isEditingLocked;
|
|
95
|
-
$[17] =
|
|
96
|
-
$[18] =
|
|
97
|
-
|
|
97
|
+
$[17] = isPreviewingNonDraft;
|
|
98
|
+
$[18] = t10;
|
|
99
|
+
$[19] = t11;
|
|
100
|
+
} else t11 = $[19];
|
|
98
101
|
let t12;
|
|
99
|
-
if ($[
|
|
102
|
+
if ($[20] === Symbol.for("react.memo_cache_sentinel")) {
|
|
100
103
|
t12 = /* @__PURE__ */ jsx(Lock, {});
|
|
101
|
-
$[
|
|
102
|
-
} else t12 = $[
|
|
104
|
+
$[20] = t12;
|
|
105
|
+
} else t12 = $[20];
|
|
103
106
|
let t13;
|
|
104
|
-
if ($[
|
|
107
|
+
if ($[21] !== t11) {
|
|
105
108
|
t13 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
|
|
106
109
|
render: t11,
|
|
107
110
|
children: t12
|
|
108
111
|
});
|
|
109
|
-
$[
|
|
110
|
-
$[
|
|
111
|
-
} else t13 = $[
|
|
112
|
+
$[21] = t11;
|
|
113
|
+
$[22] = t13;
|
|
114
|
+
} else t13 = $[22];
|
|
112
115
|
let t14;
|
|
113
|
-
if ($[
|
|
114
|
-
t14 = /* @__PURE__ */ jsxs(
|
|
115
|
-
$[
|
|
116
|
-
|
|
116
|
+
if ($[23] !== isPreviewingNonDraft) {
|
|
117
|
+
t14 = isPreviewingNonDraft ? "Switch to draft to edit" : /* @__PURE__ */ jsxs(Fragment, { children: ["Toggle edit mode ", /* @__PURE__ */ jsx(Kbd, { children: "L" })] });
|
|
118
|
+
$[23] = isPreviewingNonDraft;
|
|
119
|
+
$[24] = t14;
|
|
120
|
+
} else t14 = $[24];
|
|
117
121
|
let t15;
|
|
118
|
-
if ($[
|
|
119
|
-
t15 = /* @__PURE__ */
|
|
120
|
-
$[
|
|
121
|
-
$[
|
|
122
|
-
} else t15 = $[
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
if ($[25] !== t14) {
|
|
123
|
+
t15 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: t14 });
|
|
124
|
+
$[25] = t14;
|
|
125
|
+
$[26] = t15;
|
|
126
|
+
} else t15 = $[26];
|
|
127
|
+
let t16;
|
|
128
|
+
if ($[27] !== t13 || $[28] !== t15) {
|
|
129
|
+
t16 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t13, t15] });
|
|
130
|
+
$[27] = t13;
|
|
131
|
+
$[28] = t15;
|
|
132
|
+
$[29] = t16;
|
|
133
|
+
} else t16 = $[29];
|
|
134
|
+
const t17 = isMobileMode ? "on" : "off";
|
|
135
|
+
let t18;
|
|
136
|
+
if ($[30] !== isMobileMode || $[31] !== t17) {
|
|
137
|
+
t18 = /* @__PURE__ */ jsx(Toggle, {
|
|
138
|
+
"data-state": t17,
|
|
128
139
|
pressed: isMobileMode,
|
|
129
|
-
onPressedChange:
|
|
140
|
+
onPressedChange: _temp10,
|
|
130
141
|
variant: "outline"
|
|
131
142
|
});
|
|
132
|
-
$[
|
|
133
|
-
$[
|
|
134
|
-
$[
|
|
135
|
-
} else
|
|
136
|
-
let t18;
|
|
137
|
-
if ($[28] === Symbol.for("react.memo_cache_sentinel")) {
|
|
138
|
-
t18 = /* @__PURE__ */ jsx(TabletSmartphone, {});
|
|
139
|
-
$[28] = t18;
|
|
140
|
-
} else t18 = $[28];
|
|
143
|
+
$[30] = isMobileMode;
|
|
144
|
+
$[31] = t17;
|
|
145
|
+
$[32] = t18;
|
|
146
|
+
} else t18 = $[32];
|
|
141
147
|
let t19;
|
|
142
|
-
if ($[
|
|
143
|
-
t19 = /* @__PURE__ */ jsx(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
147
|
-
$[29] = t17;
|
|
148
|
-
$[30] = t19;
|
|
149
|
-
} else t19 = $[30];
|
|
148
|
+
if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
|
|
149
|
+
t19 = /* @__PURE__ */ jsx(TabletSmartphone, {});
|
|
150
|
+
$[33] = t19;
|
|
151
|
+
} else t19 = $[33];
|
|
150
152
|
let t20;
|
|
151
|
-
if ($[
|
|
152
|
-
t20 =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
if ($[34] !== t18) {
|
|
154
|
+
t20 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
|
|
155
|
+
render: t18,
|
|
156
|
+
children: t19
|
|
157
|
+
});
|
|
158
|
+
$[34] = t18;
|
|
159
|
+
$[35] = t20;
|
|
160
|
+
} else t20 = $[35];
|
|
156
161
|
let t21;
|
|
157
|
-
if ($[
|
|
158
|
-
t21 =
|
|
159
|
-
$[
|
|
160
|
-
$[
|
|
161
|
-
} else t21 = $[
|
|
162
|
+
if ($[36] !== actions) {
|
|
163
|
+
t21 = getActionShortcut(actions, "toggle-mobile-mode");
|
|
164
|
+
$[36] = actions;
|
|
165
|
+
$[37] = t21;
|
|
166
|
+
} else t21 = $[37];
|
|
162
167
|
let t22;
|
|
163
|
-
if ($[
|
|
164
|
-
t22 = /* @__PURE__ */ jsxs(Tooltip$1.
|
|
165
|
-
$[
|
|
166
|
-
$[
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
168
|
+
if ($[38] !== t21) {
|
|
169
|
+
t22 = /* @__PURE__ */ jsxs(Tooltip$1.TooltipContent, { children: ["Toggle mobile layout ", t21] });
|
|
170
|
+
$[38] = t21;
|
|
171
|
+
$[39] = t22;
|
|
172
|
+
} else t22 = $[39];
|
|
173
|
+
let t23;
|
|
174
|
+
if ($[40] !== t20 || $[41] !== t22) {
|
|
175
|
+
t23 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t20, t22] });
|
|
176
|
+
$[40] = t20;
|
|
177
|
+
$[41] = t22;
|
|
178
|
+
$[42] = t23;
|
|
179
|
+
} else t23 = $[42];
|
|
180
|
+
const t24 = isPresentationMode ? "on" : "off";
|
|
181
|
+
let t25;
|
|
182
|
+
if ($[43] !== isPresentationMode || $[44] !== t24) {
|
|
183
|
+
t25 = /* @__PURE__ */ jsx(Toggle, {
|
|
184
|
+
"data-state": t24,
|
|
174
185
|
pressed: isPresentationMode,
|
|
175
186
|
variant: "outline",
|
|
176
|
-
onClick:
|
|
187
|
+
onClick: _temp11
|
|
177
188
|
});
|
|
178
|
-
$[
|
|
179
|
-
$[
|
|
180
|
-
$[
|
|
181
|
-
} else
|
|
182
|
-
let t25;
|
|
183
|
-
if ($[41] === Symbol.for("react.memo_cache_sentinel")) {
|
|
184
|
-
t25 = /* @__PURE__ */ jsx(MonitorPlay, {});
|
|
185
|
-
$[41] = t25;
|
|
186
|
-
} else t25 = $[41];
|
|
189
|
+
$[43] = isPresentationMode;
|
|
190
|
+
$[44] = t24;
|
|
191
|
+
$[45] = t25;
|
|
192
|
+
} else t25 = $[45];
|
|
187
193
|
let t26;
|
|
188
|
-
if ($[
|
|
189
|
-
t26 = /* @__PURE__ */
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
});
|
|
193
|
-
$[42] = t24;
|
|
194
|
-
$[43] = t26;
|
|
195
|
-
} else t26 = $[43];
|
|
194
|
+
if ($[46] === Symbol.for("react.memo_cache_sentinel")) {
|
|
195
|
+
t26 = /* @__PURE__ */ jsx(MonitorPlay, {});
|
|
196
|
+
$[46] = t26;
|
|
197
|
+
} else t26 = $[46];
|
|
196
198
|
let t27;
|
|
197
|
-
if ($[
|
|
198
|
-
t27 =
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
if ($[47] !== t25) {
|
|
200
|
+
t27 = /* @__PURE__ */ jsxs(Tooltip$1.TooltipTrigger, {
|
|
201
|
+
render: t25,
|
|
202
|
+
children: [t26, "Preview"]
|
|
203
|
+
});
|
|
204
|
+
$[47] = t25;
|
|
205
|
+
$[48] = t27;
|
|
206
|
+
} else t27 = $[48];
|
|
202
207
|
let t28;
|
|
203
|
-
if ($[
|
|
204
|
-
t28 =
|
|
205
|
-
$[
|
|
206
|
-
$[
|
|
207
|
-
} else t28 = $[
|
|
208
|
+
if ($[49] !== actions) {
|
|
209
|
+
t28 = getActionShortcut(actions, "enter-presentation-mode");
|
|
210
|
+
$[49] = actions;
|
|
211
|
+
$[50] = t28;
|
|
212
|
+
} else t28 = $[50];
|
|
208
213
|
let t29;
|
|
209
|
-
if ($[
|
|
210
|
-
t29 = /* @__PURE__ */ jsxs(Tooltip$1.
|
|
211
|
-
$[
|
|
212
|
-
$[
|
|
213
|
-
|
|
214
|
-
} else t29 = $[50];
|
|
214
|
+
if ($[51] !== t28) {
|
|
215
|
+
t29 = /* @__PURE__ */ jsxs(Tooltip$1.TooltipContent, { children: ["Hide Camox Studio ", t28] });
|
|
216
|
+
$[51] = t28;
|
|
217
|
+
$[52] = t29;
|
|
218
|
+
} else t29 = $[52];
|
|
215
219
|
let t30;
|
|
216
|
-
if ($[
|
|
217
|
-
t30 = /* @__PURE__ */ jsxs(
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
t22,
|
|
221
|
-
t29
|
|
222
|
-
] });
|
|
223
|
-
$[51] = t15;
|
|
224
|
-
$[52] = t22;
|
|
225
|
-
$[53] = t29;
|
|
226
|
-
$[54] = t9;
|
|
220
|
+
if ($[53] !== t27 || $[54] !== t29) {
|
|
221
|
+
t30 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t27, t29] });
|
|
222
|
+
$[53] = t27;
|
|
223
|
+
$[54] = t29;
|
|
227
224
|
$[55] = t30;
|
|
228
225
|
} else t30 = $[55];
|
|
229
226
|
let t31;
|
|
230
|
-
if ($[56]
|
|
231
|
-
t31 = /* @__PURE__ */
|
|
227
|
+
if ($[56] !== t16 || $[57] !== t23 || $[58] !== t30 || $[59] !== t9) {
|
|
228
|
+
t31 = /* @__PURE__ */ jsxs(ButtonGroup, { children: [
|
|
229
|
+
t9,
|
|
230
|
+
t16,
|
|
231
|
+
t23,
|
|
232
|
+
t30
|
|
233
|
+
] });
|
|
234
|
+
$[56] = t16;
|
|
235
|
+
$[57] = t23;
|
|
236
|
+
$[58] = t30;
|
|
237
|
+
$[59] = t9;
|
|
238
|
+
$[60] = t31;
|
|
239
|
+
} else t31 = $[60];
|
|
240
|
+
let t32;
|
|
241
|
+
if ($[61] === Symbol.for("react.memo_cache_sentinel")) {
|
|
242
|
+
t32 = /* @__PURE__ */ jsx("span", {
|
|
232
243
|
className: "text-muted-foreground",
|
|
233
244
|
children: "Ask for changes..."
|
|
234
245
|
});
|
|
235
|
-
$[
|
|
236
|
-
} else
|
|
237
|
-
let t32;
|
|
238
|
-
if ($[57] !== actions) {
|
|
239
|
-
t32 = getActionShortcut(actions, "open-agent-chat");
|
|
240
|
-
$[57] = actions;
|
|
241
|
-
$[58] = t32;
|
|
242
|
-
} else t32 = $[58];
|
|
246
|
+
$[61] = t32;
|
|
247
|
+
} else t32 = $[61];
|
|
243
248
|
let t33;
|
|
244
|
-
if ($[
|
|
245
|
-
t33 =
|
|
249
|
+
if ($[62] !== actions) {
|
|
250
|
+
t33 = getActionShortcut(actions, "open-agent-chat");
|
|
251
|
+
$[62] = actions;
|
|
252
|
+
$[63] = t33;
|
|
253
|
+
} else t33 = $[63];
|
|
254
|
+
let t34;
|
|
255
|
+
if ($[64] !== t33) {
|
|
256
|
+
t34 = /* @__PURE__ */ jsxs(Button, {
|
|
246
257
|
variant: "outline",
|
|
247
258
|
className: "bg-transparent dark:bg-transparent",
|
|
248
|
-
onClick:
|
|
249
|
-
children: [
|
|
259
|
+
onClick: _temp12,
|
|
260
|
+
children: [t32, t33]
|
|
250
261
|
});
|
|
251
|
-
$[
|
|
252
|
-
$[
|
|
253
|
-
} else
|
|
254
|
-
let
|
|
255
|
-
if ($[
|
|
256
|
-
|
|
262
|
+
$[64] = t33;
|
|
263
|
+
$[65] = t34;
|
|
264
|
+
} else t34 = $[65];
|
|
265
|
+
let t35;
|
|
266
|
+
if ($[66] !== t1 || $[67] !== t31 || $[68] !== t34) {
|
|
267
|
+
t35 = /* @__PURE__ */ jsxs(FloatingToolbar, {
|
|
257
268
|
className: t1,
|
|
258
|
-
children: [
|
|
269
|
+
children: [t31, t34]
|
|
259
270
|
});
|
|
260
|
-
$[
|
|
261
|
-
$[
|
|
262
|
-
$[
|
|
263
|
-
$[
|
|
264
|
-
} else
|
|
265
|
-
return
|
|
271
|
+
$[66] = t1;
|
|
272
|
+
$[67] = t31;
|
|
273
|
+
$[68] = t34;
|
|
274
|
+
$[69] = t35;
|
|
275
|
+
} else t35 = $[69];
|
|
276
|
+
return t35;
|
|
266
277
|
};
|
|
267
278
|
function _temp(state) {
|
|
268
279
|
return state.context.isContentLocked;
|
|
@@ -274,33 +285,36 @@ function _temp3(state_1) {
|
|
|
274
285
|
return state_1.context.isPresentationMode;
|
|
275
286
|
}
|
|
276
287
|
function _temp4(state_2) {
|
|
277
|
-
return state_2.context.
|
|
288
|
+
return state_2.context.previewSource;
|
|
278
289
|
}
|
|
279
290
|
function _temp5(state_3) {
|
|
280
|
-
return state_3.context.
|
|
291
|
+
return state_3.context.isPageContentSheetOpen;
|
|
281
292
|
}
|
|
282
293
|
function _temp6(state_4) {
|
|
283
|
-
return state_4.context.
|
|
294
|
+
return state_4.context.isAddBlockSheetOpen;
|
|
284
295
|
}
|
|
285
296
|
function _temp7(state_5) {
|
|
286
|
-
return state_5.context.
|
|
297
|
+
return state_5.context.isAgentChatSheetOpen;
|
|
287
298
|
}
|
|
288
299
|
function _temp8(state_6) {
|
|
289
|
-
return state_6.context.
|
|
300
|
+
return state_6.context.actions;
|
|
290
301
|
}
|
|
291
|
-
function _temp9() {
|
|
292
|
-
return
|
|
302
|
+
function _temp9(state_7) {
|
|
303
|
+
return state_7.context.isMobileMode;
|
|
293
304
|
}
|
|
294
305
|
function _temp0() {
|
|
295
|
-
return previewStore.send({ type: "
|
|
306
|
+
return previewStore.send({ type: "toggleSidebar" });
|
|
296
307
|
}
|
|
297
308
|
function _temp1() {
|
|
298
|
-
return previewStore.send({ type: "
|
|
309
|
+
return previewStore.send({ type: "toggleLockContent" });
|
|
299
310
|
}
|
|
300
311
|
function _temp10() {
|
|
301
|
-
return previewStore.send({ type: "
|
|
312
|
+
return previewStore.send({ type: "toggleMobileMode" });
|
|
302
313
|
}
|
|
303
314
|
function _temp11() {
|
|
315
|
+
return previewStore.send({ type: "enterPresentationMode" });
|
|
316
|
+
}
|
|
317
|
+
function _temp12() {
|
|
304
318
|
return previewStore.send({ type: "openAgentChatSheet" });
|
|
305
319
|
}
|
|
306
320
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { trackClientEvent } from "../../../lib/telemetry-client.js";
|
|
2
|
+
import { pageMutations } from "../../../lib/queries.js";
|
|
3
|
+
import { Label } from "@camox/ui/label";
|
|
4
|
+
import { toast } from "@camox/ui/toaster";
|
|
5
|
+
import { useMutation } from "@tanstack/react-query";
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { Switch } from "@camox/ui/switch";
|
|
9
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@camox/ui/alert-dialog";
|
|
10
|
+
|
|
11
|
+
//#region src/features/preview/components/PublishDialog.tsx
|
|
12
|
+
/**
|
|
13
|
+
* Confirmation dialog for `pages.publish`. Shows the path that will go live
|
|
14
|
+
* (= the current draft path; same as today's public URL unless the user
|
|
15
|
+
* changed it while drafting), and a primary Publish button.
|
|
16
|
+
*
|
|
17
|
+
* Description copy branches on the page's current status: a `'draft'` page
|
|
18
|
+
* has never been public so we frame it as "will go live"; a `'modified'`
|
|
19
|
+
* page is already public and we're promoting the latest edits.
|
|
20
|
+
*
|
|
21
|
+
* When the page's layout is itself modified (`alsoPublishLayout` prop set),
|
|
22
|
+
* a toggle appears below the primary action, pre-checked. Bundling is the
|
|
23
|
+
* common case — the user is usually editing page + layout together and
|
|
24
|
+
* expects "Publish" to mean "what I see goes live". Power users who edited
|
|
25
|
+
* the layout independently can opt out before confirming.
|
|
26
|
+
*/
|
|
27
|
+
function PublishDialog({ page, pageStatus, alsoPublishLayout, open, onOpenChange }) {
|
|
28
|
+
const publishPage = useMutation(pageMutations.publish());
|
|
29
|
+
const [bundleLayout, setBundleLayout] = React.useState(true);
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
if (open) setBundleLayout(true);
|
|
32
|
+
}, [open]);
|
|
33
|
+
const handlePublish = async () => {
|
|
34
|
+
if (!page) return;
|
|
35
|
+
const shouldBundle = bundleLayout && alsoPublishLayout != null;
|
|
36
|
+
try {
|
|
37
|
+
await publishPage.mutateAsync({
|
|
38
|
+
id: page.id,
|
|
39
|
+
...shouldBundle ? { alsoPublishLayout: true } : {}
|
|
40
|
+
});
|
|
41
|
+
trackClientEvent("page_published", {
|
|
42
|
+
pageId: page.id,
|
|
43
|
+
...shouldBundle ? { alsoPublishedLayout: true } : {}
|
|
44
|
+
});
|
|
45
|
+
toast.success(shouldBundle ? `Published this page and layout ${alsoPublishLayout?.layoutHandle}` : "Published this page");
|
|
46
|
+
onOpenChange(false);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error("Failed to publish page:", error);
|
|
49
|
+
toast.error("Could not publish this page");
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const pathCode = /* @__PURE__ */ jsx("code", {
|
|
53
|
+
className: "bg-muted rounded px-1 py-0.5 font-mono text-xs",
|
|
54
|
+
children: page?.fullPath ?? ""
|
|
55
|
+
});
|
|
56
|
+
return /* @__PURE__ */ jsx(AlertDialog, {
|
|
57
|
+
open,
|
|
58
|
+
onOpenChange,
|
|
59
|
+
children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
|
|
60
|
+
/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [/* @__PURE__ */ jsx(AlertDialogTitle, { children: pageStatus === "modified" ? "Publish changes" : "Publish page" }), /* @__PURE__ */ jsx(AlertDialogDescription, { children: pageStatus === "modified" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
61
|
+
"Visitors at ",
|
|
62
|
+
pathCode,
|
|
63
|
+
" will start seeing your latest changes."
|
|
64
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
65
|
+
"This page will go live at ",
|
|
66
|
+
pathCode,
|
|
67
|
+
". Visitors will see the current draft."
|
|
68
|
+
] }) })] }),
|
|
69
|
+
alsoPublishLayout && /* @__PURE__ */ jsxs("div", {
|
|
70
|
+
className: "flex items-start gap-3",
|
|
71
|
+
children: [/* @__PURE__ */ jsx(Switch, {
|
|
72
|
+
id: "also-publish-layout",
|
|
73
|
+
checked: bundleLayout,
|
|
74
|
+
onCheckedChange: (checked) => setBundleLayout(checked),
|
|
75
|
+
disabled: publishPage.isPending
|
|
76
|
+
}), /* @__PURE__ */ jsxs(Label, {
|
|
77
|
+
htmlFor: "also-publish-layout",
|
|
78
|
+
className: "flex flex-col items-start gap-1",
|
|
79
|
+
children: [/* @__PURE__ */ jsxs("span", { children: [
|
|
80
|
+
"Also publish layout",
|
|
81
|
+
" ",
|
|
82
|
+
/* @__PURE__ */ jsx("code", {
|
|
83
|
+
className: "bg-muted rounded px-1 py-0.5 font-mono text-xs",
|
|
84
|
+
children: alsoPublishLayout.layoutHandle
|
|
85
|
+
})
|
|
86
|
+
] }), /* @__PURE__ */ jsx("span", {
|
|
87
|
+
className: "text-muted-foreground text-xs font-normal",
|
|
88
|
+
children: (() => {
|
|
89
|
+
const others = Math.max(0, alsoPublishLayout.affectedPagesCount - 1);
|
|
90
|
+
if (others === 0) return "Affects no other pages";
|
|
91
|
+
return `Affects ${others} other ${others === 1 ? "page" : "pages"}`;
|
|
92
|
+
})()
|
|
93
|
+
})]
|
|
94
|
+
})]
|
|
95
|
+
}),
|
|
96
|
+
/* @__PURE__ */ jsxs(AlertDialogFooter, { children: [/* @__PURE__ */ jsx(AlertDialogCancel, {
|
|
97
|
+
variant: "outline",
|
|
98
|
+
size: "default",
|
|
99
|
+
disabled: publishPage.isPending,
|
|
100
|
+
children: "Cancel"
|
|
101
|
+
}), /* @__PURE__ */ jsx(AlertDialogAction, {
|
|
102
|
+
onClick: handlePublish,
|
|
103
|
+
disabled: publishPage.isPending,
|
|
104
|
+
children: publishPage.isPending ? "Publishing…" : "Publish"
|
|
105
|
+
})] })
|
|
106
|
+
] })
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//#endregion
|
|
111
|
+
export { PublishDialog };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { previewStore } from "../previewStore.js";
|
|
2
2
|
import { blockQueries, repeatableItemMutations } from "../../../lib/queries.js";
|
|
3
3
|
import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
|
|
4
|
+
import { useRequireDraftSource } from "../../../core/hooks/useRequireDraftSource.js";
|
|
4
5
|
import { c } from "react/compiler-runtime";
|
|
5
6
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
6
7
|
import { generateKeyBetween } from "fractional-indexing";
|
|
@@ -50,10 +51,10 @@ const buildNestedItemSeeds = (itemProperties) => {
|
|
|
50
51
|
return seeds;
|
|
51
52
|
};
|
|
52
53
|
const useRepeatableItemActions = (t0) => {
|
|
53
|
-
const $ = c(
|
|
54
|
-
if ($[0] !== "
|
|
55
|
-
for (let $i = 0; $i <
|
|
56
|
-
$[0] = "
|
|
54
|
+
const $ = c(18);
|
|
55
|
+
if ($[0] !== "16e9f8f4b1a1e8d41d093c0930e510d6bea72e481f78c01b1ca1e595bec9f4cb") {
|
|
56
|
+
for (let $i = 0; $i < 18; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
57
|
+
$[0] = "16e9f8f4b1a1e8d41d093c0930e510d6bea72e481f78c01b1ca1e595bec9f4cb";
|
|
57
58
|
}
|
|
58
59
|
const { blockId, fieldName, parentItemId, arraySchema, siblingCount } = t0;
|
|
59
60
|
let t1;
|
|
@@ -68,12 +69,14 @@ const useRepeatableItemActions = (t0) => {
|
|
|
68
69
|
$[2] = t2;
|
|
69
70
|
} else t2 = $[2];
|
|
70
71
|
const deleteRepeatableItem = useMutation(t2);
|
|
72
|
+
const requireDraft = useRequireDraftSource();
|
|
71
73
|
const canAdd = arraySchema != null && (arraySchema.maxItems === void 0 || siblingCount < arraySchema.maxItems);
|
|
72
74
|
const canRemove = arraySchema != null && (arraySchema.minItems === void 0 || siblingCount > arraySchema.minItems);
|
|
73
75
|
let t3;
|
|
74
|
-
if ($[3] !== arraySchema || $[4] !== blockId || $[5] !== createRepeatableItem || $[6] !== fieldName || $[7] !== parentItemId) {
|
|
76
|
+
if ($[3] !== arraySchema || $[4] !== blockId || $[5] !== createRepeatableItem || $[6] !== fieldName || $[7] !== parentItemId || $[8] !== requireDraft) {
|
|
75
77
|
t3 = (options) => {
|
|
76
78
|
if (!arraySchema) return;
|
|
79
|
+
if (!requireDraft()) return;
|
|
77
80
|
const itemsSchema = arraySchema.items;
|
|
78
81
|
const defaultContent = buildDefaultContent(itemsSchema?.properties);
|
|
79
82
|
const defaultSettings = arraySchema.defaultItemSettings;
|
|
@@ -99,32 +102,35 @@ const useRepeatableItemActions = (t0) => {
|
|
|
99
102
|
$[5] = createRepeatableItem;
|
|
100
103
|
$[6] = fieldName;
|
|
101
104
|
$[7] = parentItemId;
|
|
102
|
-
$[8] =
|
|
103
|
-
|
|
105
|
+
$[8] = requireDraft;
|
|
106
|
+
$[9] = t3;
|
|
107
|
+
} else t3 = $[9];
|
|
104
108
|
const addItem = t3;
|
|
105
109
|
let t4;
|
|
106
|
-
if ($[
|
|
110
|
+
if ($[10] !== deleteRepeatableItem || $[11] !== requireDraft) {
|
|
107
111
|
t4 = (itemId, options_0) => {
|
|
112
|
+
if (!requireDraft()) return;
|
|
108
113
|
deleteRepeatableItem.mutate({ id: itemId }, { onSuccess: options_0?.onSuccess });
|
|
109
114
|
};
|
|
110
|
-
$[
|
|
111
|
-
$[
|
|
112
|
-
|
|
115
|
+
$[10] = deleteRepeatableItem;
|
|
116
|
+
$[11] = requireDraft;
|
|
117
|
+
$[12] = t4;
|
|
118
|
+
} else t4 = $[12];
|
|
113
119
|
const removeItem = t4;
|
|
114
120
|
let t5;
|
|
115
|
-
if ($[
|
|
121
|
+
if ($[13] !== addItem || $[14] !== canAdd || $[15] !== canRemove || $[16] !== removeItem) {
|
|
116
122
|
t5 = {
|
|
117
123
|
canAdd,
|
|
118
124
|
addItem,
|
|
119
125
|
canRemove,
|
|
120
126
|
removeItem
|
|
121
127
|
};
|
|
122
|
-
$[
|
|
123
|
-
$[
|
|
124
|
-
$[
|
|
125
|
-
$[
|
|
126
|
-
$[
|
|
127
|
-
} else t5 = $[
|
|
128
|
+
$[13] = addItem;
|
|
129
|
+
$[14] = canAdd;
|
|
130
|
+
$[15] = canRemove;
|
|
131
|
+
$[16] = removeItem;
|
|
132
|
+
$[17] = t5;
|
|
133
|
+
} else t5 = $[17];
|
|
128
134
|
return t5;
|
|
129
135
|
};
|
|
130
136
|
const getArraySchemaForItem = (contentSchema, itemId, itemsMap) => {
|
|
@@ -151,9 +157,9 @@ const getArraySchemaForItem = (contentSchema, itemId, itemsMap) => {
|
|
|
151
157
|
*/
|
|
152
158
|
const useCurrentItemActions = (blockId, itemId) => {
|
|
153
159
|
const $ = c(27);
|
|
154
|
-
if ($[0] !== "
|
|
160
|
+
if ($[0] !== "16e9f8f4b1a1e8d41d093c0930e510d6bea72e481f78c01b1ca1e595bec9f4cb") {
|
|
155
161
|
for (let $i = 0; $i < 27; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
156
|
-
$[0] = "
|
|
162
|
+
$[0] = "16e9f8f4b1a1e8d41d093c0930e510d6bea72e481f78c01b1ca1e595bec9f4cb";
|
|
157
163
|
}
|
|
158
164
|
const camoxApp = useCamoxApp();
|
|
159
165
|
let t0;
|