camox 0.79.0 → 0.81.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/lib/artifact.d.ts +26 -1
- package/dist/core/lib/artifactData.d.ts +5 -1
- package/dist/core/lib/artifactHost.d.ts +43 -0
- package/dist/features/brand/BrandPart.js +116 -0
- package/dist/features/brand/CamoxBrand.js +758 -0
- package/dist/features/brand/VoiceGroup.js +443 -0
- package/dist/features/preview/EditablePageExperience.js +2 -2
- package/dist/features/runtime/artifactReplay.d.ts +3 -0
- package/dist/features/runtime/artifactReplay.js +4 -0
- package/dist/features/runtime/runtime.d.ts +1 -1
- package/dist/features/runtime/runtime.js +4 -4
- package/dist/features/studio/components/DraftReview.js +8 -8
- package/dist/features/studio/components/Navbar.js +9 -7
- package/dist/features/studio/routes.js +3 -3
- package/dist/lib/queries.js +7 -7
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +8 -4
- package/dist/features/memory/CamoxMemory.js +0 -756
- package/dist/features/memory/VoiceGroup.js +0 -350
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
import { useDraftScope } from "../../lib/draft-scope.js";
|
|
2
|
+
import { useNavigate } from "../navigation/navigation.js";
|
|
3
|
+
import { reads, useReadQuery, useStudioCache } from "../../lib/studio-reads.js";
|
|
4
|
+
import { cn } from "../../lib/utils.js";
|
|
5
|
+
import { brandMutations } from "../../lib/queries.js";
|
|
6
|
+
import { previewStore } from "../preview/previewStore.js";
|
|
7
|
+
import { useWebsiteHref } from "../studio/components/Navbar.js";
|
|
8
|
+
import { BrandPart } from "./BrandPart.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 { Skeleton } from "@camox/ui/skeleton";
|
|
15
|
+
import { Spinner } from "@camox/ui/spinner";
|
|
16
|
+
import { Slider } from "@base-ui/react/slider";
|
|
17
|
+
import { VOICE_AXES } from "@camox/api-contract/voice";
|
|
18
|
+
|
|
19
|
+
//#region src/features/brand/VoiceGroup.tsx
|
|
20
|
+
/**
|
|
21
|
+
* The Voice group, at the top of the Brand Section (ADR 0051): a slider per Voice Axis, showing
|
|
22
|
+
* its chosen step and that step's definition, as models read it. Moving sliders saves nothing:
|
|
23
|
+
* Save shows while they differ from the saved Voice, and saves every moved axis as one change.
|
|
24
|
+
* Like any edit to the brand, saving while viewing Live starts a draft. "Save and rewrite", beside it,
|
|
25
|
+
* also asks Camox's agent, as the member, to rewrite the site's copy in the new Voice, and shows
|
|
26
|
+
* the draft with its thread beside the Canvas, where the rewrite happens.
|
|
27
|
+
*/
|
|
28
|
+
function VoiceGroup(t0) {
|
|
29
|
+
const $ = c(37);
|
|
30
|
+
const { projectId } = t0;
|
|
31
|
+
let t1;
|
|
32
|
+
if ($[0] !== projectId) {
|
|
33
|
+
t1 = reads.voice({ projectId });
|
|
34
|
+
$[0] = projectId;
|
|
35
|
+
$[1] = t1;
|
|
36
|
+
} else t1 = $[1];
|
|
37
|
+
const { data: saved } = useReadQuery(t1);
|
|
38
|
+
let t2;
|
|
39
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
40
|
+
t2 = {};
|
|
41
|
+
$[2] = t2;
|
|
42
|
+
} else t2 = $[2];
|
|
43
|
+
const [moved, setMoved] = React.useState(t2);
|
|
44
|
+
const cache = useStudioCache();
|
|
45
|
+
const draftScope = useDraftScope();
|
|
46
|
+
const navigate = useNavigate();
|
|
47
|
+
const websiteHref = useWebsiteHref();
|
|
48
|
+
const heading = React.useRef(null);
|
|
49
|
+
const actions = React.useRef(null);
|
|
50
|
+
const [justSaved, setJustSaved] = React.useState(false);
|
|
51
|
+
let t3;
|
|
52
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
53
|
+
t3 = brandMutations.saveVoice();
|
|
54
|
+
$[3] = t3;
|
|
55
|
+
} else t3 = $[3];
|
|
56
|
+
let t4;
|
|
57
|
+
if ($[4] !== cache || $[5] !== draftScope || $[6] !== navigate || $[7] !== projectId || $[8] !== websiteHref) {
|
|
58
|
+
t4 = {
|
|
59
|
+
...t3,
|
|
60
|
+
onSuccess: (_voice, t5) => {
|
|
61
|
+
const { rewrite } = t5;
|
|
62
|
+
const focused = document.activeElement;
|
|
63
|
+
const focusWasOnSave = !focused || focused === document.body || actions.current?.contains(focused);
|
|
64
|
+
setMoved({});
|
|
65
|
+
cache.invalidate(reads.voice({ projectId }));
|
|
66
|
+
if (!rewrite) {
|
|
67
|
+
setJustSaved(true);
|
|
68
|
+
if (focusWasOnSave) heading.current?.focus();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
previewStore.send({ type: "showCanvas" });
|
|
72
|
+
navigate({
|
|
73
|
+
to: websiteHref(),
|
|
74
|
+
draft: draftScope.current() ?? void 0
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
$[4] = cache;
|
|
79
|
+
$[5] = draftScope;
|
|
80
|
+
$[6] = navigate;
|
|
81
|
+
$[7] = projectId;
|
|
82
|
+
$[8] = websiteHref;
|
|
83
|
+
$[9] = t4;
|
|
84
|
+
} else t4 = $[9];
|
|
85
|
+
const save = useMutation(t4);
|
|
86
|
+
let t5;
|
|
87
|
+
if ($[10] !== moved || $[11] !== saved) {
|
|
88
|
+
t5 = saved && {
|
|
89
|
+
...saved,
|
|
90
|
+
...moved
|
|
91
|
+
};
|
|
92
|
+
$[10] = moved;
|
|
93
|
+
$[11] = saved;
|
|
94
|
+
$[12] = t5;
|
|
95
|
+
} else t5 = $[12];
|
|
96
|
+
const voice = t5;
|
|
97
|
+
let t6;
|
|
98
|
+
if ($[13] !== saved || $[14] !== voice) {
|
|
99
|
+
t6 = saved && voice ? changedAxes(saved, voice) : {};
|
|
100
|
+
$[13] = saved;
|
|
101
|
+
$[14] = voice;
|
|
102
|
+
$[15] = t6;
|
|
103
|
+
} else t6 = $[15];
|
|
104
|
+
const changed = t6;
|
|
105
|
+
let t7;
|
|
106
|
+
if ($[16] !== changed) {
|
|
107
|
+
t7 = Object.keys(changed);
|
|
108
|
+
$[16] = changed;
|
|
109
|
+
$[17] = t7;
|
|
110
|
+
} else t7 = $[17];
|
|
111
|
+
const dirty = t7.length > 0;
|
|
112
|
+
const t8 = dirty ? "The Voice has unsaved changes." : justSaved ? "Voice saved." : "";
|
|
113
|
+
let t9;
|
|
114
|
+
if ($[18] !== t8) {
|
|
115
|
+
t9 = /* @__PURE__ */ jsx("p", {
|
|
116
|
+
role: "status",
|
|
117
|
+
className: "sr-only",
|
|
118
|
+
children: t8
|
|
119
|
+
});
|
|
120
|
+
$[18] = t8;
|
|
121
|
+
$[19] = t9;
|
|
122
|
+
} else t9 = $[19];
|
|
123
|
+
let t10;
|
|
124
|
+
if ($[20] !== changed || $[21] !== dirty || $[22] !== projectId || $[23] !== save) {
|
|
125
|
+
t10 = dirty && /* @__PURE__ */ jsxs("div", {
|
|
126
|
+
className: "flex flex-wrap gap-2",
|
|
127
|
+
children: [/* @__PURE__ */ jsxs(Button, {
|
|
128
|
+
disabled: save.isPending,
|
|
129
|
+
onClick: () => save.mutate({
|
|
130
|
+
projectId,
|
|
131
|
+
steps: changed
|
|
132
|
+
}),
|
|
133
|
+
children: [save.isPending && !save.variables?.rewrite && /* @__PURE__ */ jsx(Spinner, {}), "Save"]
|
|
134
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
135
|
+
variant: "outline",
|
|
136
|
+
disabled: save.isPending,
|
|
137
|
+
onClick: () => save.mutate({
|
|
138
|
+
projectId,
|
|
139
|
+
steps: changed,
|
|
140
|
+
rewrite: true
|
|
141
|
+
}),
|
|
142
|
+
children: [save.isPending && save.variables?.rewrite && /* @__PURE__ */ jsx(Spinner, {}), "Save and rewrite"]
|
|
143
|
+
})]
|
|
144
|
+
});
|
|
145
|
+
$[20] = changed;
|
|
146
|
+
$[21] = dirty;
|
|
147
|
+
$[22] = projectId;
|
|
148
|
+
$[23] = save;
|
|
149
|
+
$[24] = t10;
|
|
150
|
+
} else t10 = $[24];
|
|
151
|
+
let t11;
|
|
152
|
+
if ($[25] !== save.error) {
|
|
153
|
+
t11 = save.error && /* @__PURE__ */ jsx("p", {
|
|
154
|
+
"data-voice-error": true,
|
|
155
|
+
role: "alert",
|
|
156
|
+
className: "text-destructive text-xs",
|
|
157
|
+
children: save.error.message
|
|
158
|
+
});
|
|
159
|
+
$[25] = save.error;
|
|
160
|
+
$[26] = t11;
|
|
161
|
+
} else t11 = $[26];
|
|
162
|
+
let t12;
|
|
163
|
+
if ($[27] !== t10 || $[28] !== t11 || $[29] !== t9) {
|
|
164
|
+
t12 = /* @__PURE__ */ jsxs("div", {
|
|
165
|
+
ref: actions,
|
|
166
|
+
className: "flex flex-col items-start gap-3",
|
|
167
|
+
children: [
|
|
168
|
+
t9,
|
|
169
|
+
t10,
|
|
170
|
+
t11
|
|
171
|
+
]
|
|
172
|
+
});
|
|
173
|
+
$[27] = t10;
|
|
174
|
+
$[28] = t11;
|
|
175
|
+
$[29] = t9;
|
|
176
|
+
$[30] = t12;
|
|
177
|
+
} else t12 = $[30];
|
|
178
|
+
let t13;
|
|
179
|
+
if ($[31] !== save || $[32] !== voice) {
|
|
180
|
+
t13 = voice ? /* @__PURE__ */ jsx("ul", {
|
|
181
|
+
className: "flex flex-col gap-12",
|
|
182
|
+
children: VOICE_AXES.map((axis) => /* @__PURE__ */ jsx(VoiceAxisRow, {
|
|
183
|
+
axis,
|
|
184
|
+
step: voice[axis.key],
|
|
185
|
+
disabled: save.isPending,
|
|
186
|
+
onStep: (step) => {
|
|
187
|
+
setMoved((current) => ({
|
|
188
|
+
...current,
|
|
189
|
+
[axis.key]: step
|
|
190
|
+
}));
|
|
191
|
+
setJustSaved(false);
|
|
192
|
+
save.reset();
|
|
193
|
+
}
|
|
194
|
+
}, axis.key))
|
|
195
|
+
}) : /* @__PURE__ */ jsx(Skeleton, { className: "h-96" });
|
|
196
|
+
$[31] = save;
|
|
197
|
+
$[32] = voice;
|
|
198
|
+
$[33] = t13;
|
|
199
|
+
} else t13 = $[33];
|
|
200
|
+
let t14;
|
|
201
|
+
if ($[34] !== t12 || $[35] !== t13) {
|
|
202
|
+
t14 = /* @__PURE__ */ jsx(BrandPart, {
|
|
203
|
+
"data-voice": true,
|
|
204
|
+
title: "Voice",
|
|
205
|
+
description: "How the website speaks to visitors.",
|
|
206
|
+
headingRef: heading,
|
|
207
|
+
aside: t12,
|
|
208
|
+
children: t13
|
|
209
|
+
});
|
|
210
|
+
$[34] = t12;
|
|
211
|
+
$[35] = t13;
|
|
212
|
+
$[36] = t14;
|
|
213
|
+
} else t14 = $[36];
|
|
214
|
+
return t14;
|
|
215
|
+
}
|
|
216
|
+
/** The axes `voice` moves away from `saved`, with their new steps. */
|
|
217
|
+
function changedAxes(saved, voice) {
|
|
218
|
+
const changed = {};
|
|
219
|
+
for (const { key } of VOICE_AXES) if (voice[key] !== saved[key]) changed[key] = voice[key];
|
|
220
|
+
return changed;
|
|
221
|
+
}
|
|
222
|
+
const sentenceCase = (text) => text.charAt(0).toUpperCase() + text.slice(1);
|
|
223
|
+
/**
|
|
224
|
+
* One Voice Axis: its name over an oversized slider, with the chosen step's name and definition
|
|
225
|
+
* centered under its stop, and following it as it moves.
|
|
226
|
+
*/
|
|
227
|
+
function VoiceAxisRow(t0) {
|
|
228
|
+
const $ = c(55);
|
|
229
|
+
const { axis, step, disabled, onStep } = t0;
|
|
230
|
+
const steps = axis.steps;
|
|
231
|
+
const last = steps.length - 1;
|
|
232
|
+
let t1;
|
|
233
|
+
if ($[0] !== step || $[1] !== steps) {
|
|
234
|
+
let t2;
|
|
235
|
+
if ($[3] !== step) {
|
|
236
|
+
t2 = (candidate) => candidate.key === step;
|
|
237
|
+
$[3] = step;
|
|
238
|
+
$[4] = t2;
|
|
239
|
+
} else t2 = $[4];
|
|
240
|
+
t1 = steps.findIndex(t2);
|
|
241
|
+
$[0] = step;
|
|
242
|
+
$[1] = steps;
|
|
243
|
+
$[2] = t1;
|
|
244
|
+
} else t1 = $[2];
|
|
245
|
+
const index = Math.max(t1, 0);
|
|
246
|
+
const chosen = steps[index];
|
|
247
|
+
const at = index / last * 100;
|
|
248
|
+
let t2;
|
|
249
|
+
if ($[5] !== axis.name) {
|
|
250
|
+
t2 = /* @__PURE__ */ jsx("h3", {
|
|
251
|
+
"data-voice-axis-name": true,
|
|
252
|
+
className: "text-sm font-medium",
|
|
253
|
+
children: axis.name
|
|
254
|
+
});
|
|
255
|
+
$[5] = axis.name;
|
|
256
|
+
$[6] = t2;
|
|
257
|
+
} else t2 = $[6];
|
|
258
|
+
let t3;
|
|
259
|
+
if ($[7] !== onStep || $[8] !== steps) {
|
|
260
|
+
t3 = (value) => {
|
|
261
|
+
const next = steps[value];
|
|
262
|
+
if (next) onStep(next.key);
|
|
263
|
+
};
|
|
264
|
+
$[7] = onStep;
|
|
265
|
+
$[8] = steps;
|
|
266
|
+
$[9] = t3;
|
|
267
|
+
} else t3 = $[9];
|
|
268
|
+
let t4;
|
|
269
|
+
if ($[10] !== last || $[11] !== steps) {
|
|
270
|
+
let t5;
|
|
271
|
+
if ($[13] !== last) {
|
|
272
|
+
t5 = (candidate_0, stop) => /* @__PURE__ */ jsx("span", {
|
|
273
|
+
"aria-hidden": true,
|
|
274
|
+
className: "bg-muted-foreground/80 absolute top-1/2 size-2.5 -translate-x-1/2 -translate-y-1/2 rounded-full",
|
|
275
|
+
style: { left: `${stop / last * 100}%` }
|
|
276
|
+
}, candidate_0.key);
|
|
277
|
+
$[13] = last;
|
|
278
|
+
$[14] = t5;
|
|
279
|
+
} else t5 = $[14];
|
|
280
|
+
t4 = steps.map(t5);
|
|
281
|
+
$[10] = last;
|
|
282
|
+
$[11] = steps;
|
|
283
|
+
$[12] = t4;
|
|
284
|
+
} else t4 = $[12];
|
|
285
|
+
let t5;
|
|
286
|
+
if ($[15] !== t4) {
|
|
287
|
+
t5 = /* @__PURE__ */ jsx(Slider.Track, {
|
|
288
|
+
className: "bg-muted relative h-2 w-full rounded-full",
|
|
289
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
290
|
+
className: "pointer-events-none absolute inset-x-3.5 inset-y-0",
|
|
291
|
+
children: t4
|
|
292
|
+
})
|
|
293
|
+
});
|
|
294
|
+
$[15] = t4;
|
|
295
|
+
$[16] = t5;
|
|
296
|
+
} else t5 = $[16];
|
|
297
|
+
let t6;
|
|
298
|
+
if ($[17] !== axis.name) {
|
|
299
|
+
t6 = () => axis.name;
|
|
300
|
+
$[17] = axis.name;
|
|
301
|
+
$[18] = t6;
|
|
302
|
+
} else t6 = $[18];
|
|
303
|
+
const t7 = chosen.name;
|
|
304
|
+
const t8 = steps.length;
|
|
305
|
+
let t9;
|
|
306
|
+
if ($[19] !== chosen.definition) {
|
|
307
|
+
t9 = sentenceCase(chosen.definition);
|
|
308
|
+
$[19] = chosen.definition;
|
|
309
|
+
$[20] = t9;
|
|
310
|
+
} else t9 = $[20];
|
|
311
|
+
const t10 = `${t7}, ${index + 1} of ${t8}. ${t9}`;
|
|
312
|
+
let t11;
|
|
313
|
+
if ($[21] !== t10 || $[22] !== t6) {
|
|
314
|
+
t11 = /* @__PURE__ */ jsx(Slider.Thumb, {
|
|
315
|
+
getAriaLabel: t6,
|
|
316
|
+
"aria-valuetext": t10,
|
|
317
|
+
className: "border-primary bg-background ring-ring/50 block size-7 shrink-0 rounded-full border-[3px] shadow-md transition-[left,box-shadow] duration-150 ease-out outline-none hover:ring-4 has-focus-visible:ring-4 data-disabled:pointer-events-none motion-reduce:transition-none"
|
|
318
|
+
});
|
|
319
|
+
$[21] = t10;
|
|
320
|
+
$[22] = t6;
|
|
321
|
+
$[23] = t11;
|
|
322
|
+
} else t11 = $[23];
|
|
323
|
+
let t12;
|
|
324
|
+
if ($[24] !== t11 || $[25] !== t5) {
|
|
325
|
+
t12 = /* @__PURE__ */ jsxs(Slider.Control, {
|
|
326
|
+
className: "relative flex h-8 w-full cursor-pointer touch-none items-center select-none data-disabled:cursor-not-allowed",
|
|
327
|
+
children: [t5, t11]
|
|
328
|
+
});
|
|
329
|
+
$[24] = t11;
|
|
330
|
+
$[25] = t5;
|
|
331
|
+
$[26] = t12;
|
|
332
|
+
} else t12 = $[26];
|
|
333
|
+
let t13;
|
|
334
|
+
if ($[27] !== disabled || $[28] !== index || $[29] !== last || $[30] !== t12 || $[31] !== t3) {
|
|
335
|
+
t13 = /* @__PURE__ */ jsx(Slider.Root, {
|
|
336
|
+
value: index,
|
|
337
|
+
min: 0,
|
|
338
|
+
max: last,
|
|
339
|
+
step: 1,
|
|
340
|
+
thumbAlignment: "edge",
|
|
341
|
+
disabled,
|
|
342
|
+
className: "data-disabled:opacity-50",
|
|
343
|
+
onValueChange: t3,
|
|
344
|
+
children: t12
|
|
345
|
+
});
|
|
346
|
+
$[27] = disabled;
|
|
347
|
+
$[28] = index;
|
|
348
|
+
$[29] = last;
|
|
349
|
+
$[30] = t12;
|
|
350
|
+
$[31] = t3;
|
|
351
|
+
$[32] = t13;
|
|
352
|
+
} else t13 = $[32];
|
|
353
|
+
const t14 = index === 0 ? "text-left" : index === last ? "text-right" : "text-center";
|
|
354
|
+
let t15;
|
|
355
|
+
if ($[33] !== t14) {
|
|
356
|
+
t15 = cn("transition-[margin-left] duration-200 ease-out motion-reduce:transition-none", t14);
|
|
357
|
+
$[33] = t14;
|
|
358
|
+
$[34] = t15;
|
|
359
|
+
} else t15 = $[34];
|
|
360
|
+
const t16 = `clamp(-0.875rem, calc(${at}% - min(8rem, 50%)), calc(100% + 0.875rem - min(16rem, 100%)))`;
|
|
361
|
+
let t17;
|
|
362
|
+
if ($[35] !== t16) {
|
|
363
|
+
t17 = {
|
|
364
|
+
width: "min(16rem, 100%)",
|
|
365
|
+
marginLeft: t16
|
|
366
|
+
};
|
|
367
|
+
$[35] = t16;
|
|
368
|
+
$[36] = t17;
|
|
369
|
+
} else t17 = $[36];
|
|
370
|
+
const t18 = chosen.key;
|
|
371
|
+
let t19;
|
|
372
|
+
if ($[37] !== chosen.name) {
|
|
373
|
+
t19 = /* @__PURE__ */ jsx("p", {
|
|
374
|
+
"data-voice-step": true,
|
|
375
|
+
className: "font-semibold",
|
|
376
|
+
children: chosen.name
|
|
377
|
+
});
|
|
378
|
+
$[37] = chosen.name;
|
|
379
|
+
$[38] = t19;
|
|
380
|
+
} else t19 = $[38];
|
|
381
|
+
let t20;
|
|
382
|
+
if ($[39] !== chosen.definition) {
|
|
383
|
+
t20 = sentenceCase(chosen.definition);
|
|
384
|
+
$[39] = chosen.definition;
|
|
385
|
+
$[40] = t20;
|
|
386
|
+
} else t20 = $[40];
|
|
387
|
+
let t21;
|
|
388
|
+
if ($[41] !== t20) {
|
|
389
|
+
t21 = /* @__PURE__ */ jsx("p", {
|
|
390
|
+
"data-voice-definition": true,
|
|
391
|
+
className: "text-muted-foreground mt-0.5 text-sm",
|
|
392
|
+
children: t20
|
|
393
|
+
});
|
|
394
|
+
$[41] = t20;
|
|
395
|
+
$[42] = t21;
|
|
396
|
+
} else t21 = $[42];
|
|
397
|
+
let t22;
|
|
398
|
+
if ($[43] !== chosen.key || $[44] !== t19 || $[45] !== t21) {
|
|
399
|
+
t22 = /* @__PURE__ */ jsxs("div", {
|
|
400
|
+
className: "animate-in fade-in-0 duration-200",
|
|
401
|
+
children: [t19, t21]
|
|
402
|
+
}, t18);
|
|
403
|
+
$[43] = chosen.key;
|
|
404
|
+
$[44] = t19;
|
|
405
|
+
$[45] = t21;
|
|
406
|
+
$[46] = t22;
|
|
407
|
+
} else t22 = $[46];
|
|
408
|
+
let t23;
|
|
409
|
+
if ($[47] !== t15 || $[48] !== t17 || $[49] !== t22) {
|
|
410
|
+
t23 = /* @__PURE__ */ jsx("div", {
|
|
411
|
+
className: "mx-3.5 min-h-21",
|
|
412
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
413
|
+
className: t15,
|
|
414
|
+
style: t17,
|
|
415
|
+
children: t22
|
|
416
|
+
})
|
|
417
|
+
});
|
|
418
|
+
$[47] = t15;
|
|
419
|
+
$[48] = t17;
|
|
420
|
+
$[49] = t22;
|
|
421
|
+
$[50] = t23;
|
|
422
|
+
} else t23 = $[50];
|
|
423
|
+
let t24;
|
|
424
|
+
if ($[51] !== t13 || $[52] !== t2 || $[53] !== t23) {
|
|
425
|
+
t24 = /* @__PURE__ */ jsxs("li", {
|
|
426
|
+
"data-voice-axis": true,
|
|
427
|
+
className: "flex flex-col gap-3",
|
|
428
|
+
children: [
|
|
429
|
+
t2,
|
|
430
|
+
t13,
|
|
431
|
+
t23
|
|
432
|
+
]
|
|
433
|
+
});
|
|
434
|
+
$[51] = t13;
|
|
435
|
+
$[52] = t2;
|
|
436
|
+
$[53] = t23;
|
|
437
|
+
$[54] = t24;
|
|
438
|
+
} else t24 = $[54];
|
|
439
|
+
return t24;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
//#endregion
|
|
443
|
+
export { VoiceGroup };
|
|
@@ -3,7 +3,7 @@ import { CamoxContent } from "../content/CamoxContent.js";
|
|
|
3
3
|
import { AuthenticatedCamoxProvider } from "../provider/AuthenticatedCamoxProvider.js";
|
|
4
4
|
import { CamoxStudio } from "../studio/CamoxStudio.js";
|
|
5
5
|
import { CompleteBlockEditingRuntimeProvider } from "../../core/editing/CompleteBlockEditingRuntime.js";
|
|
6
|
-
import {
|
|
6
|
+
import { CamoxBrand } from "../brand/CamoxBrand.js";
|
|
7
7
|
import { CamoxSettings } from "../settings/CamoxSettings.js";
|
|
8
8
|
import { c } from "react/compiler-runtime";
|
|
9
9
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -12,7 +12,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
12
12
|
/** The studio section each studio route shows. */
|
|
13
13
|
const STUDIO_SECTIONS = {
|
|
14
14
|
"studio-content": CamoxContent,
|
|
15
|
-
"studio-
|
|
15
|
+
"studio-brand": CamoxBrand,
|
|
16
16
|
"studio-settings": CamoxSettings
|
|
17
17
|
};
|
|
18
18
|
function EditablePageExperience(t0) {
|
|
@@ -11,7 +11,7 @@ import { LookPlaceholderHeight } from "@camox/api-contract/drafts";
|
|
|
11
11
|
import { UseHeadInput } from "unhead/types";
|
|
12
12
|
//#region src/features/runtime/runtime.d.ts
|
|
13
13
|
/** The studio's own routes, rather than a page or the Canvas. */
|
|
14
|
-
declare const STUDIO_ROUTE_KINDS: readonly ["studio", "studio-content", "studio-
|
|
14
|
+
declare const STUDIO_ROUTE_KINDS: readonly ["studio", "studio-content", "studio-brand", "studio-settings", "studio-nested"];
|
|
15
15
|
export type StudioRouteKind = (typeof STUDIO_ROUTE_KINDS)[number];
|
|
16
16
|
export type RuntimeRouteKind = RuntimeOwnedRouteKind | "canvas" | "page" | StudioRouteKind;
|
|
17
17
|
export interface RuntimeRouteMatch {
|
|
@@ -8,7 +8,7 @@ import { ARTIFACTS_PATH_PREFIX, RUNTIME_ROUTE_PATHS, matchRuntimeOwnedRoute } fr
|
|
|
8
8
|
import { reads } from "../../lib/studio-reads.js";
|
|
9
9
|
import { recordMarkdownTemplate } from "../../core/recordItem.js";
|
|
10
10
|
import { PLATFORM_SCRIPT } from "../../lib/platform.js";
|
|
11
|
-
import { STUDIO_ASSETS_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH,
|
|
11
|
+
import { STUDIO_ASSETS_PATH, STUDIO_BRAND_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_SETTINGS_PATH, matchCollectionContentPath } from "../studio/routes.js";
|
|
12
12
|
import { STUDIO_THEME_SCRIPT } from "../studio/studioTheme.js";
|
|
13
13
|
import { DefaultPageImage, renderPageImage } from "../og/pageImage.js";
|
|
14
14
|
import { discoverLayoutPages } from "../../core/derivedRoutes.js";
|
|
@@ -39,7 +39,7 @@ const DEFAULT_RUNTIME_BASE_PATH = "";
|
|
|
39
39
|
const STUDIO_ROUTE_KINDS = [
|
|
40
40
|
"studio",
|
|
41
41
|
"studio-content",
|
|
42
|
-
"studio-
|
|
42
|
+
"studio-brand",
|
|
43
43
|
"studio-settings",
|
|
44
44
|
"studio-nested"
|
|
45
45
|
];
|
|
@@ -123,8 +123,8 @@ function matchRuntimeRoute(pathname) {
|
|
|
123
123
|
kind: "studio-content",
|
|
124
124
|
pathname
|
|
125
125
|
};
|
|
126
|
-
if (pathname === "/camox/
|
|
127
|
-
kind: "studio-
|
|
126
|
+
if (pathname === "/camox/brand" || pathname === `${"/camox/brand"}/`) return {
|
|
127
|
+
kind: "studio-brand",
|
|
128
128
|
pathname
|
|
129
129
|
};
|
|
130
130
|
if (pathname === "/camox/settings" || pathname === `${"/camox/settings"}/`) return {
|
|
@@ -20,12 +20,12 @@ import { voiceAxis, voiceStep } from "@camox/api-contract/voice";
|
|
|
20
20
|
|
|
21
21
|
//#region src/features/studio/components/DraftReview.tsx
|
|
22
22
|
/**
|
|
23
|
-
* Where a subject sits: its page or layout, or the files, the languages or
|
|
24
|
-
*
|
|
23
|
+
* Where a subject sits: its page or layout, or the files, the languages or the brand (the Voice
|
|
24
|
+
* and memory), which belong to none.
|
|
25
25
|
*/
|
|
26
26
|
function ownerName(owner, entity) {
|
|
27
27
|
if (entity === "locale") return "Languages";
|
|
28
|
-
if (entity === "memory" || entity === "voiceAxis") return "
|
|
28
|
+
if (entity === "memory" || entity === "voiceAxis") return "Brand";
|
|
29
29
|
if (!owner) return entity === "file" ? "Files" : "Elsewhere";
|
|
30
30
|
if (owner.kind === "layout") return `Layout ${owner.name}`;
|
|
31
31
|
if (owner.kind === "syncedBlock") return `Synced block ${owner.title}`;
|
|
@@ -226,11 +226,11 @@ function voiceLine({ axis, before, after }) {
|
|
|
226
226
|
return `${voiceAxis(axis).name}: ${stepName(before)} → ${stepName(after)}`;
|
|
227
227
|
}
|
|
228
228
|
/**
|
|
229
|
-
* What publishing the draft changes in
|
|
229
|
+
* What publishing the draft changes in the brand: each Voice Axis it moves, from Live's step to the
|
|
230
230
|
* draft's, then the memories it adds, changes and deletes, each with its text, and Live's before a
|
|
231
231
|
* change. Nothing when it changes neither.
|
|
232
232
|
*/
|
|
233
|
-
function
|
|
233
|
+
function BrandChanges(t0) {
|
|
234
234
|
const $ = c(8);
|
|
235
235
|
const { voice, changes } = t0;
|
|
236
236
|
if (voice.length === 0 && changes.length === 0) return null;
|
|
@@ -238,7 +238,7 @@ function MemoryChanges(t0) {
|
|
|
238
238
|
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
239
239
|
t1 = /* @__PURE__ */ jsx("h3", {
|
|
240
240
|
className: "text-sm font-medium",
|
|
241
|
-
children: "
|
|
241
|
+
children: "Brand"
|
|
242
242
|
});
|
|
243
243
|
$[0] = t1;
|
|
244
244
|
} else t1 = $[0];
|
|
@@ -257,7 +257,7 @@ function MemoryChanges(t0) {
|
|
|
257
257
|
let t4;
|
|
258
258
|
if ($[5] !== t2 || $[6] !== t3) {
|
|
259
259
|
t4 = /* @__PURE__ */ jsxs("section", {
|
|
260
|
-
"data-
|
|
260
|
+
"data-brand-changes": true,
|
|
261
261
|
className: "flex flex-col gap-2",
|
|
262
262
|
children: [t1, /* @__PURE__ */ jsxs("ul", {
|
|
263
263
|
className: "flex flex-col gap-2",
|
|
@@ -590,7 +590,7 @@ function DraftReview(t0) {
|
|
|
590
590
|
}
|
|
591
591
|
}),
|
|
592
592
|
lines.map(_temp9),
|
|
593
|
-
/* @__PURE__ */ jsx(
|
|
593
|
+
/* @__PURE__ */ jsx(BrandChanges, {
|
|
594
594
|
voice: data.voiceChanges,
|
|
595
595
|
changes: data.memoryChanges
|
|
596
596
|
})
|
|
@@ -4,7 +4,7 @@ import { actionsStore } from "../../provider/actionsStore.js";
|
|
|
4
4
|
import { cn } from "../../../lib/utils.js";
|
|
5
5
|
import { usePageDestinations } from "../../../hooks/use-page-destinations.js";
|
|
6
6
|
import { useLocalePath, useLocalizedPath } from "../../../lib/view-locale.js";
|
|
7
|
-
import { STUDIO_BASE_PATH,
|
|
7
|
+
import { STUDIO_BASE_PATH, STUDIO_BRAND_PATH, STUDIO_CONTENT_PATH, STUDIO_SETTINGS_PATH } from "../routes.js";
|
|
8
8
|
import { studioStore } from "../studioStore.js";
|
|
9
9
|
import { UserButton } from "./UserButton.js";
|
|
10
10
|
import { ConnectAgent } from "./ConnectAgent.js";
|
|
@@ -29,11 +29,13 @@ const links = [
|
|
|
29
29
|
aliases: ["Website"]
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
|
-
to:
|
|
33
|
-
title: "
|
|
34
|
-
children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Brain, {}), "
|
|
32
|
+
to: STUDIO_BRAND_PATH,
|
|
33
|
+
title: "Brand",
|
|
34
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Brain, {}), "Brand"] }),
|
|
35
35
|
icon: "Brain",
|
|
36
36
|
aliases: [
|
|
37
|
+
"Brand",
|
|
38
|
+
"Voice",
|
|
37
39
|
"Memory",
|
|
38
40
|
"Memories",
|
|
39
41
|
"Remember"
|
|
@@ -98,11 +100,11 @@ const Navbar = (t0) => {
|
|
|
98
100
|
const isSettings = t2;
|
|
99
101
|
let t3;
|
|
100
102
|
if ($[2] !== pathname) {
|
|
101
|
-
t3 = isInSection(
|
|
103
|
+
t3 = isInSection(STUDIO_BRAND_PATH, pathname);
|
|
102
104
|
$[2] = pathname;
|
|
103
105
|
$[3] = t3;
|
|
104
106
|
} else t3 = $[3];
|
|
105
|
-
const
|
|
107
|
+
const isBrand = t3;
|
|
106
108
|
let t4;
|
|
107
109
|
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
|
|
108
110
|
t4 = /* @__PURE__ */ jsx(ProjectMenu, {});
|
|
@@ -114,7 +116,7 @@ const Navbar = (t0) => {
|
|
|
114
116
|
$[5] = isSettings;
|
|
115
117
|
$[6] = t5;
|
|
116
118
|
} else t5 = $[6];
|
|
117
|
-
const t6 = isSettings ||
|
|
119
|
+
const t6 = isSettings || isBrand;
|
|
118
120
|
let t7;
|
|
119
121
|
if ($[7] !== recordPage || $[8] !== t6) {
|
|
120
122
|
t7 = /* @__PURE__ */ jsx(LocalePicker, {
|
|
@@ -3,8 +3,8 @@ const STUDIO_ROUTE_SEGMENT = "camox";
|
|
|
3
3
|
const STUDIO_BASE_PATH = `/${STUDIO_ROUTE_SEGMENT}`;
|
|
4
4
|
const STUDIO_CONTENT_PATH = `${STUDIO_BASE_PATH}/content`;
|
|
5
5
|
const STUDIO_ASSETS_PATH = `${STUDIO_CONTENT_PATH}/assets`;
|
|
6
|
-
/** The
|
|
7
|
-
const
|
|
6
|
+
/** The Brand Section, where members set the Voice and see and correct memory. */
|
|
7
|
+
const STUDIO_BRAND_PATH = `${STUDIO_BASE_PATH}/brand`;
|
|
8
8
|
/** The Settings Section, where members change Project Settings. */
|
|
9
9
|
const STUDIO_SETTINGS_PATH = `${STUDIO_BASE_PATH}/settings`;
|
|
10
10
|
const collectionContentPath = (collectionId) => `${STUDIO_CONTENT_PATH}/collections/${encodeURIComponent(collectionId)}`;
|
|
@@ -34,4 +34,4 @@ function matchCollectionContentPath(pathname) {
|
|
|
34
34
|
const STUDIO_CANVAS_PATH = `${STUDIO_BASE_PATH}/canvas`;
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
|
-
export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH,
|
|
37
|
+
export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH, STUDIO_BRAND_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT, STUDIO_SETTINGS_PATH, collectionContentPath, editCollectionItemPath, matchCollectionContentPath };
|
package/dist/lib/queries.js
CHANGED
|
@@ -81,13 +81,13 @@ const localeMutations = {
|
|
|
81
81
|
addBack: () => getOrpc().locales.addBack.mutationOptions()
|
|
82
82
|
};
|
|
83
83
|
/**
|
|
84
|
-
*
|
|
85
|
-
* ADR 0051).
|
|
84
|
+
* Changing the brand, by correcting memory or saving the Voice: content writes, so on Live they
|
|
85
|
+
* start a draft (ADR 0049, ADR 0051, ADR 0052).
|
|
86
86
|
*/
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
const brandMutations = {
|
|
88
|
+
addMemory: () => getOrpc().memories.add.mutationOptions(),
|
|
89
|
+
changeMemory: () => getOrpc().memories.change.mutationOptions(),
|
|
90
|
+
deleteMemory: () => getOrpc().memories.delete.mutationOptions(),
|
|
91
91
|
saveVoice: () => getOrpc().memories.saveVoice.mutationOptions()
|
|
92
92
|
};
|
|
93
93
|
const blockMutations = {
|
|
@@ -163,4 +163,4 @@ const fileMutations = {
|
|
|
163
163
|
};
|
|
164
164
|
|
|
165
165
|
//#endregion
|
|
166
|
-
export { blockMutations, collectionMutations, draftMutations, fileMutations, localeMutations,
|
|
166
|
+
export { blockMutations, brandMutations, collectionMutations, draftMutations, fileMutations, localeMutations, pageMutations, projectMutations, publicationMutations, repeatableItemMutations, specialistMutations };
|
package/dist/package.js
CHANGED