@designcrowd/library.brand-page 5.18.1-undo-31 → 5.18.1-undo-33

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 (42) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-o_EZLLMS.js → CreatedOnBrandCrowd-de-de-986OpXvU.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-BD9czE0V.js → CreatedOnBrandCrowd-en-us-CTZuZ366.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BymhYJ3W.js → CreatedOnBrandCrowd-es-es-CHrTgX9-.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-CUAEgyAJ.js → CreatedOnBrandCrowd-fr-ca-xJAvxQ-x.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-CUAEgyAJ.js → CreatedOnBrandCrowd-fr-fr-xJAvxQ-x.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt--zSZt-Xl.js → CreatedOnBrandCrowd-pt-br-lpRIGIcs.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br--zSZt-Xl.js → CreatedOnBrandCrowd-pt-pt-lpRIGIcs.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BDLX7HCP.js → CreatedOnDcom-de-de-CZuim3ee.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-BqM2Nkb9.js → CreatedOnDcom-en-us-DG4I5f4s.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-DJ1TGVBd.js → CreatedOnDcom-es-es-Hpieh1wX.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-Bsml5qLX.js → CreatedOnDcom-fr-ca-DWr5P-df.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-a_Kmgb0N.js → CreatedOnDcom-fr-fr-CHfOyS6V.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-c6WK8bRr.js → CreatedOnDcom-pt-br-bQwCCDDI.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-BacuWl6v.js → CreatedOnDcom-pt-pt-bo-i_h0N.js} +1 -1
  15. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +2 -11
  16. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +15 -47
  17. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +7 -47
  18. package/lib/src/brand-page-maker/stores/history/history-store.js +67 -271
  19. package/lib/src/index.mjs +1 -1
  20. package/lib/src/{lib-8q5RIrss.js → lib-DNHBgZyy.js} +4520 -4534
  21. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.d.ts +1 -1
  22. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +64 -0
  23. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +5 -0
  24. package/lib/src/shared/content-settings/components/email-field/EmailField.mixin.d.ts +1 -1
  25. package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.js +2 -8
  26. package/lib/src/shared/content-settings/components/radio-field/RadioField.mixin.d.ts +1 -1
  27. package/lib/src/shared/content-settings/components/tel-field/TelField.mixin.d.ts +1 -1
  28. package/lib/src/shared/content-settings/components/text-field/TextField.mixin.d.ts +1 -1
  29. package/lib/src/shared/content-settings/components/textarea-field/TextareaField.mixin.d.ts +1 -1
  30. package/lib/src/shared/content-settings/components/url-field/UrlField.mixin.d.ts +1 -1
  31. package/lib/src/shared/content-settings/components/youtube-video-field/YoutubeVideoField.mixin.d.ts +1 -1
  32. package/lib/src/shared/logo-settings/store/editable-logo-store.d.ts +0 -18
  33. package/lib/src/shared/logo-settings/store/editable-logo-store.js +6 -24
  34. package/package.json +1 -1
  35. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +2 -11
  36. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +15 -47
  37. package/src/brand-page-maker/stores/history/history-store.test.ts +29 -0
  38. package/src/brand-page-maker/stores/history/history-store.ts +77 -327
  39. package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +5 -0
  40. package/src/shared/content-settings/components/page-dropdown-field/PageDropdownField.vue +1 -4
  41. package/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.ts +2 -8
  42. package/src/shared/logo-settings/store/editable-logo-store.ts +9 -29
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-8q5RIrss.js";
2
+ import { _ as t } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, h = {
4
4
  width: "275",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-8q5RIrss.js";
2
+ import { _ as t } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, h = {
4
4
  width: "251",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-8q5RIrss.js";
2
+ import { _ as t } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, h = {
4
4
  width: "250",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-8q5RIrss.js";
2
+ import { _ as t } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-8q5RIrss.js";
2
+ import { _ as t } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, h = {
4
4
  width: "237",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-8q5RIrss.js";
2
+ import { _ as t } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as e, createElementBlock as l, createStaticVNode as a } from "vue";
2
- import { _ as t } from "./lib-8q5RIrss.js";
2
+ import { _ as t } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, h = {
4
4
  width: "263",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-8q5RIrss.js";
2
+ import { _ as e } from "./lib-DNHBgZyy.js";
3
3
  const M = {}, Z = {
4
4
  width: "242",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-8q5RIrss.js";
2
+ import { _ as e } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, M = {
4
4
  width: "231",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-8q5RIrss.js";
2
+ import { _ as e } from "./lib-DNHBgZyy.js";
3
3
  const M = {}, Z = {
4
4
  width: "230",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-8q5RIrss.js";
2
+ import { _ as e } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as e } from "./lib-8q5RIrss.js";
2
+ import { _ as e } from "./lib-DNHBgZyy.js";
3
3
  const i = {}, l = {
4
4
  width: "216",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-8q5RIrss.js";
2
+ import { _ as M } from "./lib-DNHBgZyy.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -1,5 +1,5 @@
1
1
  import { openBlock as H, createElementBlock as V, createStaticVNode as t } from "vue";
2
- import { _ as M } from "./lib-8q5RIrss.js";
2
+ import { _ as M } from "./lib-DNHBgZyy.js";
3
3
  const Z = {}, e = {
4
4
  width: "232",
5
5
  height: "36",
@@ -74,17 +74,8 @@ export const useExternalRichTextEditor = () => {
74
74
  };
75
75
  export const useRichTextEditor = (model, props, emit, fontSettings, fontStyleDropdownRef, selectedGlobalTextStyles, onSelectTextStyleType, updateRichTextEditor, textStyleTypeOptions, markedText, isHyperlinkPopupOpen, selectedLinkTypeValue) => {
76
76
  const historyStore = useHistoryStore();
77
- // TipTap rehydrates `model.value` on first mount and writes the
78
- // canonical HTML back via `editor.on('update', ...)` — even when the
79
- // user-visible text is unchanged (it normalises whitespace, wraps plain
80
- // text in `<p>`, expands `%0A` to `<br>`, mirrors the resolved textStyle
81
- // as inline `<strong>`/`<span style="...">`/`<mark>` tags, etc). Each of
82
- // those rehydration writes mutates `brandPageData` and would otherwise
83
- // surface as a phantom undo entry the first time the user opens a
84
- // sidebar or clicks into a section. Arming the merge flag folds the
85
- // resulting watcher flush into the current head instead of pushing.
86
- // Idempotent — every editor on the page mounting at once collapses
87
- // into the same merge.
77
+ // TipTap rehydrates and writes back canonical HTML on mount — fold
78
+ // that into the current head instead of pushing a phantom entry.
88
79
  historyStore.mergeNextMutation();
89
80
  const editor = new Editor({
90
81
  content: model.value ?? '',
@@ -607,20 +607,12 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
607
607
  const editableLogoStore = useUiEditableLogoStore();
608
608
  const logoStore = useLogoStore();
609
609
  const containerStore = useBrandPageContainerStore();
610
- // Snapshot the pre-restore logo identity BEFORE we $patch logoEdits.
611
- // Used below to short-circuit the fabric-render call when the entry
612
- // we're restoring has the same logoEdits + draft token as the live
613
- // state — i.e. only non-logo state changed between the two entries.
610
+ // Pre-restore logo identity, used to short-circuit the
611
+ // fabric-render call when only non-logo state changed.
614
612
  const prevLogoEditsStr = JSON.stringify(toRaw(editableLogoStore.logoEdits));
615
613
  const prevDraftToken = editableLogoStore.logoDraftToken;
616
- // Restore `editableLogoStore.logoEdits` first — sidecar to `brandPageData`,
617
- // captured per-entry. Wholesale-replace via `$patch` so a previous
618
- // entry's textObjects/colors don't leak through (e.g. switching
619
- // template A→B then undoing A's restored object set must NOT contain
620
- // B's textObject ids). Failing parse is non-fatal; the logo tab will
621
- // just keep showing whatever logoEdits state was already loaded —
622
- // canvas + saved metadata still come from `brandPageData` + the
623
- // save-time `updateMetadataAsync` round-trip.
614
+ // Wholesale-replace via $patch so prior textObjects/colors don't
615
+ // leak across template switches.
624
616
  if (logoEditsStr) {
625
617
  try {
626
618
  const parsed = JSON.parse(logoEditsStr);
@@ -641,12 +633,8 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
641
633
  const draftToken = logoImage.logoDraftToken;
642
634
  if (!draftToken)
643
635
  return;
644
- // Re-derive `enableEditMode` and the active template asset from the
645
- // logo-store's draft registry. Drafts are append-only for the session,
646
- // and BYO upload stamps `templateAsset` onto the registered draft when
647
- // it lands — so the registered draft is enough to fully restore the
648
- // sidebar's design/upload chooser without storing anything inside
649
- // each history entry.
636
+ // Re-derive enableEditMode + templateAsset from the draft registry
637
+ // (append-only for the session) instead of stashing on every entry.
650
638
  const draft = logoStore.getLogoDraftAssetByToken(draftToken);
651
639
  if (draft) {
652
640
  editableLogoStore.setEnableEditMode(!draft.isByo);
@@ -655,12 +643,8 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
655
643
  }
656
644
  }
657
645
  editableLogoStore.setLogoDraftToken(draftToken);
658
- // Did the logo identity actually change between the two entries?
659
- // If both `logoEdits` and the draft token match what was already
660
- // live, the cached `editableLogoVariations` is still the right
661
- // render and we just need to stamp it back into `brandPageData`
662
- // (history-store strips `logoImageBase64Url` from snapshots, so
663
- // the page-level base64 fields are now empty).
646
+ // No logo change → cache is still correct; just stamp base64 back
647
+ // (snapshot doesn't carry logoImageBase64Url).
664
648
  const logoUnchanged = prevDraftToken === draftToken &&
665
649
  (logoEditsStr === undefined || logoEditsStr === prevLogoEditsStr);
666
650
  if (logoUnchanged) {
@@ -669,34 +653,18 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
669
653
  }
670
654
  const isByo = !!draft?.isByo;
671
655
  if (isByo) {
672
- // BYO uploads register a fresh `logoDraftToken` per upload, so
673
- // `variationsByDraftToken` keyed off that token always matches the
674
- // base64 the user saw at capture. No re-render — the uploaded
675
- // image bytes are the source of truth and there's nothing for
676
- // fabric-render to derive. After restoring the variations cache,
677
- // stamp the base64 back across header/footer/per-page logo
678
- // content; the snapshot itself doesn't carry `logoImageBase64Url`.
656
+ // BYO mints a fresh draftToken per upload so the per-token
657
+ // cache always matches; no re-render needed.
679
658
  if (editableLogoStore.restoreVariationsForDraftToken(draftToken)) {
680
659
  editableLogoStore.stampLogoBase64IntoBrandPageData();
681
660
  }
682
661
  return;
683
662
  }
684
- // Designed (non-BYO) logo whose form state actually differs from
685
- // the live state. The draft token is reused across every form-field
686
- // edit, so the per-token cache only holds the latest render —
687
- // re-issue the same fabric-render call the live edit path runs.
688
- // `updateEditableLogoImageUrlAsync` POSTs the freshly-restored
689
- // `logoEdits`, writes the returned base64 across every header/footer
690
- // + per-page logo content + `editableLogoVariations`.
691
- //
692
- // Awaited (not fire-and-forget): two undos in quick succession would
693
- // otherwise kick off two parallel render bursts whose `Promise.all`
694
- // tasks interleave, leaving each variation showing whichever request
695
- // happened to win the race rather than the variation that belongs
696
- // to the snapshot the user landed on. Awaiting also keeps the call
697
- // inside the `applyHistorySnapshot`/`isApplyingSnapshot` window, so
698
- // the post-render writeback is naturally suppressed by the existing
699
- // watcher guard — no `mergeNextMutation()` needed.
663
+ // Designed: draft token is reused across edits, so the cache
664
+ // only holds the latest render. Re-issue fabric-render — same
665
+ // call as the live edit path. Awaited so concurrent undos
666
+ // serialize and the call sits inside the isApplyingSnapshot
667
+ // window (watcher guard suppresses the writeback).
700
668
  if (containerStore.isPrePurchase &&
701
669
  logoEditsStr &&
702
670
  logoStore.logoTemplateAsset) {
@@ -1,60 +1,20 @@
1
1
  /**
2
- * A single history entry.
3
- *
4
- * `snapshot` is a **JSON-stringified** `BrandPageModel`, not a plain object.
5
- * Stringifying up-front has two benefits:
6
- * 1. Pinia's reactive proxy treats the string as a primitive — no traversal,
7
- * no per-field getters/setters on our entries, no accidental shared refs
8
- * with the live store.
9
- * 2. `sizeBytes === snapshot.length` is automatic and accurate for the V2
10
- * memory-budget instrumentation.
11
- *
12
- * Sidecar state that doesn't live on `brandPageData` (the variations grid in
13
- * the Logo sidebar, the active `logoTemplateAsset`, the active
14
- * `logoDraftToken`) is restored on undo by `_syncLogoSettingsFromSnapshot`
15
- * via per-draft-token caches on the logo / editable-logo stores — keyed off
16
- * `logoImage.logoDraftToken` which IS in the snapshot. Pre-purchase logo-tab
17
- * property edits (text, support text, logo colors, font, outline, shadow)
18
- * live on `editableLogoStore.logoEdits` and ride along on the `logoEdits`
19
- * sidecar below.
2
+ * A single history entry. `snapshot` is JSON-stringified up-front so Pinia
3
+ * treats it as opaque (no per-field reactivity) and `sizeBytes` is exact.
4
+ * Sidecar state not in `brandPageData` rides along on this entry —
5
+ * `activePageId` for page-tab restore, `logoEdits` for pre-purchase logo
6
+ * form state.
20
7
  */
21
8
  export interface HistoryEntry {
22
- /** JSON.stringify(BrandPageModel) at the moment of capture. */
23
9
  snapshot: string;
24
- /** ISO-8601 timestamp of when the entry was captured. */
25
10
  timestamp: string;
26
- /** What kind of change produced this entry. */
27
11
  source: 'manual_edit' | 'template_switch' | 'ai_changeset' | 'rich_text';
28
- /** Who authored the change. */
29
12
  actor: 'user' | 'ai_builder';
30
- /** Optional human-readable short description. Reserved for V2 UI / debugging. */
31
13
  label?: string;
32
- /** Serialized size in bytes (= snapshot.length in JS string semantics). */
33
14
  sizeBytes: number;
34
- /**
35
- * The page the user was viewing when this entry was captured. Sidecar to the
36
- * `BrandPageModel` snapshot — page-tab "selected" styling and the sidebar's
37
- * `currentPage` getter both key off this id (via the route URL → routeStore →
38
- * `pageNavigation.activePageId`). Snapshots only contain the document model,
39
- * so without this we can't restore the URL/active-page on undo and the
40
- * carousel highlight bleeds through to the page that no longer exists.
41
- *
42
- * Empty string when no page is active yet (e.g. earliest baseline before
43
- * first router push). Always a real id once the editor has settled.
44
- */
15
+ /** Active page id at capture time. Empty before first router push. */
45
16
  activePageId: string;
46
- /**
47
- * `JSON.stringify(editableLogoStore.logoEdits)` at the moment of capture.
48
- * Sidecar — `logoEdits` is NOT part of `brandPageData` but its state
49
- * (logo text, support text, logo colors, fonts, outlines, shadows) drives
50
- * what the pre-purchase save path POSTs to fabric-render to regenerate
51
- * the persisted draft metadata. Without restoring it on undo, save after
52
- * an undo would re-derive metadata from the post-edit `logoEdits` and
53
- * silently reapply the change the user just undid.
54
- *
55
- * Undefined for sessions where the editable-logo store has never been
56
- * touched (no logo tab interaction yet) — restore is a no-op in that case.
57
- */
17
+ /** JSON-stringified `editableLogoStore.logoEdits`. Undefined if logo tab never opened. */
58
18
  logoEdits?: string;
59
19
  }
60
20
  export declare const useHistoryStore: import("pinia").StoreDefinition<"history", Pick<{