camox 0.76.1 → 0.78.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/artifactTheme.js +43 -6
- package/dist/features/canvas/CamoxCanvas.js +187 -197
- package/dist/features/canvas/canvasCameraController.js +1 -1
- package/dist/features/canvas/canvasItems.js +40 -9
- package/dist/features/canvas/sidebar/ContentSidebarFrame.js +15 -11
- package/dist/features/canvas/useCanvasLayout.js +34 -0
- package/dist/features/memory/CamoxMemory.js +747 -0
- package/dist/features/preview/EditablePageExperience.js +2 -0
- package/dist/features/runtime/publicCache.d.ts +2 -0
- package/dist/features/runtime/publicCache.js +27 -4
- package/dist/features/runtime/runtime.d.ts +1 -1
- package/dist/features/runtime/runtime.js +34 -15
- package/dist/features/studio/FollowAgentProvider.js +1 -1
- package/dist/features/studio/components/AgentSidebar.js +22 -16
- package/dist/features/studio/components/DraftBar.js +167 -103
- package/dist/features/studio/components/{ReviewDraftDialog.js → DraftReview.js} +191 -218
- package/dist/features/studio/components/DraftsControl.js +174 -202
- package/dist/features/studio/components/DraftsSheet.js +102 -94
- package/dist/features/studio/components/LocalePicker.js +518 -134
- package/dist/features/studio/components/Navbar.js +121 -84
- package/dist/features/studio/components/PublishedTab.js +21 -20
- package/dist/features/studio/routes.js +3 -1
- package/dist/features/studio/studioStore.js +12 -9
- package/dist/features/studio/usePublishDraft.js +116 -0
- package/dist/features/studio/viewSwitch.js +10 -7
- package/dist/lib/locale-path.js +2 -2
- package/dist/lib/queries.js +12 -2
- package/dist/lib/studio-reads.js +6 -0
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +5 -5
- package/skills/camox/references/artifacts.md +7 -0
- package/LICENSE.md +0 -21
|
@@ -0,0 +1,747 @@
|
|
|
1
|
+
import { useNavigate } from "../navigation/navigation.js";
|
|
2
|
+
import { useProjectUuid } from "../../lib/auth.js";
|
|
3
|
+
import { reads, useReadQuery, useStudioCache } from "../../lib/studio-reads.js";
|
|
4
|
+
import { memoryMutations } from "../../lib/queries.js";
|
|
5
|
+
import { previewStore } from "../preview/previewStore.js";
|
|
6
|
+
import { studioStore } from "../studio/studioStore.js";
|
|
7
|
+
import { timeAgo } from "../studio/draftLabel.js";
|
|
8
|
+
import { useWebsiteHref } from "../studio/components/Navbar.js";
|
|
9
|
+
import { c } from "react/compiler-runtime";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { useMutation } from "@tanstack/react-query";
|
|
13
|
+
import { Button } from "@camox/ui/button";
|
|
14
|
+
import { Textarea } from "@camox/ui/textarea";
|
|
15
|
+
import { ChevronRight, MessagesSquare, Pencil, Trash2 } from "lucide-react";
|
|
16
|
+
import { ButtonGroup } from "@camox/ui/button-group";
|
|
17
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@camox/ui/dialog";
|
|
18
|
+
import { Skeleton } from "@camox/ui/skeleton";
|
|
19
|
+
import { Spinner } from "@camox/ui/spinner";
|
|
20
|
+
import { Accordion, AccordionHeader, AccordionItem, AccordionPanel, AccordionTrigger } from "@camox/ui/accordion";
|
|
21
|
+
|
|
22
|
+
//#region src/features/memory/CamoxMemory.tsx
|
|
23
|
+
/**
|
|
24
|
+
* The Memory Section (GLOSSARY): the memory of Live or of the draft being viewed, where members
|
|
25
|
+
* add, correct and delete memories. Like content, a first edit while viewing Live starts a draft.
|
|
26
|
+
*/
|
|
27
|
+
const CamoxMemory = () => {
|
|
28
|
+
const $ = c(5);
|
|
29
|
+
const projectUuid = useProjectUuid();
|
|
30
|
+
let t0;
|
|
31
|
+
if ($[0] !== projectUuid) {
|
|
32
|
+
t0 = reads.project({ projectUuid });
|
|
33
|
+
$[0] = projectUuid;
|
|
34
|
+
$[1] = t0;
|
|
35
|
+
} else t0 = $[1];
|
|
36
|
+
const { data: project } = useReadQuery(t0);
|
|
37
|
+
let t1;
|
|
38
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
39
|
+
t1 = /* @__PURE__ */ jsxs("header", {
|
|
40
|
+
className: "flex flex-col gap-1",
|
|
41
|
+
children: [/* @__PURE__ */ jsx("h1", {
|
|
42
|
+
className: "text-xl font-semibold",
|
|
43
|
+
children: "Memory"
|
|
44
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
45
|
+
className: "text-muted-foreground text-sm",
|
|
46
|
+
children: "What Camox's agent knows about the business beyond what the website shows. Every model that writes for visitors follows it."
|
|
47
|
+
})]
|
|
48
|
+
});
|
|
49
|
+
$[2] = t1;
|
|
50
|
+
} else t1 = $[2];
|
|
51
|
+
let t2;
|
|
52
|
+
if ($[3] !== project) {
|
|
53
|
+
t2 = /* @__PURE__ */ jsxs("div", {
|
|
54
|
+
"data-memory-section": true,
|
|
55
|
+
className: "mx-auto flex w-full max-w-3xl flex-col gap-6 p-6 md:p-10",
|
|
56
|
+
children: [t1, project ? /* @__PURE__ */ jsx(ProjectMemory, { projectId: project.id }) : /* @__PURE__ */ jsx(Loading, {})]
|
|
57
|
+
});
|
|
58
|
+
$[3] = project;
|
|
59
|
+
$[4] = t2;
|
|
60
|
+
} else t2 = $[4];
|
|
61
|
+
return t2;
|
|
62
|
+
};
|
|
63
|
+
const Loading = () => {
|
|
64
|
+
const $ = c(1);
|
|
65
|
+
let t0;
|
|
66
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
67
|
+
t0 = /* @__PURE__ */ jsxs("div", {
|
|
68
|
+
role: "status",
|
|
69
|
+
"aria-label": "Loading memory",
|
|
70
|
+
className: "flex flex-col gap-3",
|
|
71
|
+
children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-16" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-16" })]
|
|
72
|
+
});
|
|
73
|
+
$[0] = t0;
|
|
74
|
+
} else t0 = $[0];
|
|
75
|
+
return t0;
|
|
76
|
+
};
|
|
77
|
+
const words = (count) => `${count.toLocaleString("en")} word${count === 1 ? "" : "s"}`;
|
|
78
|
+
function ProjectMemory(t0) {
|
|
79
|
+
const $ = c(19);
|
|
80
|
+
const { projectId } = t0;
|
|
81
|
+
let t1;
|
|
82
|
+
if ($[0] !== projectId) {
|
|
83
|
+
t1 = reads.memories({ projectId });
|
|
84
|
+
$[0] = projectId;
|
|
85
|
+
$[1] = t1;
|
|
86
|
+
} else t1 = $[1];
|
|
87
|
+
const { data } = useReadQuery(t1);
|
|
88
|
+
if (!data) {
|
|
89
|
+
let t2;
|
|
90
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
91
|
+
t2 = /* @__PURE__ */ jsx(Loading, {});
|
|
92
|
+
$[2] = t2;
|
|
93
|
+
} else t2 = $[2];
|
|
94
|
+
return t2;
|
|
95
|
+
}
|
|
96
|
+
const room = Math.max(data.limitWords - data.usedWords, 0);
|
|
97
|
+
let t2;
|
|
98
|
+
if ($[3] !== projectId) {
|
|
99
|
+
t2 = /* @__PURE__ */ jsx(AddMemory, { projectId });
|
|
100
|
+
$[3] = projectId;
|
|
101
|
+
$[4] = t2;
|
|
102
|
+
} else t2 = $[4];
|
|
103
|
+
let t3;
|
|
104
|
+
if ($[5] !== room) {
|
|
105
|
+
t3 = words(room);
|
|
106
|
+
$[5] = room;
|
|
107
|
+
$[6] = t3;
|
|
108
|
+
} else t3 = $[6];
|
|
109
|
+
let t4;
|
|
110
|
+
if ($[7] !== data.limitWords) {
|
|
111
|
+
t4 = data.limitWords.toLocaleString("en");
|
|
112
|
+
$[7] = data.limitWords;
|
|
113
|
+
$[8] = t4;
|
|
114
|
+
} else t4 = $[8];
|
|
115
|
+
let t5;
|
|
116
|
+
if ($[9] !== t3 || $[10] !== t4) {
|
|
117
|
+
t5 = /* @__PURE__ */ jsxs("p", {
|
|
118
|
+
"data-memory-room": true,
|
|
119
|
+
className: "text-muted-foreground text-xs",
|
|
120
|
+
children: [
|
|
121
|
+
t3,
|
|
122
|
+
" left of ",
|
|
123
|
+
t4
|
|
124
|
+
]
|
|
125
|
+
});
|
|
126
|
+
$[9] = t3;
|
|
127
|
+
$[10] = t4;
|
|
128
|
+
$[11] = t5;
|
|
129
|
+
} else t5 = $[11];
|
|
130
|
+
let t6;
|
|
131
|
+
if ($[12] !== data.memories || $[13] !== projectId) {
|
|
132
|
+
t6 = data.memories.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
133
|
+
"data-memory-empty": true,
|
|
134
|
+
className: "text-muted-foreground py-6 text-sm",
|
|
135
|
+
children: "Camox's agent remembers what members teach it that holds beyond one request and that the website can't show, such as how the business talks, what sets it apart, or rules like \"never use usted\". What it remembers in a draft applies there at once, and reaches the live website when the draft is published. Nothing yet: it learns as you work with it, or add a memory yourself."
|
|
136
|
+
}) : /* @__PURE__ */ jsx(Accordion, {
|
|
137
|
+
multiple: true,
|
|
138
|
+
className: "divide-y overflow-hidden rounded-lg border",
|
|
139
|
+
children: data.memories.map((memory) => /* @__PURE__ */ jsx(MemoryRow, {
|
|
140
|
+
projectId,
|
|
141
|
+
memory
|
|
142
|
+
}, memory.id))
|
|
143
|
+
});
|
|
144
|
+
$[12] = data.memories;
|
|
145
|
+
$[13] = projectId;
|
|
146
|
+
$[14] = t6;
|
|
147
|
+
} else t6 = $[14];
|
|
148
|
+
let t7;
|
|
149
|
+
if ($[15] !== t2 || $[16] !== t5 || $[17] !== t6) {
|
|
150
|
+
t7 = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
151
|
+
t2,
|
|
152
|
+
t5,
|
|
153
|
+
t6
|
|
154
|
+
] });
|
|
155
|
+
$[15] = t2;
|
|
156
|
+
$[16] = t5;
|
|
157
|
+
$[17] = t6;
|
|
158
|
+
$[18] = t7;
|
|
159
|
+
} else t7 = $[18];
|
|
160
|
+
return t7;
|
|
161
|
+
}
|
|
162
|
+
/** Refreshes the memory a write changed. On Live, the write started a draft, which it reads. */
|
|
163
|
+
function useRefreshMemory(projectId) {
|
|
164
|
+
const $ = c(3);
|
|
165
|
+
const cache = useStudioCache();
|
|
166
|
+
let t0;
|
|
167
|
+
if ($[0] !== cache || $[1] !== projectId) {
|
|
168
|
+
t0 = () => void cache.invalidate(reads.memories({ projectId }));
|
|
169
|
+
$[0] = cache;
|
|
170
|
+
$[1] = projectId;
|
|
171
|
+
$[2] = t0;
|
|
172
|
+
} else t0 = $[2];
|
|
173
|
+
return t0;
|
|
174
|
+
}
|
|
175
|
+
function AddMemory(t0) {
|
|
176
|
+
const $ = c(29);
|
|
177
|
+
const { projectId } = t0;
|
|
178
|
+
const [text, setText] = React.useState("");
|
|
179
|
+
const refresh = useRefreshMemory(projectId);
|
|
180
|
+
let t1;
|
|
181
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
182
|
+
t1 = memoryMutations.add();
|
|
183
|
+
$[0] = t1;
|
|
184
|
+
} else t1 = $[0];
|
|
185
|
+
let t2;
|
|
186
|
+
if ($[1] !== refresh) {
|
|
187
|
+
t2 = {
|
|
188
|
+
...t1,
|
|
189
|
+
onSuccess: () => {
|
|
190
|
+
setText("");
|
|
191
|
+
refresh();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
$[1] = refresh;
|
|
195
|
+
$[2] = t2;
|
|
196
|
+
} else t2 = $[2];
|
|
197
|
+
const add = useMutation(t2);
|
|
198
|
+
let t3;
|
|
199
|
+
if ($[3] !== text) {
|
|
200
|
+
t3 = text.trim();
|
|
201
|
+
$[3] = text;
|
|
202
|
+
$[4] = t3;
|
|
203
|
+
} else t3 = $[4];
|
|
204
|
+
const trimmed = t3;
|
|
205
|
+
let t4;
|
|
206
|
+
if ($[5] !== add || $[6] !== projectId || $[7] !== trimmed) {
|
|
207
|
+
t4 = (event) => {
|
|
208
|
+
event.preventDefault();
|
|
209
|
+
if (trimmed) add.mutate({
|
|
210
|
+
projectId,
|
|
211
|
+
text: trimmed
|
|
212
|
+
});
|
|
213
|
+
};
|
|
214
|
+
$[5] = add;
|
|
215
|
+
$[6] = projectId;
|
|
216
|
+
$[7] = trimmed;
|
|
217
|
+
$[8] = t4;
|
|
218
|
+
} else t4 = $[8];
|
|
219
|
+
let t5;
|
|
220
|
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
|
221
|
+
t5 = /* @__PURE__ */ jsx("label", {
|
|
222
|
+
htmlFor: "camox-new-memory",
|
|
223
|
+
className: "sr-only",
|
|
224
|
+
children: "A new memory"
|
|
225
|
+
});
|
|
226
|
+
$[9] = t5;
|
|
227
|
+
} else t5 = $[9];
|
|
228
|
+
const t6 = add.error ? true : void 0;
|
|
229
|
+
let t7;
|
|
230
|
+
if ($[10] !== add) {
|
|
231
|
+
t7 = (event_0) => {
|
|
232
|
+
setText(event_0.target.value);
|
|
233
|
+
add.reset();
|
|
234
|
+
};
|
|
235
|
+
$[10] = add;
|
|
236
|
+
$[11] = t7;
|
|
237
|
+
} else t7 = $[11];
|
|
238
|
+
let t8;
|
|
239
|
+
if ($[12] !== add.isPending || $[13] !== t6 || $[14] !== t7 || $[15] !== text) {
|
|
240
|
+
t8 = /* @__PURE__ */ jsx(Textarea, {
|
|
241
|
+
id: "camox-new-memory",
|
|
242
|
+
placeholder: "Something Camox's agent should always know, such as a rule or how the business talks",
|
|
243
|
+
value: text,
|
|
244
|
+
"aria-invalid": t6,
|
|
245
|
+
disabled: add.isPending,
|
|
246
|
+
onChange: t7
|
|
247
|
+
});
|
|
248
|
+
$[12] = add.isPending;
|
|
249
|
+
$[13] = t6;
|
|
250
|
+
$[14] = t7;
|
|
251
|
+
$[15] = text;
|
|
252
|
+
$[16] = t8;
|
|
253
|
+
} else t8 = $[16];
|
|
254
|
+
let t9;
|
|
255
|
+
if ($[17] !== add.error) {
|
|
256
|
+
t9 = add.error && /* @__PURE__ */ jsx("p", {
|
|
257
|
+
"data-memory-error": true,
|
|
258
|
+
className: "text-destructive text-xs",
|
|
259
|
+
children: add.error.message
|
|
260
|
+
});
|
|
261
|
+
$[17] = add.error;
|
|
262
|
+
$[18] = t9;
|
|
263
|
+
} else t9 = $[18];
|
|
264
|
+
const t10 = !trimmed || add.isPending;
|
|
265
|
+
let t11;
|
|
266
|
+
if ($[19] !== add.isPending) {
|
|
267
|
+
t11 = add.isPending && /* @__PURE__ */ jsx(Spinner, {});
|
|
268
|
+
$[19] = add.isPending;
|
|
269
|
+
$[20] = t11;
|
|
270
|
+
} else t11 = $[20];
|
|
271
|
+
let t12;
|
|
272
|
+
if ($[21] !== t10 || $[22] !== t11) {
|
|
273
|
+
t12 = /* @__PURE__ */ jsxs(Button, {
|
|
274
|
+
type: "submit",
|
|
275
|
+
className: "self-start",
|
|
276
|
+
disabled: t10,
|
|
277
|
+
children: [t11, "Remember"]
|
|
278
|
+
});
|
|
279
|
+
$[21] = t10;
|
|
280
|
+
$[22] = t11;
|
|
281
|
+
$[23] = t12;
|
|
282
|
+
} else t12 = $[23];
|
|
283
|
+
let t13;
|
|
284
|
+
if ($[24] !== t12 || $[25] !== t4 || $[26] !== t8 || $[27] !== t9) {
|
|
285
|
+
t13 = /* @__PURE__ */ jsxs("form", {
|
|
286
|
+
className: "flex flex-col gap-2",
|
|
287
|
+
onSubmit: t4,
|
|
288
|
+
children: [
|
|
289
|
+
t5,
|
|
290
|
+
t8,
|
|
291
|
+
t9,
|
|
292
|
+
t12
|
|
293
|
+
]
|
|
294
|
+
});
|
|
295
|
+
$[24] = t12;
|
|
296
|
+
$[25] = t4;
|
|
297
|
+
$[26] = t8;
|
|
298
|
+
$[27] = t9;
|
|
299
|
+
$[28] = t13;
|
|
300
|
+
} else t13 = $[28];
|
|
301
|
+
return t13;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Opens the thread a memory's quote was said in: its draft's, beside the Canvas, or its
|
|
305
|
+
* Publication's once the draft was published (ADR 0045).
|
|
306
|
+
*/
|
|
307
|
+
function SourceThread(t0) {
|
|
308
|
+
const $ = c(9);
|
|
309
|
+
const { source } = t0;
|
|
310
|
+
const navigate = useNavigate();
|
|
311
|
+
const websiteHref = useWebsiteHref();
|
|
312
|
+
let t1;
|
|
313
|
+
if ($[0] !== navigate || $[1] !== source.draftId || $[2] !== source.published || $[3] !== websiteHref) {
|
|
314
|
+
t1 = () => {
|
|
315
|
+
if (source.published) {
|
|
316
|
+
studioStore.send({
|
|
317
|
+
type: "openDraftsSheet",
|
|
318
|
+
publicationId: source.draftId
|
|
319
|
+
});
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
previewStore.send({ type: "showCanvas" });
|
|
323
|
+
navigate({
|
|
324
|
+
to: websiteHref(),
|
|
325
|
+
draft: source.draftId
|
|
326
|
+
});
|
|
327
|
+
};
|
|
328
|
+
$[0] = navigate;
|
|
329
|
+
$[1] = source.draftId;
|
|
330
|
+
$[2] = source.published;
|
|
331
|
+
$[3] = websiteHref;
|
|
332
|
+
$[4] = t1;
|
|
333
|
+
} else t1 = $[4];
|
|
334
|
+
const open = t1;
|
|
335
|
+
let t2;
|
|
336
|
+
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
|
337
|
+
t2 = /* @__PURE__ */ jsx(MessagesSquare, {});
|
|
338
|
+
$[5] = t2;
|
|
339
|
+
} else t2 = $[5];
|
|
340
|
+
const t3 = source.published ? "See the published draft's thread" : "See the draft's thread";
|
|
341
|
+
let t4;
|
|
342
|
+
if ($[6] !== open || $[7] !== t3) {
|
|
343
|
+
t4 = /* @__PURE__ */ jsxs(Button, {
|
|
344
|
+
variant: "link",
|
|
345
|
+
size: "sm",
|
|
346
|
+
className: "h-auto px-0 text-xs",
|
|
347
|
+
onClick: open,
|
|
348
|
+
children: [t2, t3]
|
|
349
|
+
});
|
|
350
|
+
$[6] = open;
|
|
351
|
+
$[7] = t3;
|
|
352
|
+
$[8] = t4;
|
|
353
|
+
} else t4 = $[8];
|
|
354
|
+
return t4;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* One memory: its text, which opens to show where it came from (the quote and its thread, who
|
|
358
|
+
* taught it and when) and to edit or delete it.
|
|
359
|
+
*/
|
|
360
|
+
function MemoryRow(t0) {
|
|
361
|
+
const $ = c(42);
|
|
362
|
+
const { projectId, memory } = t0;
|
|
363
|
+
const [editing, setEditing] = React.useState(false);
|
|
364
|
+
const refresh = useRefreshMemory(projectId);
|
|
365
|
+
let t1;
|
|
366
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
367
|
+
t1 = memoryMutations.delete();
|
|
368
|
+
$[0] = t1;
|
|
369
|
+
} else t1 = $[0];
|
|
370
|
+
let t2;
|
|
371
|
+
if ($[1] !== refresh) {
|
|
372
|
+
t2 = {
|
|
373
|
+
...t1,
|
|
374
|
+
onSuccess: refresh
|
|
375
|
+
};
|
|
376
|
+
$[1] = refresh;
|
|
377
|
+
$[2] = t2;
|
|
378
|
+
} else t2 = $[2];
|
|
379
|
+
const remove = useMutation(t2);
|
|
380
|
+
const t3 = memory.id;
|
|
381
|
+
let t4;
|
|
382
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
383
|
+
t4 = /* @__PURE__ */ jsx(ChevronRight, { className: "text-muted-foreground mt-0.5 size-4 shrink-0 transition-transform duration-200 ease-out group-data-open/memory:rotate-90 motion-reduce:transition-none" });
|
|
384
|
+
$[3] = t4;
|
|
385
|
+
} else t4 = $[3];
|
|
386
|
+
let t5;
|
|
387
|
+
if ($[4] !== memory.text) {
|
|
388
|
+
t5 = /* @__PURE__ */ jsx(AccordionHeader, { children: /* @__PURE__ */ jsxs(AccordionTrigger, {
|
|
389
|
+
className: "hover:bg-muted/40 focus-visible:ring-ring/50 flex w-full items-start gap-2 px-4 py-3 text-left text-sm transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-inset",
|
|
390
|
+
children: [t4, /* @__PURE__ */ jsx("span", {
|
|
391
|
+
"data-memory-text": true,
|
|
392
|
+
className: "flex-1",
|
|
393
|
+
children: memory.text
|
|
394
|
+
})]
|
|
395
|
+
}) });
|
|
396
|
+
$[4] = memory.text;
|
|
397
|
+
$[5] = t5;
|
|
398
|
+
} else t5 = $[5];
|
|
399
|
+
let t6;
|
|
400
|
+
if ($[6] !== memory.source) {
|
|
401
|
+
t6 = memory.source.kind === "thread" && /* @__PURE__ */ jsxs("div", {
|
|
402
|
+
className: "flex flex-col items-start gap-1",
|
|
403
|
+
children: [/* @__PURE__ */ jsxs("blockquote", {
|
|
404
|
+
className: "text-muted-foreground border-l-2 pl-3 text-xs italic",
|
|
405
|
+
children: [
|
|
406
|
+
"“",
|
|
407
|
+
memory.source.quote,
|
|
408
|
+
"”"
|
|
409
|
+
]
|
|
410
|
+
}), /* @__PURE__ */ jsx(SourceThread, { source: memory.source })]
|
|
411
|
+
});
|
|
412
|
+
$[6] = memory.source;
|
|
413
|
+
$[7] = t6;
|
|
414
|
+
} else t6 = $[7];
|
|
415
|
+
const t7 = memory.source.kind === "studio" && "Written in the studio · ";
|
|
416
|
+
const t8 = memory.author.name;
|
|
417
|
+
let t9;
|
|
418
|
+
if ($[8] !== memory.createdAt) {
|
|
419
|
+
t9 = timeAgo(memory.createdAt);
|
|
420
|
+
$[8] = memory.createdAt;
|
|
421
|
+
$[9] = t9;
|
|
422
|
+
} else t9 = $[9];
|
|
423
|
+
let t10;
|
|
424
|
+
if ($[10] !== memory.author.name || $[11] !== t7 || $[12] !== t9) {
|
|
425
|
+
t10 = /* @__PURE__ */ jsxs("p", {
|
|
426
|
+
className: "text-muted-foreground text-xs",
|
|
427
|
+
children: [
|
|
428
|
+
t7,
|
|
429
|
+
t8,
|
|
430
|
+
" · ",
|
|
431
|
+
t9
|
|
432
|
+
]
|
|
433
|
+
});
|
|
434
|
+
$[10] = memory.author.name;
|
|
435
|
+
$[11] = t7;
|
|
436
|
+
$[12] = t9;
|
|
437
|
+
$[13] = t10;
|
|
438
|
+
} else t10 = $[13];
|
|
439
|
+
let t11;
|
|
440
|
+
if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
|
|
441
|
+
t11 = /* @__PURE__ */ jsxs(Button, {
|
|
442
|
+
variant: "outline",
|
|
443
|
+
size: "sm",
|
|
444
|
+
"aria-label": "Edit memory",
|
|
445
|
+
onClick: () => setEditing(true),
|
|
446
|
+
children: [/* @__PURE__ */ jsx(Pencil, { className: "text-muted-foreground" }), "Edit"]
|
|
447
|
+
});
|
|
448
|
+
$[14] = t11;
|
|
449
|
+
} else t11 = $[14];
|
|
450
|
+
let t12;
|
|
451
|
+
if ($[15] !== memory.id || $[16] !== projectId || $[17] !== remove) {
|
|
452
|
+
t12 = () => remove.mutate({
|
|
453
|
+
projectId,
|
|
454
|
+
id: memory.id
|
|
455
|
+
});
|
|
456
|
+
$[15] = memory.id;
|
|
457
|
+
$[16] = projectId;
|
|
458
|
+
$[17] = remove;
|
|
459
|
+
$[18] = t12;
|
|
460
|
+
} else t12 = $[18];
|
|
461
|
+
let t13;
|
|
462
|
+
if ($[19] !== remove.isPending) {
|
|
463
|
+
t13 = remove.isPending ? /* @__PURE__ */ jsx(Spinner, { className: "text-muted-foreground" }) : /* @__PURE__ */ jsx(Trash2, { className: "text-muted-foreground" });
|
|
464
|
+
$[19] = remove.isPending;
|
|
465
|
+
$[20] = t13;
|
|
466
|
+
} else t13 = $[20];
|
|
467
|
+
let t14;
|
|
468
|
+
if ($[21] !== remove.isPending || $[22] !== t12 || $[23] !== t13) {
|
|
469
|
+
t14 = /* @__PURE__ */ jsxs(ButtonGroup, { children: [t11, /* @__PURE__ */ jsxs(Button, {
|
|
470
|
+
variant: "outline",
|
|
471
|
+
size: "sm",
|
|
472
|
+
"aria-label": "Delete memory",
|
|
473
|
+
disabled: remove.isPending,
|
|
474
|
+
onClick: t12,
|
|
475
|
+
children: [t13, "Delete"]
|
|
476
|
+
})] });
|
|
477
|
+
$[21] = remove.isPending;
|
|
478
|
+
$[22] = t12;
|
|
479
|
+
$[23] = t13;
|
|
480
|
+
$[24] = t14;
|
|
481
|
+
} else t14 = $[24];
|
|
482
|
+
let t15;
|
|
483
|
+
if ($[25] !== remove.error) {
|
|
484
|
+
t15 = remove.error && /* @__PURE__ */ jsx("p", {
|
|
485
|
+
"data-memory-error": true,
|
|
486
|
+
className: "text-destructive text-xs",
|
|
487
|
+
children: remove.error.message
|
|
488
|
+
});
|
|
489
|
+
$[25] = remove.error;
|
|
490
|
+
$[26] = t15;
|
|
491
|
+
} else t15 = $[26];
|
|
492
|
+
let t16;
|
|
493
|
+
if ($[27] !== t10 || $[28] !== t14 || $[29] !== t15 || $[30] !== t6) {
|
|
494
|
+
t16 = /* @__PURE__ */ jsx(AccordionPanel, { children: /* @__PURE__ */ jsxs("div", {
|
|
495
|
+
"data-memory-details": true,
|
|
496
|
+
className: "flex flex-col items-start gap-3 pr-4 pb-3 pl-10",
|
|
497
|
+
children: [
|
|
498
|
+
t6,
|
|
499
|
+
t10,
|
|
500
|
+
t14,
|
|
501
|
+
t15
|
|
502
|
+
]
|
|
503
|
+
}) });
|
|
504
|
+
$[27] = t10;
|
|
505
|
+
$[28] = t14;
|
|
506
|
+
$[29] = t15;
|
|
507
|
+
$[30] = t6;
|
|
508
|
+
$[31] = t16;
|
|
509
|
+
} else t16 = $[31];
|
|
510
|
+
let t17;
|
|
511
|
+
if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
|
|
512
|
+
t17 = () => setEditing(false);
|
|
513
|
+
$[32] = t17;
|
|
514
|
+
} else t17 = $[32];
|
|
515
|
+
let t18;
|
|
516
|
+
if ($[33] !== editing || $[34] !== memory || $[35] !== projectId) {
|
|
517
|
+
t18 = /* @__PURE__ */ jsx(EditMemoryDialog, {
|
|
518
|
+
projectId,
|
|
519
|
+
memory,
|
|
520
|
+
open: editing,
|
|
521
|
+
onClose: t17
|
|
522
|
+
});
|
|
523
|
+
$[33] = editing;
|
|
524
|
+
$[34] = memory;
|
|
525
|
+
$[35] = projectId;
|
|
526
|
+
$[36] = t18;
|
|
527
|
+
} else t18 = $[36];
|
|
528
|
+
let t19;
|
|
529
|
+
if ($[37] !== memory.id || $[38] !== t16 || $[39] !== t18 || $[40] !== t5) {
|
|
530
|
+
t19 = /* @__PURE__ */ jsxs(AccordionItem, {
|
|
531
|
+
value: t3,
|
|
532
|
+
"data-memory": true,
|
|
533
|
+
className: "group/memory",
|
|
534
|
+
children: [
|
|
535
|
+
t5,
|
|
536
|
+
t16,
|
|
537
|
+
t18
|
|
538
|
+
]
|
|
539
|
+
});
|
|
540
|
+
$[37] = memory.id;
|
|
541
|
+
$[38] = t16;
|
|
542
|
+
$[39] = t18;
|
|
543
|
+
$[40] = t5;
|
|
544
|
+
$[41] = t19;
|
|
545
|
+
} else t19 = $[41];
|
|
546
|
+
return t19;
|
|
547
|
+
}
|
|
548
|
+
/** Edits a memory's text in a dialog, so the list keeps its layout. */
|
|
549
|
+
function EditMemoryDialog(t0) {
|
|
550
|
+
const $ = c(48);
|
|
551
|
+
const { projectId, memory, open, onClose } = t0;
|
|
552
|
+
const [text, setText] = React.useState(memory.text);
|
|
553
|
+
const field = React.useRef(null);
|
|
554
|
+
const refresh = useRefreshMemory(projectId);
|
|
555
|
+
let t1;
|
|
556
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
557
|
+
t1 = memoryMutations.change();
|
|
558
|
+
$[0] = t1;
|
|
559
|
+
} else t1 = $[0];
|
|
560
|
+
let t2;
|
|
561
|
+
if ($[1] !== onClose || $[2] !== refresh) {
|
|
562
|
+
t2 = {
|
|
563
|
+
...t1,
|
|
564
|
+
onSuccess: () => {
|
|
565
|
+
onClose();
|
|
566
|
+
refresh();
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
$[1] = onClose;
|
|
570
|
+
$[2] = refresh;
|
|
571
|
+
$[3] = t2;
|
|
572
|
+
} else t2 = $[3];
|
|
573
|
+
const change = useMutation(t2);
|
|
574
|
+
let t3;
|
|
575
|
+
if ($[4] !== text) {
|
|
576
|
+
t3 = text.trim();
|
|
577
|
+
$[4] = text;
|
|
578
|
+
$[5] = t3;
|
|
579
|
+
} else t3 = $[5];
|
|
580
|
+
const trimmed = t3;
|
|
581
|
+
const [wasOpen, setWasOpen] = React.useState(open);
|
|
582
|
+
if (open !== wasOpen) {
|
|
583
|
+
setWasOpen(open);
|
|
584
|
+
if (open) setText(memory.text);
|
|
585
|
+
}
|
|
586
|
+
let t4;
|
|
587
|
+
if ($[6] !== change || $[7] !== onClose) {
|
|
588
|
+
t4 = () => {
|
|
589
|
+
change.reset();
|
|
590
|
+
onClose();
|
|
591
|
+
};
|
|
592
|
+
$[6] = change;
|
|
593
|
+
$[7] = onClose;
|
|
594
|
+
$[8] = t4;
|
|
595
|
+
} else t4 = $[8];
|
|
596
|
+
const close = t4;
|
|
597
|
+
let t5;
|
|
598
|
+
if ($[9] !== change.isPending || $[10] !== close) {
|
|
599
|
+
t5 = (next) => {
|
|
600
|
+
if (!next && !change.isPending) close();
|
|
601
|
+
};
|
|
602
|
+
$[9] = change.isPending;
|
|
603
|
+
$[10] = close;
|
|
604
|
+
$[11] = t5;
|
|
605
|
+
} else t5 = $[11];
|
|
606
|
+
let t6;
|
|
607
|
+
if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
|
|
608
|
+
t6 = () => {
|
|
609
|
+
field.current?.select();
|
|
610
|
+
return field.current;
|
|
611
|
+
};
|
|
612
|
+
$[12] = t6;
|
|
613
|
+
} else t6 = $[12];
|
|
614
|
+
let t7;
|
|
615
|
+
if ($[13] !== change || $[14] !== memory.id || $[15] !== projectId || $[16] !== trimmed) {
|
|
616
|
+
t7 = (event) => {
|
|
617
|
+
event.preventDefault();
|
|
618
|
+
if (trimmed) change.mutate({
|
|
619
|
+
projectId,
|
|
620
|
+
id: memory.id,
|
|
621
|
+
text: trimmed
|
|
622
|
+
});
|
|
623
|
+
};
|
|
624
|
+
$[13] = change;
|
|
625
|
+
$[14] = memory.id;
|
|
626
|
+
$[15] = projectId;
|
|
627
|
+
$[16] = trimmed;
|
|
628
|
+
$[17] = t7;
|
|
629
|
+
} else t7 = $[17];
|
|
630
|
+
let t8;
|
|
631
|
+
if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
|
|
632
|
+
t8 = /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Edit memory" }), /* @__PURE__ */ jsx(DialogDescription, { children: "The change is made in a draft, and reaches the live website when the draft is published." })] });
|
|
633
|
+
$[18] = t8;
|
|
634
|
+
} else t8 = $[18];
|
|
635
|
+
const t9 = change.error ? true : void 0;
|
|
636
|
+
let t10;
|
|
637
|
+
if ($[19] !== change) {
|
|
638
|
+
t10 = (event_0) => {
|
|
639
|
+
setText(event_0.target.value);
|
|
640
|
+
change.reset();
|
|
641
|
+
};
|
|
642
|
+
$[19] = change;
|
|
643
|
+
$[20] = t10;
|
|
644
|
+
} else t10 = $[20];
|
|
645
|
+
let t11;
|
|
646
|
+
if ($[21] !== change.isPending || $[22] !== t10 || $[23] !== t9 || $[24] !== text) {
|
|
647
|
+
t11 = /* @__PURE__ */ jsx(Textarea, {
|
|
648
|
+
ref: field,
|
|
649
|
+
"aria-label": "Memory",
|
|
650
|
+
value: text,
|
|
651
|
+
"aria-invalid": t9,
|
|
652
|
+
disabled: change.isPending,
|
|
653
|
+
onChange: t10
|
|
654
|
+
});
|
|
655
|
+
$[21] = change.isPending;
|
|
656
|
+
$[22] = t10;
|
|
657
|
+
$[23] = t9;
|
|
658
|
+
$[24] = text;
|
|
659
|
+
$[25] = t11;
|
|
660
|
+
} else t11 = $[25];
|
|
661
|
+
let t12;
|
|
662
|
+
if ($[26] !== change.error) {
|
|
663
|
+
t12 = change.error && /* @__PURE__ */ jsx("p", {
|
|
664
|
+
"data-memory-error": true,
|
|
665
|
+
className: "text-destructive text-xs",
|
|
666
|
+
children: change.error.message
|
|
667
|
+
});
|
|
668
|
+
$[26] = change.error;
|
|
669
|
+
$[27] = t12;
|
|
670
|
+
} else t12 = $[27];
|
|
671
|
+
let t13;
|
|
672
|
+
if ($[28] !== change.isPending || $[29] !== close) {
|
|
673
|
+
t13 = /* @__PURE__ */ jsx(Button, {
|
|
674
|
+
type: "button",
|
|
675
|
+
variant: "outline",
|
|
676
|
+
disabled: change.isPending,
|
|
677
|
+
onClick: close,
|
|
678
|
+
children: "Cancel"
|
|
679
|
+
});
|
|
680
|
+
$[28] = change.isPending;
|
|
681
|
+
$[29] = close;
|
|
682
|
+
$[30] = t13;
|
|
683
|
+
} else t13 = $[30];
|
|
684
|
+
const t14 = !trimmed || change.isPending;
|
|
685
|
+
let t15;
|
|
686
|
+
if ($[31] !== change.isPending) {
|
|
687
|
+
t15 = change.isPending && /* @__PURE__ */ jsx(Spinner, {});
|
|
688
|
+
$[31] = change.isPending;
|
|
689
|
+
$[32] = t15;
|
|
690
|
+
} else t15 = $[32];
|
|
691
|
+
let t16;
|
|
692
|
+
if ($[33] !== t14 || $[34] !== t15) {
|
|
693
|
+
t16 = /* @__PURE__ */ jsxs(Button, {
|
|
694
|
+
type: "submit",
|
|
695
|
+
disabled: t14,
|
|
696
|
+
children: [t15, "Save"]
|
|
697
|
+
});
|
|
698
|
+
$[33] = t14;
|
|
699
|
+
$[34] = t15;
|
|
700
|
+
$[35] = t16;
|
|
701
|
+
} else t16 = $[35];
|
|
702
|
+
let t17;
|
|
703
|
+
if ($[36] !== t13 || $[37] !== t16) {
|
|
704
|
+
t17 = /* @__PURE__ */ jsxs(DialogFooter, { children: [t13, t16] });
|
|
705
|
+
$[36] = t13;
|
|
706
|
+
$[37] = t16;
|
|
707
|
+
$[38] = t17;
|
|
708
|
+
} else t17 = $[38];
|
|
709
|
+
let t18;
|
|
710
|
+
if ($[39] !== t11 || $[40] !== t12 || $[41] !== t17 || $[42] !== t7) {
|
|
711
|
+
t18 = /* @__PURE__ */ jsx(DialogContent, {
|
|
712
|
+
className: "sm:max-w-lg",
|
|
713
|
+
initialFocus: t6,
|
|
714
|
+
children: /* @__PURE__ */ jsxs("form", {
|
|
715
|
+
className: "flex flex-col gap-4",
|
|
716
|
+
onSubmit: t7,
|
|
717
|
+
children: [
|
|
718
|
+
t8,
|
|
719
|
+
t11,
|
|
720
|
+
t12,
|
|
721
|
+
t17
|
|
722
|
+
]
|
|
723
|
+
})
|
|
724
|
+
});
|
|
725
|
+
$[39] = t11;
|
|
726
|
+
$[40] = t12;
|
|
727
|
+
$[41] = t17;
|
|
728
|
+
$[42] = t7;
|
|
729
|
+
$[43] = t18;
|
|
730
|
+
} else t18 = $[43];
|
|
731
|
+
let t19;
|
|
732
|
+
if ($[44] !== open || $[45] !== t18 || $[46] !== t5) {
|
|
733
|
+
t19 = /* @__PURE__ */ jsx(Dialog, {
|
|
734
|
+
open,
|
|
735
|
+
onOpenChange: t5,
|
|
736
|
+
children: t18
|
|
737
|
+
});
|
|
738
|
+
$[44] = open;
|
|
739
|
+
$[45] = t18;
|
|
740
|
+
$[46] = t5;
|
|
741
|
+
$[47] = t19;
|
|
742
|
+
} else t19 = $[47];
|
|
743
|
+
return t19;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
//#endregion
|
|
747
|
+
export { CamoxMemory };
|