@designcrowd/library.brand-page 5.17.25-undo-19 → 5.17.25-undo-21

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 (37) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-jjqBiULc.js → CreatedOnBrandCrowd-de-de-Bze5WUip.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-B6h7bcbj.js → CreatedOnBrandCrowd-en-us-Dw5uSnX8.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-Cmys6ypT.js → CreatedOnBrandCrowd-es-es-Cz-oPdjt.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-Ceybzq8J.js → CreatedOnBrandCrowd-fr-ca-zldLXw3G.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-Ceybzq8J.js → CreatedOnBrandCrowd-fr-fr-zldLXw3G.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-CHV5Fh4C.js → CreatedOnBrandCrowd-pt-br-64QJpEaD.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-CHV5Fh4C.js → CreatedOnBrandCrowd-pt-pt-64QJpEaD.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-t2W_ziW-.js → CreatedOnDcom-de-de-8SXOvjEH.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CsPm5hFT.js → CreatedOnDcom-en-us-ClZBYY_t.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-DjQbRJVQ.js → CreatedOnDcom-es-es-xg4ZwvEb.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-DK6rTyy-.js → CreatedOnDcom-fr-ca-4zo2gxc1.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-D_lMd4Dy.js → CreatedOnDcom-fr-fr-Dw9Fuy7U.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CZBLwwrp.js → CreatedOnDcom-pt-br-Dbl0EWcU.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-Hl48EO74.js → CreatedOnDcom-pt-pt-Bps73oQE.js} +1 -1
  15. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +7 -5
  16. package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.js +4 -4
  17. package/lib/src/brand-page-maker/composables/useUndoRedoFlag.d.ts +12 -5
  18. package/lib/src/brand-page-maker/composables/useUndoRedoFlag.js +15 -6
  19. package/lib/src/css/library.brand-page-brandCrowd.min.css +2 -2
  20. package/lib/src/css/library.brand-page-brandPage.min.css +2 -2
  21. package/lib/src/css/library.brand-page-designCom.min.css +2 -2
  22. package/lib/src/css/library.brand-page-preview.min.css +2 -2
  23. package/lib/src/index.mjs +1 -1
  24. package/lib/src/{lib-CWzbO4Vy.js → lib-BgvZxeSl.js} +10886 -10927
  25. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +1 -2
  26. package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.js +1 -10
  27. package/lib/src/shared/logo-settings/store/editable-logo-store.js +0 -18
  28. package/package.json +1 -1
  29. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +7 -6
  30. package/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.ts +3 -5
  31. package/src/brand-page-maker/components/quick-link-bar/RedoButton.test.ts +30 -0
  32. package/src/brand-page-maker/components/quick-link-bar/RedoButton.vue +6 -1
  33. package/src/brand-page-maker/components/quick-link-bar/UndoButton.test.ts +30 -0
  34. package/src/brand-page-maker/components/quick-link-bar/UndoButton.vue +6 -1
  35. package/src/brand-page-maker/composables/useUndoRedoFlag.ts +17 -6
  36. package/src/shared/logo-settings/components/EditLogoSettings.mixin.ts +1 -14
  37. package/src/shared/logo-settings/store/editable-logo-store.ts +0 -36
@@ -440,8 +440,7 @@ declare const _default: import("vue").DefineComponent<{}, {
440
440
  convertBpColorToFabricColor(selectedColor: any): any;
441
441
  onSelectTextColor(selectedColor: any, i: any): void;
442
442
  onLogoColorSelected(selectedColor: any): void;
443
- onUpdate(...args: any[]): any;
444
- _onUpdateDebounced: import("lodash.debounce").DebounceHandle;
443
+ onUpdate: import("lodash.debounce").DebounceHandle;
445
444
  onToggleText(e: boolean, i: number): void;
446
445
  }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
447
446
  export default _default;
@@ -181,16 +181,7 @@ export default defineComponent({
181
181
  this.logoColors[selectedColor.id].toColor = newColor;
182
182
  this.onUpdate();
183
183
  },
184
- onUpdate(...args) {
185
- console.log('[logo-debug] keystroke | textObjects=', this.editableLogoStore.logoEdits.textObjects.map((t) => ({
186
- id: t.id,
187
- role: t.role,
188
- text: t.text,
189
- textEnabled: t.textEnabled,
190
- })));
191
- return this._onUpdateDebounced(...args);
192
- },
193
- _onUpdateDebounced: debounce(async function () {
184
+ onUpdate: debounce(async function () {
194
185
  await this.editableLogoStore.updateEditableLogoImageUrlAsync();
195
186
  return true;
196
187
  }, 300),
@@ -110,12 +110,6 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
110
110
  if (!logoDraft?.isByo) {
111
111
  this.setEnableEditMode(true);
112
112
  }
113
- console.log('[logo-debug] init complete | logoDraftToken=', this.logoDraftToken, '| textObjects=', this.logoEdits.textObjects.map((t) => ({
114
- id: t.id,
115
- role: t.role,
116
- text: t.text,
117
- textEnabled: t.textEnabled,
118
- })));
119
113
  },
120
114
  resetLogoEdits() {
121
115
  this.logoEdits = {
@@ -222,20 +216,8 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
222
216
  this.editableLogoVariations[0]);
223
217
  },
224
218
  async updateEditableLogoImageUrlAsync(defaultPrimaryText, overrideLogoVariation, layout) {
225
- console.log('[logo-debug] BEFORE API call | logoDraftToken=', this.logoDraftToken, '| textObjects=', this.logoEdits.textObjects.map((t) => ({
226
- id: t.id,
227
- role: t.role,
228
- text: t.text,
229
- textEnabled: t.textEnabled,
230
- })));
231
219
  const tasks = this.editableLogoVariations.map((x) => this.updateEditableLogoImageByVariationAsync(x, defaultPrimaryText, layout));
232
220
  await Promise.all(tasks);
233
- console.log('[logo-debug] AFTER API call | logoDraftToken=', this.logoDraftToken, '| textObjects=', this.logoEdits.textObjects.map((t) => ({
234
- id: t.id,
235
- role: t.role,
236
- text: t.text,
237
- textEnabled: t.textEnabled,
238
- })));
239
221
  const pageSettingStore = useUiPageSettingsStore();
240
222
  [PAGE_SECTIONS.header, PAGE_SECTIONS.footer].forEach((section) => {
241
223
  [VIEWPORTS.desktop, VIEWPORTS.mobile].forEach((viewport) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "5.17.25-undo-19",
4
+ "version": "5.17.25-undo-21",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -36,6 +36,7 @@ import {
36
36
  useVideoStore,
37
37
  } from '@brand-page-maker/stores';
38
38
  import { useHistoryStore } from '@brand-page-maker/stores/history/history-store';
39
+ import { useUndoRedoFlag } from '@brand-page-maker/composables/useUndoRedoFlag';
39
40
  import type { AdminPreviewLogoTemplateModel } from '@brand-page-maker/stores/admin-logo-settings';
40
41
  import { useUiContentSettingsStore } from '@shared/content-settings/store';
41
42
  import { useUiTemplateSettingsStore } from '@shared/template-settings/store';
@@ -284,12 +285,12 @@ export default defineComponent({
284
285
  // Mark brand page as fully loaded
285
286
  this.brandPageMakerStore.setIsBrandPageLoaded(true);
286
287
 
287
- // Capture baseline for undo/redo when feature flag is enabled.
288
- // Flag lives on userStore.features.canUseUndoRedo, populated by the
289
- // consumer (BrandCrowd.Net / web-renderer) via the ViewModel.
290
- const userStore = useBrandPageMakerUserStore();
291
-
292
- if (userStore.features.canUseUndoRedo) {
288
+ // Capture baseline for undo/redo when the feature is active for this
289
+ // session. `useUndoRedoFlag` requires both the LaunchDarkly feature
290
+ // (`userStore.features.canUseUndoRedo`) AND the maker being a brand-site
291
+ // — V1 scope is brand-site only; brand-page and brand-contact don't get
292
+ // undo/redo. See useUndoRedoFlag.ts for the rationale.
293
+ if (useUndoRedoFlag().value) {
293
294
  useHistoryStore().captureBaseline();
294
295
  }
295
296
 
@@ -1,10 +1,10 @@
1
- import { computed, defineComponent } from 'vue';
1
+ import { defineComponent } from 'vue';
2
2
  import { CUSTOM_DOMAIN_STATUSES } from '@brand-page-maker/constants';
3
3
  import {
4
4
  useBrandPageContainerStore,
5
- useBrandPageMakerUserStore,
6
5
  useEventManagerStore,
7
6
  } from '@brand-page-maker/stores';
7
+ import { useUndoRedoFlag } from '@brand-page-maker/composables/useUndoRedoFlag';
8
8
  import { quickLinkBarTr } from '@src/composables/useTranslate';
9
9
 
10
10
  export default defineComponent({
@@ -19,12 +19,10 @@ export default defineComponent({
19
19
  },
20
20
  },
21
21
  setup() {
22
- const userStore = useBrandPageMakerUserStore();
23
-
24
22
  return {
25
23
  brandPageContainerStore: useBrandPageContainerStore(),
26
24
  eventManagerStore: useEventManagerStore(),
27
- undoRedoEnabled: computed(() => userStore.features.canUseUndoRedo),
25
+ undoRedoEnabled: useUndoRedoFlag(),
28
26
  };
29
27
  },
30
28
  data() {
@@ -57,6 +57,15 @@ vi.mock(
57
57
  }),
58
58
  );
59
59
 
60
+ // Container store mock — mutable so each test can flip isSaving.
61
+ const containerStoreMock = {
62
+ isSaving: false,
63
+ };
64
+
65
+ vi.mock('@brand-page-maker/stores/brandpage-container', () => ({
66
+ useBrandPageContainerStore: vi.fn(() => containerStoreMock),
67
+ }));
68
+
60
69
  describe('RedoButton.vue', () => {
61
70
  beforeEach(() => {
62
71
  setActivePinia(createPinia());
@@ -66,6 +75,7 @@ describe('RedoButton.vue', () => {
66
75
  historyStoreMock.undo = vi.fn();
67
76
  historyStoreMock.redo = vi.fn();
68
77
  aiStoreMock.isProcessing = false;
78
+ containerStoreMock.isSaving = false;
69
79
  });
70
80
 
71
81
  it('renders the expected data-test selector', () => {
@@ -106,6 +116,26 @@ describe('RedoButton.vue', () => {
106
116
  expect(icon.classes()).toContain('tw-cursor-not-allowed');
107
117
  });
108
118
 
119
+ it('marks itself disabled while a save is in flight', () => {
120
+ containerStoreMock.isSaving = true;
121
+
122
+ const wrapper = mount(RedoButton);
123
+ const icon = wrapper.find('[data-test-redo-button]');
124
+
125
+ expect(icon.classes()).toContain('tw-cursor-not-allowed');
126
+ });
127
+
128
+ it('does not dispatch historyStore.redo on click while saving', async () => {
129
+ containerStoreMock.isSaving = true;
130
+
131
+ const wrapper = mount(RedoButton);
132
+ const icon = wrapper.find('[data-test-redo-button]');
133
+
134
+ await icon.trigger('click');
135
+
136
+ expect(historyStoreMock.redo).not.toHaveBeenCalled();
137
+ });
138
+
109
139
  it('is interactive (no disabled class) at baseline with canRedo', () => {
110
140
  const wrapper = mount(RedoButton);
111
141
  const icon = wrapper.find('[data-test-redo-button]');
@@ -38,13 +38,18 @@ import { computed } from 'vue';
38
38
  import { Icon, Tooltip } from '@designcrowd/fe-shared-lib';
39
39
  import { useHistoryStore } from '@brand-page-maker/stores/history/history-store';
40
40
  import { useAiWebsiteBuilderThreadStore } from '@brand-page-maker/stores/ai-thread/ai-website-builder-thread-store';
41
+ import { useBrandPageContainerStore } from '@brand-page-maker/stores/brandpage-container';
41
42
  import { quickLinkBarTr } from '@src/composables/useTranslate';
42
43
 
43
44
  const historyStore = useHistoryStore();
44
45
  const aiThreadStore = useAiWebsiteBuilderThreadStore();
46
+ const containerStore = useBrandPageContainerStore();
45
47
 
46
48
  const isDisabled = computed(
47
- () => !historyStore.canRedo || aiThreadStore.isProcessing,
49
+ () =>
50
+ !historyStore.canRedo ||
51
+ aiThreadStore.isProcessing ||
52
+ containerStore.isSaving,
48
53
  );
49
54
 
50
55
  const onClick = () => {
@@ -57,6 +57,15 @@ vi.mock(
57
57
  }),
58
58
  );
59
59
 
60
+ // Container store mock — mutable so each test can flip isSaving.
61
+ const containerStoreMock = {
62
+ isSaving: false,
63
+ };
64
+
65
+ vi.mock('@brand-page-maker/stores/brandpage-container', () => ({
66
+ useBrandPageContainerStore: vi.fn(() => containerStoreMock),
67
+ }));
68
+
60
69
  describe('UndoButton.vue', () => {
61
70
  beforeEach(() => {
62
71
  setActivePinia(createPinia());
@@ -66,6 +75,7 @@ describe('UndoButton.vue', () => {
66
75
  historyStoreMock.undo = vi.fn();
67
76
  historyStoreMock.redo = vi.fn();
68
77
  aiStoreMock.isProcessing = false;
78
+ containerStoreMock.isSaving = false;
69
79
  });
70
80
 
71
81
  it('renders the expected data-test selector', () => {
@@ -106,6 +116,26 @@ describe('UndoButton.vue', () => {
106
116
  expect(icon.classes()).toContain('tw-cursor-not-allowed');
107
117
  });
108
118
 
119
+ it('marks itself disabled while a save is in flight', () => {
120
+ containerStoreMock.isSaving = true;
121
+
122
+ const wrapper = mount(UndoButton);
123
+ const icon = wrapper.find('[data-test-undo-button]');
124
+
125
+ expect(icon.classes()).toContain('tw-cursor-not-allowed');
126
+ });
127
+
128
+ it('does not dispatch historyStore.undo on click while saving', async () => {
129
+ containerStoreMock.isSaving = true;
130
+
131
+ const wrapper = mount(UndoButton);
132
+ const icon = wrapper.find('[data-test-undo-button]');
133
+
134
+ await icon.trigger('click');
135
+
136
+ expect(historyStoreMock.undo).not.toHaveBeenCalled();
137
+ });
138
+
109
139
  it('is interactive (no disabled class) at baseline with canUndo', () => {
110
140
  const wrapper = mount(UndoButton);
111
141
  const icon = wrapper.find('[data-test-undo-button]');
@@ -38,13 +38,18 @@ import { computed } from 'vue';
38
38
  import { Icon, Tooltip } from '@designcrowd/fe-shared-lib';
39
39
  import { useHistoryStore } from '@brand-page-maker/stores/history/history-store';
40
40
  import { useAiWebsiteBuilderThreadStore } from '@brand-page-maker/stores/ai-thread/ai-website-builder-thread-store';
41
+ import { useBrandPageContainerStore } from '@brand-page-maker/stores/brandpage-container';
41
42
  import { quickLinkBarTr } from '@src/composables/useTranslate';
42
43
 
43
44
  const historyStore = useHistoryStore();
44
45
  const aiThreadStore = useAiWebsiteBuilderThreadStore();
46
+ const containerStore = useBrandPageContainerStore();
45
47
 
46
48
  const isDisabled = computed(
47
- () => !historyStore.canUndo || aiThreadStore.isProcessing,
49
+ () =>
50
+ !historyStore.canUndo ||
51
+ aiThreadStore.isProcessing ||
52
+ containerStore.isSaving,
48
53
  );
49
54
 
50
55
  const onClick = () => {
@@ -1,15 +1,26 @@
1
1
  import { computed, type ComputedRef } from 'vue';
2
2
  import { useBrandPageMakerUserStore } from '@brand-page-maker/stores/user';
3
+ import { useBrandPageMakerStore } from '@brand-page-maker/stores/brandpage-maker/brandpage-maker-store';
3
4
 
4
5
  /**
5
- * Reads the undo/redo feature flag from the maker user store's `features` bag,
6
- * which is populated by the consumer (BrandCrowd.Net / web-renderer) via the
7
- * `WebsiteDesignUserFeatures.CanUseUndoRedo` boolean on the ViewModel. Follows
8
- * the same precedent as other maker feature flags (RichTextEditor, GettyVideos,
9
- * AITextGenerator).
6
+ * Returns whether undo/redo is active for the current maker session. Two
7
+ * conditions must hold:
8
+ *
9
+ * 1. `userStore.features.canUseUndoRedo` is true. The flag is populated by
10
+ * the consumer (BrandCrowd.Net / web-renderer) via the
11
+ * `WebsiteDesignUserFeatures.CanUseUndoRedo` boolean on the ViewModel —
12
+ * same precedent as RichTextEditor / GettyVideos / AITextGenerator.
13
+ * 2. The maker is a brand-site (Website Maker). V1 scope is brand-site
14
+ * only; brand-page (single-page profile) and brand-contact (vCard) are
15
+ * out of scope. The flag itself is global on LaunchDarkly so it can't
16
+ * gate this on its own — `isBrandSite` is the per-session
17
+ * discriminator.
10
18
  */
11
19
  export function useUndoRedoFlag(): ComputedRef<boolean> {
12
20
  const userStore = useBrandPageMakerUserStore();
21
+ const brandPageMakerStore = useBrandPageMakerStore();
13
22
 
14
- return computed(() => userStore.features.canUseUndoRedo);
23
+ return computed(
24
+ () => userStore.features.canUseUndoRedo && brandPageMakerStore.isBrandSite,
25
+ );
15
26
  }
@@ -217,20 +217,7 @@ export default defineComponent({
217
217
  this.logoColors[selectedColor.id].toColor = newColor;
218
218
  this.onUpdate();
219
219
  },
220
- onUpdate(...args: any[]) {
221
- console.log(
222
- '[logo-debug] keystroke | textObjects=',
223
- this.editableLogoStore.logoEdits.textObjects.map((t) => ({
224
- id: t.id,
225
- role: t.role,
226
- text: t.text,
227
- textEnabled: t.textEnabled,
228
- })),
229
- );
230
-
231
- return this._onUpdateDebounced(...args);
232
- },
233
- _onUpdateDebounced: debounce(async function () {
220
+ onUpdate: debounce(async function () {
234
221
  await this.editableLogoStore.updateEditableLogoImageUrlAsync();
235
222
 
236
223
  return true;
@@ -257,18 +257,6 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
257
257
  if (!logoDraft?.isByo) {
258
258
  this.setEnableEditMode(true);
259
259
  }
260
-
261
- console.log(
262
- '[logo-debug] init complete | logoDraftToken=',
263
- this.logoDraftToken,
264
- '| textObjects=',
265
- this.logoEdits.textObjects.map((t) => ({
266
- id: t.id,
267
- role: t.role,
268
- text: t.text,
269
- textEnabled: t.textEnabled,
270
- })),
271
- );
272
260
  },
273
261
 
274
262
  resetLogoEdits() {
@@ -415,18 +403,6 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
415
403
  overrideLogoVariation?: number | undefined,
416
404
  layout?: string,
417
405
  ): Promise<void> {
418
- console.log(
419
- '[logo-debug] BEFORE API call | logoDraftToken=',
420
- this.logoDraftToken,
421
- '| textObjects=',
422
- this.logoEdits.textObjects.map((t) => ({
423
- id: t.id,
424
- role: t.role,
425
- text: t.text,
426
- textEnabled: t.textEnabled,
427
- })),
428
- );
429
-
430
406
  const tasks = this.editableLogoVariations.map((x) =>
431
407
  this.updateEditableLogoImageByVariationAsync(
432
408
  x,
@@ -437,18 +413,6 @@ export const useUiEditableLogoStore = defineStore('uiEditableLogo', {
437
413
 
438
414
  await Promise.all(tasks);
439
415
 
440
- console.log(
441
- '[logo-debug] AFTER API call | logoDraftToken=',
442
- this.logoDraftToken,
443
- '| textObjects=',
444
- this.logoEdits.textObjects.map((t) => ({
445
- id: t.id,
446
- role: t.role,
447
- text: t.text,
448
- textEnabled: t.textEnabled,
449
- })),
450
- );
451
-
452
416
  const pageSettingStore = useUiPageSettingsStore();
453
417
 
454
418
  [PAGE_SECTIONS.header, PAGE_SECTIONS.footer].forEach((section) => {