camox 0.26.0 → 0.28.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 (30) hide show
  1. package/dist/core/components/lexical/InlineLexicalEditor.js +14 -11
  2. package/dist/core/components/lexical/SidebarLexicalEditor.js +10 -7
  3. package/dist/features/preview/CamoxPreview.d.ts +1 -0
  4. package/dist/features/preview/CamoxPreview.js +507 -147
  5. package/dist/features/preview/components/AssetLightbox.js +1 -1
  6. package/dist/features/preview/components/BlockActionsPopover.js +1 -1
  7. package/dist/features/preview/components/CreatePageModal.js +23 -8
  8. package/dist/features/preview/components/FieldToolbar.js +1 -1
  9. package/dist/features/preview/components/LinkFieldEditor.js +192 -204
  10. package/dist/features/preview/components/PageContentSheet.js +1 -1
  11. package/dist/features/preview/components/PageLocationFieldset.js +3 -4
  12. package/dist/features/preview/components/{EditPageModal.js → PageMetadataModal.js} +413 -229
  13. package/dist/features/preview/components/PageNicknameField.js +69 -0
  14. package/dist/features/preview/components/PagePicker.js +21 -84
  15. package/dist/features/preview/components/PageStatusBadge.js +97 -0
  16. package/dist/features/preview/components/PreviewPanel.js +111 -117
  17. package/dist/features/preview/components/PreviewToolbar.js +4 -4
  18. package/dist/features/preview/components/PublishDialog.js +1 -1
  19. package/dist/features/preview/components/UnlinkAssetButton.js +1 -1
  20. package/dist/features/routes/pageRoute.d.ts +3 -1
  21. package/dist/features/routes/pageRoute.js +34 -11
  22. package/dist/features/studio/components/EnvironmentMenu.js +1 -1
  23. package/dist/features/studio/components/ProjectMenu.js +1 -1
  24. package/dist/features/studio/components/UserButton.js +1 -1
  25. package/dist/lib/auth.js +43 -15
  26. package/dist/lib/queries.js +1 -0
  27. package/dist/lib/utils.js +1 -11
  28. package/dist/studio.css +1 -1
  29. package/package.json +4 -4
  30. package/skills/camox-cli/SKILL.md +79 -12
@@ -1,9 +1,10 @@
1
+ import { trackClientEvent } from "../../lib/telemetry-client.js";
1
2
  import { previewStore } from "./previewStore.js";
2
3
  import { actionsStore } from "../provider/actionsStore.js";
3
4
  import { useIsAuthenticated, useProjectSlug } from "../../lib/auth.js";
4
5
  import { getApiClient } from "../../lib/api-client.js";
5
- import { blockQueries, pageQueries, projectQueries } from "../../lib/queries.js";
6
- import { cn, formatPathSegment } from "../../lib/utils.js";
6
+ import { blockQueries, pageMutations, pageQueries, projectQueries } from "../../lib/queries.js";
7
+ import { cn } from "../../lib/utils.js";
7
8
  import { NormalizedDataProvider, seedBlockCaches, usePageBlocks } from "../../lib/normalized-data.js";
8
9
  import { BlockErrorBoundary } from "./components/BlockErrorBoundary.js";
9
10
  import { useCamoxApp } from "../provider/components/CamoxAppContext.js";
@@ -12,8 +13,8 @@ import { AddBlockSheet } from "./components/AddBlockSheet.js";
12
13
  import { AgentChatSheet } from "./components/AgentChatSheet.js";
13
14
  import { CreatePageModal } from "./components/CreatePageModal.js";
14
15
  import { DraftSwitchDialog } from "./components/DraftSwitchDialog.js";
15
- import { EditPageModal } from "./components/EditPageModal.js";
16
16
  import { PageContentSheet } from "./components/PageContentSheet.js";
17
+ import { PageMetadataModal } from "./components/PageMetadataModal.js";
17
18
  import { PagePicker } from "./components/PagePicker.js";
18
19
  import { PageTree } from "./components/PageTree.js";
19
20
  import { PeekedBlock } from "./components/PeekedBlock.js";
@@ -21,17 +22,21 @@ import { PreviewFrame, PreviewPanel } from "./components/PreviewPanel.js";
21
22
  import { PublishDialog } from "./components/PublishDialog.js";
22
23
  import { c } from "react/compiler-runtime";
23
24
  import { Label } from "@camox/ui/label";
24
- import { keepPreviousData, useQuery, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
25
+ import { toast } from "@camox/ui/toaster";
26
+ import { keepPreviousData, useMutation, useQuery, useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
25
27
  import { useLocation, useNavigate } from "@tanstack/react-router";
26
28
  import { useSelector } from "@xstate/store-react";
27
29
  import * as React from "react";
28
30
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
29
31
  import { queryKeys } from "@camox/api-contract/query-keys";
32
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@camox/ui/alert-dialog";
30
33
  import { Button } from "@camox/ui/button";
34
+ import { ButtonGroup } from "@camox/ui/button-group";
35
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@camox/ui/dropdown-menu";
31
36
  import { PanelContent, PanelHeader } from "@camox/ui/panel";
32
37
  import { Switch } from "@camox/ui/switch";
33
38
  import { Tooltip, TooltipContent, TooltipTrigger } from "@camox/ui/tooltip";
34
- import { Info } from "lucide-react";
39
+ import { Info, MoreHorizontal } from "lucide-react";
35
40
 
36
41
  //#region src/features/preview/CamoxPreview.tsx
37
42
  /**
@@ -81,9 +86,9 @@ function pageFullQueryFn(queryClient, path, projectSlug, source) {
81
86
  }
82
87
  function usePreviewedPage() {
83
88
  const $ = c(26);
84
- if ($[0] !== "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8") {
89
+ if ($[0] !== "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b") {
85
90
  for (let $i = 0; $i < 26; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
86
- $[0] = "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8";
91
+ $[0] = "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b";
87
92
  }
88
93
  const { pathname } = useLocation();
89
94
  const queryClient = useQueryClient();
@@ -180,9 +185,9 @@ function _temp(state) {
180
185
  }
181
186
  const BlockRenderer = (t0) => {
182
187
  const $ = c(23);
183
- if ($[0] !== "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8") {
188
+ if ($[0] !== "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b") {
184
189
  for (let $i = 0; $i < 23; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
185
- $[0] = "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8";
190
+ $[0] = "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b";
186
191
  }
187
192
  const { blockId, mode, showAddBlockTop, showAddBlockBottom } = t0;
188
193
  const previewSource = useSelector(previewStore, _temp3);
@@ -324,10 +329,10 @@ const PageContent = () => {
324
329
  });
325
330
  };
326
331
  const SidebarPublishRow = (t0) => {
327
- const $ = c(30);
328
- if ($[0] !== "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8") {
329
- for (let $i = 0; $i < 30; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
330
- $[0] = "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8";
332
+ const $ = c(100);
333
+ if ($[0] !== "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b") {
334
+ for (let $i = 0; $i < 100; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
335
+ $[0] = "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b";
331
336
  }
332
337
  const { page } = t0;
333
338
  const previewSource = useSelector(previewStore, _temp4);
@@ -335,12 +340,26 @@ const SidebarPublishRow = (t0) => {
335
340
  const projectSlug = useProjectSlug();
336
341
  const { pathname } = useLocation();
337
342
  const [isPublishDialogOpen, setIsPublishDialogOpen] = React.useState(false);
343
+ const [isUnpublishDialogOpen, setIsUnpublishDialogOpen] = React.useState(false);
344
+ const [isDiscardDialogOpen, setIsDiscardDialogOpen] = React.useState(false);
345
+ let t1;
346
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
347
+ t1 = pageMutations.unpublish();
348
+ $[1] = t1;
349
+ } else t1 = $[1];
350
+ const unpublishPage = useMutation(t1);
351
+ let t2;
352
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
353
+ t2 = pageMutations.discardChanges();
354
+ $[2] = t2;
355
+ } else t2 = $[2];
356
+ const discardChanges = useMutation(t2);
338
357
  const hasLiveCheckpoint = page.livePublishedCheckpointId != null;
339
358
  const otherSource = previewSource === "draft" ? "live" : "draft";
340
359
  const canPrefetchOther = otherSource === "draft" || hasLiveCheckpoint;
341
- let t1;
342
- if ($[1] !== canPrefetchOther || $[2] !== otherSource || $[3] !== pathname || $[4] !== projectSlug || $[5] !== queryClient) {
343
- t1 = () => {
360
+ let t3;
361
+ if ($[3] !== canPrefetchOther || $[4] !== otherSource || $[5] !== pathname || $[6] !== projectSlug || $[7] !== queryClient) {
362
+ t3 = () => {
344
363
  if (!canPrefetchOther) return;
345
364
  queryClient.prefetchQuery({
346
365
  queryKey: queryKeys.pages.getByPath(pathname, otherSource),
@@ -348,117 +367,444 @@ const SidebarPublishRow = (t0) => {
348
367
  staleTime: Infinity
349
368
  });
350
369
  };
351
- $[1] = canPrefetchOther;
352
- $[2] = otherSource;
353
- $[3] = pathname;
354
- $[4] = projectSlug;
355
- $[5] = queryClient;
356
- $[6] = t1;
357
- } else t1 = $[6];
358
- const prefetchOtherSource = t1;
370
+ $[3] = canPrefetchOther;
371
+ $[4] = otherSource;
372
+ $[5] = pathname;
373
+ $[6] = projectSlug;
374
+ $[7] = queryClient;
375
+ $[8] = t3;
376
+ } else t3 = $[8];
377
+ const prefetchOtherSource = t3;
359
378
  const canPublish = (page.status === "draft" || page.status === "modified") && previewSource === "draft";
360
- let t2;
361
- if ($[7] !== page.modifiedReason) {
362
- t2 = page.modifiedReason && (page.modifiedReason.reason === "layout" || page.modifiedReason.reason === "both") ? {
379
+ const canDiscardChanges = page.status === "modified";
380
+ let t4;
381
+ if ($[9] !== page.modifiedReason) {
382
+ t4 = page.modifiedReason && (page.modifiedReason.reason === "layout" || page.modifiedReason.reason === "both") ? {
363
383
  layoutHandle: page.modifiedReason.layoutHandle,
364
384
  affectedPagesCount: page.modifiedReason.affectedPagesCount
365
385
  } : null;
366
- $[7] = page.modifiedReason;
367
- $[8] = t2;
368
- } else t2 = $[8];
369
- const layoutCascade = t2;
370
- const t3 = !hasLiveCheckpoint;
371
- const t4 = previewSource === "draft";
386
+ $[9] = page.modifiedReason;
387
+ $[10] = t4;
388
+ } else t4 = $[10];
389
+ const layoutCascade = t4;
390
+ const publishLabel = page.status === "modified" ? "Publish changes" : "Publish page";
372
391
  let t5;
373
- if ($[9] !== t3 || $[10] !== t4) {
374
- t5 = /* @__PURE__ */ jsx(Switch, {
392
+ let t6;
393
+ if ($[11] !== canDiscardChanges || $[12] !== canPublish || $[13] !== discardChanges.isPending || $[14] !== hasLiveCheckpoint || $[15] !== publishLabel || $[16] !== unpublishPage.isPending) {
394
+ t5 = () => {
395
+ const actions = [
396
+ {
397
+ id: "publish-current-page",
398
+ label: publishLabel,
399
+ groupLabel: "Preview",
400
+ checkIfAvailable: () => canPublish,
401
+ execute: () => setIsPublishDialogOpen(true)
402
+ },
403
+ {
404
+ id: "unpublish-current-page",
405
+ label: "Unpublish page",
406
+ groupLabel: "Preview",
407
+ checkIfAvailable: () => hasLiveCheckpoint && !unpublishPage.isPending,
408
+ execute: () => setIsUnpublishDialogOpen(true)
409
+ },
410
+ {
411
+ id: "discard-current-page-changes",
412
+ label: "Discard page changes",
413
+ groupLabel: "Preview",
414
+ checkIfAvailable: () => canDiscardChanges && !discardChanges.isPending,
415
+ execute: () => setIsDiscardDialogOpen(true)
416
+ }
417
+ ];
418
+ actionsStore.send({
419
+ type: "registerManyActions",
420
+ actions
421
+ });
422
+ return () => {
423
+ actionsStore.send({
424
+ type: "unregisterManyActions",
425
+ ids: actions.map(_temp5)
426
+ });
427
+ };
428
+ };
429
+ t6 = [
430
+ canDiscardChanges,
431
+ canPublish,
432
+ discardChanges.isPending,
433
+ hasLiveCheckpoint,
434
+ publishLabel,
435
+ unpublishPage.isPending
436
+ ];
437
+ $[11] = canDiscardChanges;
438
+ $[12] = canPublish;
439
+ $[13] = discardChanges.isPending;
440
+ $[14] = hasLiveCheckpoint;
441
+ $[15] = publishLabel;
442
+ $[16] = unpublishPage.isPending;
443
+ $[17] = t5;
444
+ $[18] = t6;
445
+ } else {
446
+ t5 = $[17];
447
+ t6 = $[18];
448
+ }
449
+ React.useEffect(t5, t6);
450
+ let t7;
451
+ if ($[19] !== page.id || $[20] !== pathname || $[21] !== queryClient || $[22] !== unpublishPage) {
452
+ t7 = async () => {
453
+ try {
454
+ await unpublishPage.mutateAsync({ id: page.id });
455
+ queryClient.setQueryData(queryKeys.pages.getByPath(pathname, "draft"), _temp6);
456
+ queryClient.setQueryData(queryKeys.pages.list, (current_0) => current_0?.map((item) => item.id === page.id ? {
457
+ ...item,
458
+ livePublishedCheckpointId: null,
459
+ status: "draft",
460
+ modifiedReason: null
461
+ } : item));
462
+ previewStore.send({
463
+ type: "setPreviewSource",
464
+ source: "draft"
465
+ });
466
+ trackClientEvent("page_unpublished", { pageId: page.id });
467
+ toast.success("Unpublished this page");
468
+ setIsUnpublishDialogOpen(false);
469
+ } catch (t8) {
470
+ console.error("Failed to unpublish page:", t8);
471
+ toast.error("Could not unpublish this page");
472
+ }
473
+ };
474
+ $[19] = page.id;
475
+ $[20] = pathname;
476
+ $[21] = queryClient;
477
+ $[22] = unpublishPage;
478
+ $[23] = t7;
479
+ } else t7 = $[23];
480
+ const handleUnpublish = t7;
481
+ let t8;
482
+ if ($[24] !== discardChanges || $[25] !== page.id) {
483
+ t8 = async () => {
484
+ try {
485
+ await discardChanges.mutateAsync({ id: page.id });
486
+ previewStore.send({
487
+ type: "setPreviewSource",
488
+ source: "draft"
489
+ });
490
+ trackClientEvent("page_changes_discarded", { pageId: page.id });
491
+ toast.success("Discarded draft changes");
492
+ setIsDiscardDialogOpen(false);
493
+ } catch (t9) {
494
+ console.error("Failed to discard page changes:", t9);
495
+ toast.error("Could not discard draft changes");
496
+ }
497
+ };
498
+ $[24] = discardChanges;
499
+ $[25] = page.id;
500
+ $[26] = t8;
501
+ } else t8 = $[26];
502
+ const handleDiscardChanges = t8;
503
+ const t9 = !canPublish;
504
+ let t10;
505
+ if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
506
+ t10 = () => setIsPublishDialogOpen(true);
507
+ $[27] = t10;
508
+ } else t10 = $[27];
509
+ let t11;
510
+ if ($[28] !== publishLabel || $[29] !== t9) {
511
+ t11 = /* @__PURE__ */ jsx(Button, {
512
+ variant: "outline",
513
+ type: "button",
514
+ disabled: t9,
515
+ onClick: t10,
516
+ className: "flex-1",
517
+ children: publishLabel
518
+ });
519
+ $[28] = publishLabel;
520
+ $[29] = t9;
521
+ $[30] = t11;
522
+ } else t11 = $[30];
523
+ let t12;
524
+ if ($[31] === Symbol.for("react.memo_cache_sentinel")) {
525
+ t12 = /* @__PURE__ */ jsx(DropdownMenuTrigger, {
526
+ render: /* @__PURE__ */ jsx(Button, {
527
+ type: "button",
528
+ variant: "outline",
529
+ size: "icon",
530
+ "aria-label": "More publish actions"
531
+ }),
532
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "text-muted-foreground" })
533
+ });
534
+ $[31] = t12;
535
+ } else t12 = $[31];
536
+ const t13 = !hasLiveCheckpoint || unpublishPage.isPending;
537
+ let t14;
538
+ if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
539
+ t14 = () => setIsUnpublishDialogOpen(true);
540
+ $[32] = t14;
541
+ } else t14 = $[32];
542
+ let t15;
543
+ if ($[33] !== t13) {
544
+ t15 = /* @__PURE__ */ jsx(DropdownMenuItem, {
545
+ disabled: t13,
546
+ onClick: t14,
547
+ children: "Unpublish"
548
+ });
549
+ $[33] = t13;
550
+ $[34] = t15;
551
+ } else t15 = $[34];
552
+ const t16 = !canDiscardChanges || discardChanges.isPending;
553
+ let t17;
554
+ if ($[35] === Symbol.for("react.memo_cache_sentinel")) {
555
+ t17 = () => setIsDiscardDialogOpen(true);
556
+ $[35] = t17;
557
+ } else t17 = $[35];
558
+ let t18;
559
+ if ($[36] !== t16) {
560
+ t18 = /* @__PURE__ */ jsx(DropdownMenuItem, {
561
+ disabled: t16,
562
+ onClick: t17,
563
+ children: "Discard changes"
564
+ });
565
+ $[36] = t16;
566
+ $[37] = t18;
567
+ } else t18 = $[37];
568
+ let t19;
569
+ if ($[38] !== t15 || $[39] !== t18) {
570
+ t19 = /* @__PURE__ */ jsxs(DropdownMenu, { children: [t12, /* @__PURE__ */ jsxs(DropdownMenuContent, {
571
+ align: "end",
572
+ className: "w-42",
573
+ children: [t15, t18]
574
+ })] });
575
+ $[38] = t15;
576
+ $[39] = t18;
577
+ $[40] = t19;
578
+ } else t19 = $[40];
579
+ let t20;
580
+ if ($[41] !== t11 || $[42] !== t19) {
581
+ t20 = /* @__PURE__ */ jsxs(ButtonGroup, {
582
+ className: "w-full",
583
+ children: [t11, t19]
584
+ });
585
+ $[41] = t11;
586
+ $[42] = t19;
587
+ $[43] = t20;
588
+ } else t20 = $[43];
589
+ const t21 = !hasLiveCheckpoint;
590
+ const t22 = previewSource === "draft";
591
+ let t23;
592
+ if ($[44] !== t21 || $[45] !== t22) {
593
+ t23 = /* @__PURE__ */ jsx(Switch, {
375
594
  id: "draft-content",
376
- disabled: t3,
377
- checked: t4,
378
- onCheckedChange: _temp5
595
+ disabled: t21,
596
+ checked: t22,
597
+ onCheckedChange: _temp7
379
598
  });
380
- $[9] = t3;
381
- $[10] = t4;
382
- $[11] = t5;
383
- } else t5 = $[11];
384
- let t6;
385
- if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
386
- t6 = /* @__PURE__ */ jsx(Label, {
599
+ $[44] = t21;
600
+ $[45] = t22;
601
+ $[46] = t23;
602
+ } else t23 = $[46];
603
+ let t24;
604
+ if ($[47] === Symbol.for("react.memo_cache_sentinel")) {
605
+ t24 = /* @__PURE__ */ jsx(Label, {
387
606
  htmlFor: "draft-content",
388
607
  children: "Draft content"
389
608
  });
390
- $[12] = t6;
391
- } else t6 = $[12];
392
- let t7;
393
- if ($[13] !== prefetchOtherSource || $[14] !== t5) {
394
- t7 = /* @__PURE__ */ jsxs("div", {
395
- className: "flex items-center gap-2",
609
+ $[47] = t24;
610
+ } else t24 = $[47];
611
+ let t25;
612
+ if ($[48] !== prefetchOtherSource || $[49] !== t23) {
613
+ t25 = /* @__PURE__ */ jsxs("div", {
614
+ className: "mt-1 flex items-center gap-2",
396
615
  onMouseEnter: prefetchOtherSource,
397
616
  onFocus: prefetchOtherSource,
398
- children: [t5, t6]
617
+ children: [t23, t24]
399
618
  });
400
- $[13] = prefetchOtherSource;
401
- $[14] = t5;
402
- $[15] = t7;
403
- } else t7 = $[15];
404
- const t8 = !canPublish;
405
- let t9;
406
- if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
407
- t9 = () => setIsPublishDialogOpen(true);
408
- $[16] = t9;
409
- } else t9 = $[16];
410
- let t10;
411
- if ($[17] !== t8) {
412
- t10 = /* @__PURE__ */ jsx(Button, {
413
- type: "button",
414
- size: "sm",
415
- disabled: t8,
416
- onClick: t9,
417
- children: "Publish"
619
+ $[48] = prefetchOtherSource;
620
+ $[49] = t23;
621
+ $[50] = t25;
622
+ } else t25 = $[50];
623
+ let t26;
624
+ if ($[51] !== t20 || $[52] !== t25) {
625
+ t26 = /* @__PURE__ */ jsxs("div", {
626
+ className: "flex flex-col gap-2",
627
+ children: [t20, t25]
418
628
  });
419
- $[17] = t8;
420
- $[18] = t10;
421
- } else t10 = $[18];
422
- let t11;
423
- if ($[19] !== t10 || $[20] !== t7) {
424
- t11 = /* @__PURE__ */ jsxs("div", {
425
- className: "flex items-center justify-between gap-2",
426
- children: [t7, t10]
427
- });
428
- $[19] = t10;
429
- $[20] = t7;
430
- $[21] = t11;
431
- } else t11 = $[21];
432
- const t12 = isPublishDialogOpen ? page : null;
433
- let t13;
434
- if ($[22] !== isPublishDialogOpen || $[23] !== layoutCascade || $[24] !== page.status || $[25] !== t12) {
435
- t13 = /* @__PURE__ */ jsx(PublishDialog, {
436
- page: t12,
629
+ $[51] = t20;
630
+ $[52] = t25;
631
+ $[53] = t26;
632
+ } else t26 = $[53];
633
+ const t27 = isPublishDialogOpen ? page : null;
634
+ let t28;
635
+ if ($[54] !== isPublishDialogOpen || $[55] !== layoutCascade || $[56] !== page.status || $[57] !== t27) {
636
+ t28 = /* @__PURE__ */ jsx(PublishDialog, {
637
+ page: t27,
437
638
  pageStatus: page.status,
438
639
  alsoPublishLayout: layoutCascade,
439
640
  open: isPublishDialogOpen,
440
641
  onOpenChange: setIsPublishDialogOpen
441
642
  });
442
- $[22] = isPublishDialogOpen;
443
- $[23] = layoutCascade;
444
- $[24] = page.status;
445
- $[25] = t12;
446
- $[26] = t13;
447
- } else t13 = $[26];
448
- let t14;
449
- if ($[27] !== t11 || $[28] !== t13) {
450
- t14 = /* @__PURE__ */ jsxs(Fragment, { children: [t11, t13] });
451
- $[27] = t11;
452
- $[28] = t13;
453
- $[29] = t14;
454
- } else t14 = $[29];
455
- return t14;
643
+ $[54] = isPublishDialogOpen;
644
+ $[55] = layoutCascade;
645
+ $[56] = page.status;
646
+ $[57] = t27;
647
+ $[58] = t28;
648
+ } else t28 = $[58];
649
+ let t29;
650
+ if ($[59] === Symbol.for("react.memo_cache_sentinel")) {
651
+ t29 = /* @__PURE__ */ jsx(AlertDialogTitle, { children: "Unpublish page" });
652
+ $[59] = t29;
653
+ } else t29 = $[59];
654
+ let t30;
655
+ if ($[60] !== page.fullPath) {
656
+ t30 = /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [t29, /* @__PURE__ */ jsxs(AlertDialogDescription, { children: [
657
+ "Visitors at",
658
+ " ",
659
+ /* @__PURE__ */ jsx("code", {
660
+ className: "bg-muted rounded px-1 py-0.5 font-mono text-xs",
661
+ children: page.fullPath
662
+ }),
663
+ " ",
664
+ "will get a 404. The draft stays available in Camox Studio."
665
+ ] })] });
666
+ $[60] = page.fullPath;
667
+ $[61] = t30;
668
+ } else t30 = $[61];
669
+ let t31;
670
+ if ($[62] !== unpublishPage.isPending) {
671
+ t31 = /* @__PURE__ */ jsx(AlertDialogCancel, {
672
+ variant: "outline",
673
+ size: "default",
674
+ disabled: unpublishPage.isPending,
675
+ children: "Cancel"
676
+ });
677
+ $[62] = unpublishPage.isPending;
678
+ $[63] = t31;
679
+ } else t31 = $[63];
680
+ const t32 = unpublishPage.isPending ? "Unpublishing…" : "Unpublish";
681
+ let t33;
682
+ if ($[64] !== handleUnpublish || $[65] !== t32 || $[66] !== unpublishPage.isPending) {
683
+ t33 = /* @__PURE__ */ jsx(AlertDialogAction, {
684
+ onClick: handleUnpublish,
685
+ disabled: unpublishPage.isPending,
686
+ children: t32
687
+ });
688
+ $[64] = handleUnpublish;
689
+ $[65] = t32;
690
+ $[66] = unpublishPage.isPending;
691
+ $[67] = t33;
692
+ } else t33 = $[67];
693
+ let t34;
694
+ if ($[68] !== t31 || $[69] !== t33) {
695
+ t34 = /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [t31, t33] });
696
+ $[68] = t31;
697
+ $[69] = t33;
698
+ $[70] = t34;
699
+ } else t34 = $[70];
700
+ let t35;
701
+ if ($[71] !== t30 || $[72] !== t34) {
702
+ t35 = /* @__PURE__ */ jsxs(AlertDialogContent, { children: [t30, t34] });
703
+ $[71] = t30;
704
+ $[72] = t34;
705
+ $[73] = t35;
706
+ } else t35 = $[73];
707
+ let t36;
708
+ if ($[74] !== isUnpublishDialogOpen || $[75] !== t35) {
709
+ t36 = /* @__PURE__ */ jsx(AlertDialog, {
710
+ open: isUnpublishDialogOpen,
711
+ onOpenChange: setIsUnpublishDialogOpen,
712
+ children: t35
713
+ });
714
+ $[74] = isUnpublishDialogOpen;
715
+ $[75] = t35;
716
+ $[76] = t36;
717
+ } else t36 = $[76];
718
+ let t37;
719
+ if ($[77] === Symbol.for("react.memo_cache_sentinel")) {
720
+ t37 = /* @__PURE__ */ jsx(AlertDialogTitle, { children: "Discard draft changes" });
721
+ $[77] = t37;
722
+ } else t37 = $[77];
723
+ let t38;
724
+ if ($[78] !== page.fullPath) {
725
+ t38 = /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [t37, /* @__PURE__ */ jsxs(AlertDialogDescription, { children: [
726
+ "The draft for",
727
+ " ",
728
+ /* @__PURE__ */ jsx("code", {
729
+ className: "bg-muted rounded px-1 py-0.5 font-mono text-xs",
730
+ children: page.fullPath
731
+ }),
732
+ " ",
733
+ "will be reset to match the currently published version. This does not change what visitors see."
734
+ ] })] });
735
+ $[78] = page.fullPath;
736
+ $[79] = t38;
737
+ } else t38 = $[79];
738
+ let t39;
739
+ if ($[80] !== discardChanges.isPending) {
740
+ t39 = /* @__PURE__ */ jsx(AlertDialogCancel, {
741
+ variant: "outline",
742
+ size: "default",
743
+ disabled: discardChanges.isPending,
744
+ children: "Cancel"
745
+ });
746
+ $[80] = discardChanges.isPending;
747
+ $[81] = t39;
748
+ } else t39 = $[81];
749
+ const t40 = discardChanges.isPending ? "Discarding…" : "Discard changes";
750
+ let t41;
751
+ if ($[82] !== discardChanges.isPending || $[83] !== handleDiscardChanges || $[84] !== t40) {
752
+ t41 = /* @__PURE__ */ jsx(AlertDialogAction, {
753
+ onClick: handleDiscardChanges,
754
+ disabled: discardChanges.isPending,
755
+ children: t40
756
+ });
757
+ $[82] = discardChanges.isPending;
758
+ $[83] = handleDiscardChanges;
759
+ $[84] = t40;
760
+ $[85] = t41;
761
+ } else t41 = $[85];
762
+ let t42;
763
+ if ($[86] !== t39 || $[87] !== t41) {
764
+ t42 = /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [t39, t41] });
765
+ $[86] = t39;
766
+ $[87] = t41;
767
+ $[88] = t42;
768
+ } else t42 = $[88];
769
+ let t43;
770
+ if ($[89] !== t38 || $[90] !== t42) {
771
+ t43 = /* @__PURE__ */ jsxs(AlertDialogContent, { children: [t38, t42] });
772
+ $[89] = t38;
773
+ $[90] = t42;
774
+ $[91] = t43;
775
+ } else t43 = $[91];
776
+ let t44;
777
+ if ($[92] !== isDiscardDialogOpen || $[93] !== t43) {
778
+ t44 = /* @__PURE__ */ jsx(AlertDialog, {
779
+ open: isDiscardDialogOpen,
780
+ onOpenChange: setIsDiscardDialogOpen,
781
+ children: t43
782
+ });
783
+ $[92] = isDiscardDialogOpen;
784
+ $[93] = t43;
785
+ $[94] = t44;
786
+ } else t44 = $[94];
787
+ let t45;
788
+ if ($[95] !== t26 || $[96] !== t28 || $[97] !== t36 || $[98] !== t44) {
789
+ t45 = /* @__PURE__ */ jsxs(Fragment, { children: [
790
+ t26,
791
+ t28,
792
+ t36,
793
+ t44
794
+ ] });
795
+ $[95] = t26;
796
+ $[96] = t28;
797
+ $[97] = t36;
798
+ $[98] = t44;
799
+ $[99] = t45;
800
+ } else t45 = $[99];
801
+ return t45;
456
802
  };
457
803
  function useHydrateDraftCache() {
458
804
  const $ = c(7);
459
- if ($[0] !== "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8") {
805
+ if ($[0] !== "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b") {
460
806
  for (let $i = 0; $i < 7; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
461
- $[0] = "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8";
807
+ $[0] = "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b";
462
808
  }
463
809
  const isAuthenticated = useIsAuthenticated();
464
810
  const queryClient = useQueryClient();
@@ -483,7 +829,7 @@ function useHydrateDraftCache() {
483
829
  projectName: data.projectName,
484
830
  project: data.project
485
831
  });
486
- }).catch(_temp6);
832
+ }).catch(_temp8);
487
833
  return () => {
488
834
  cancelled = true;
489
835
  };
@@ -506,18 +852,18 @@ function useHydrateDraftCache() {
506
852
  }
507
853
  React.useEffect(t0, t1);
508
854
  }
509
- function _temp6() {}
855
+ function _temp8() {}
510
856
  const CamoxPreview = (t0) => {
511
857
  const $ = c(32);
512
- if ($[0] !== "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8") {
858
+ if ($[0] !== "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b") {
513
859
  for (let $i = 0; $i < 32; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
514
- $[0] = "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8";
860
+ $[0] = "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b";
515
861
  }
516
862
  const { children } = t0;
517
863
  const isAuthenticated = useIsAuthenticated();
518
- const isPresentationMode = useSelector(previewStore, _temp7);
519
- const isSidebarOpen = useSelector(previewStore, _temp8);
520
- const previewSource = useSelector(previewStore, _temp9);
864
+ const isPresentationMode = useSelector(previewStore, _temp9);
865
+ const isSidebarOpen = useSelector(previewStore, _temp0);
866
+ const previewSource = useSelector(previewStore, _temp1);
521
867
  const pageData = usePreviewedPage();
522
868
  useHydrateDraftCache();
523
869
  const hasLiveCheckpoint = pageData.page.livePublishedCheckpointId != null;
@@ -531,7 +877,7 @@ const CamoxPreview = (t0) => {
531
877
  label: "Hide Camox Studio",
532
878
  groupLabel: "Preview",
533
879
  checkIfAvailable: () => isAuthenticated && !isPresentationMode,
534
- execute: _temp0,
880
+ execute: _temp10,
535
881
  shortcut: {
536
882
  key: "Enter",
537
883
  withMeta: true
@@ -542,7 +888,7 @@ const CamoxPreview = (t0) => {
542
888
  label: "Show Camox Studio",
543
889
  groupLabel: "Preview",
544
890
  checkIfAvailable: () => isAuthenticated && isPresentationMode,
545
- execute: _temp1,
891
+ execute: _temp11,
546
892
  shortcut: {
547
893
  key: "Enter",
548
894
  withMeta: true
@@ -553,7 +899,7 @@ const CamoxPreview = (t0) => {
553
899
  label: "Preview live content",
554
900
  groupLabel: "Preview",
555
901
  checkIfAvailable: () => isAuthenticated && previewSource === "draft" && hasLiveCheckpoint,
556
- execute: _temp10,
902
+ execute: _temp12,
557
903
  shortcut: {
558
904
  key: "d",
559
905
  withAlt: true
@@ -564,7 +910,7 @@ const CamoxPreview = (t0) => {
564
910
  label: "Preview draft content",
565
911
  groupLabel: "Preview",
566
912
  checkIfAvailable: () => isAuthenticated && previewSource === "live",
567
- execute: _temp11,
913
+ execute: _temp13,
568
914
  shortcut: {
569
915
  key: "d",
570
916
  withAlt: true
@@ -574,8 +920,8 @@ const CamoxPreview = (t0) => {
574
920
  id: "clear-selection",
575
921
  label: "Clear selection",
576
922
  groupLabel: "Preview",
577
- checkIfAvailable: _temp12,
578
- execute: _temp13,
923
+ checkIfAvailable: _temp14,
924
+ execute: _temp15,
579
925
  shortcut: { key: "Escape" }
580
926
  }
581
927
  ];
@@ -586,7 +932,7 @@ const CamoxPreview = (t0) => {
586
932
  return () => {
587
933
  actionsStore.send({
588
934
  type: "unregisterManyActions",
589
- ids: actions.map(_temp14)
935
+ ids: actions.map(_temp16)
590
936
  });
591
937
  };
592
938
  };
@@ -638,9 +984,9 @@ const CamoxPreview = (t0) => {
638
984
  t4 = isSidebarOpen && /* @__PURE__ */ jsxs("div", {
639
985
  className: "flex w-[300px] flex-col border-r-2",
640
986
  children: [/* @__PURE__ */ jsxs(PanelHeader, {
641
- className: cn("flex flex-col gap-2 px-2 py-2"),
642
- children: [/* @__PURE__ */ jsxs("div", {
643
- className: "flex flex-row gap-2",
987
+ className: cn("flex flex-col gap-2 px-2 pt-2 pb-3"),
988
+ children: [/* @__PURE__ */ jsxs(ButtonGroup, {
989
+ className: "w-full",
644
990
  children: [/* @__PURE__ */ jsx(PagePicker, {}), /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
645
991
  render: /* @__PURE__ */ jsx(Button, {
646
992
  type: "button",
@@ -652,7 +998,7 @@ const CamoxPreview = (t0) => {
652
998
  })
653
999
  }),
654
1000
  children: /* @__PURE__ */ jsx(Info, { className: "text-muted-foreground size-4" })
655
- }), /* @__PURE__ */ jsx(TooltipContent, { children: "Page metadata, SEO and markdown" })] })]
1001
+ }), /* @__PURE__ */ jsx(TooltipContent, { children: "Page metadata" })] })]
656
1002
  }), /* @__PURE__ */ jsx(SidebarPublishRow, { page: pageData.page })]
657
1003
  }), /* @__PURE__ */ jsx(PanelContent, {
658
1004
  className: "flex grow basis-0 flex-col gap-2 overflow-auto p-2",
@@ -701,7 +1047,7 @@ const CamoxPreview = (t0) => {
701
1047
  t9 = /* @__PURE__ */ jsx(AddBlockSheet, {});
702
1048
  t10 = /* @__PURE__ */ jsx(AgentChatSheet, {});
703
1049
  t11 = /* @__PURE__ */ jsx(CreatePageModal, {});
704
- t12 = /* @__PURE__ */ jsx(EditPageModal, {});
1050
+ t12 = /* @__PURE__ */ jsx(PageMetadataModal, {});
705
1051
  t13 = /* @__PURE__ */ jsx(DraftSwitchDialog, {});
706
1052
  $[24] = t10;
707
1053
  $[25] = t11;
@@ -739,9 +1085,9 @@ const CamoxPreview = (t0) => {
739
1085
  };
740
1086
  function usePreviewPagesActions() {
741
1087
  const $ = c(13);
742
- if ($[0] !== "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8") {
1088
+ if ($[0] !== "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b") {
743
1089
  for (let $i = 0; $i < 13; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
744
- $[0] = "db8d810f3b089d82690f0e1b5661e44e1ec1bfed6c53c9605ab4126a4f1e25b8";
1090
+ $[0] = "fe382a0b044a84ab3280ebb086ded75a3135ffd01e1c594e94a37233c1b7e49b";
745
1091
  }
746
1092
  const navigate = useNavigate();
747
1093
  const { pathname } = useLocation();
@@ -781,8 +1127,8 @@ function usePreviewPagesActions() {
781
1127
  id: "create-page",
782
1128
  label: "Create page",
783
1129
  groupLabel: "Preview",
784
- checkIfAvailable: _temp15,
785
- execute: _temp16
1130
+ checkIfAvailable: _temp17,
1131
+ execute: _temp18
786
1132
  },
787
1133
  {
788
1134
  id: "edit-current-page",
@@ -803,14 +1149,14 @@ function usePreviewPagesActions() {
803
1149
  groupLabel: "Preview",
804
1150
  checkIfAvailable: () => !!pages,
805
1151
  hasChildren: true,
806
- execute: _temp17
1152
+ execute: _temp19
807
1153
  },
808
1154
  ...pages ? pages.map((page) => ({
809
1155
  id: `go-to-page-${page.id}`,
810
1156
  parentActionId: "go-to-page",
811
- label: `Go to "${page.metaTitle ?? formatPathSegment(page.pathSegment)}"`,
1157
+ label: `Go to "${page.nickname}"`,
812
1158
  groupLabel: "Preview",
813
- checkIfAvailable: _temp18,
1159
+ checkIfAvailable: _temp20,
814
1160
  execute: () => navigate({ to: page.fullPath })
815
1161
  })) : []
816
1162
  ];
@@ -821,7 +1167,7 @@ function usePreviewPagesActions() {
821
1167
  return () => {
822
1168
  actionsStore.send({
823
1169
  type: "unregisterManyActions",
824
- ids: actions.map(_temp19)
1170
+ ids: actions.map(_temp21)
825
1171
  });
826
1172
  };
827
1173
  };
@@ -841,17 +1187,17 @@ function usePreviewPagesActions() {
841
1187
  }
842
1188
  React.useEffect(t4, t5);
843
1189
  }
844
- function _temp19(a) {
1190
+ function _temp21(a) {
845
1191
  return a.id;
846
1192
  }
847
- function _temp18() {
1193
+ function _temp20() {
848
1194
  return true;
849
1195
  }
850
- function _temp17() {}
851
- function _temp16() {
1196
+ function _temp19() {}
1197
+ function _temp18() {
852
1198
  return previewStore.send({ type: "openCreatePageModal" });
853
1199
  }
854
- function _temp15() {
1200
+ function _temp17() {
855
1201
  return true;
856
1202
  }
857
1203
  function _temp3(state) {
@@ -860,46 +1206,60 @@ function _temp3(state) {
860
1206
  function _temp4(state) {
861
1207
  return state.context.previewSource;
862
1208
  }
863
- function _temp5(checked) {
1209
+ function _temp5(action) {
1210
+ return action.id;
1211
+ }
1212
+ function _temp6(current) {
1213
+ return current ? {
1214
+ ...current,
1215
+ page: {
1216
+ ...current.page,
1217
+ livePublishedCheckpointId: null,
1218
+ status: "draft",
1219
+ modifiedReason: null
1220
+ }
1221
+ } : current;
1222
+ }
1223
+ function _temp7(checked) {
864
1224
  previewStore.send({
865
1225
  type: "setPreviewSource",
866
1226
  source: checked ? "draft" : "live"
867
1227
  });
868
1228
  }
869
- function _temp7(state) {
1229
+ function _temp9(state) {
870
1230
  return state.context.isPresentationMode;
871
1231
  }
872
- function _temp8(state_0) {
1232
+ function _temp0(state_0) {
873
1233
  return state_0.context.isSidebarOpen;
874
1234
  }
875
- function _temp9(state_1) {
1235
+ function _temp1(state_1) {
876
1236
  return state_1.context.previewSource;
877
1237
  }
878
- function _temp0() {
1238
+ function _temp10() {
879
1239
  return previewStore.send({ type: "enterPresentationMode" });
880
1240
  }
881
- function _temp1() {
1241
+ function _temp11() {
882
1242
  return previewStore.send({ type: "exitPresentationMode" });
883
1243
  }
884
- function _temp10() {
1244
+ function _temp12() {
885
1245
  return previewStore.send({
886
1246
  type: "setPreviewSource",
887
1247
  source: "live"
888
1248
  });
889
1249
  }
890
- function _temp11() {
1250
+ function _temp13() {
891
1251
  return previewStore.send({
892
1252
  type: "setPreviewSource",
893
1253
  source: "draft"
894
1254
  });
895
1255
  }
896
- function _temp12() {
1256
+ function _temp14() {
897
1257
  return true;
898
1258
  }
899
- function _temp13() {
1259
+ function _temp15() {
900
1260
  console.log("clear selection");
901
1261
  }
902
- function _temp14(a) {
1262
+ function _temp16(a) {
903
1263
  return a.id;
904
1264
  }
905
1265