@designcrowd/library.brand-page 6.0.12 → 6.0.14-5804-1
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/lib/src/{CreatedOnBrandCrowd-de-de-BfQcnhof.js → CreatedOnBrandCrowd-de-de-BYABvnQX.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-B86JfNzV.js → CreatedOnBrandCrowd-en-us-CU6aE_W2.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-Dy70BV7X.js → CreatedOnBrandCrowd-es-es-Pfuc4Nfl.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-CQ8UhGRG.js → CreatedOnBrandCrowd-fr-ca-DyQ1RyZN.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-CQ8UhGRG.js → CreatedOnBrandCrowd-fr-fr-DyQ1RyZN.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-c257u4q-.js → CreatedOnBrandCrowd-pt-br-DXMSa1wa.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-c257u4q-.js → CreatedOnBrandCrowd-pt-pt-DXMSa1wa.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-cRZ_Lx3_.js → CreatedOnDcom-de-de-kGnTiAMq.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-CrfHKR-1.js → CreatedOnDcom-en-us-CKrgHXUY.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-BFjhMPTR.js → CreatedOnDcom-es-es-CVxOQoOy.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-CZimjPcn.js → CreatedOnDcom-fr-ca-BduB1A0z.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-V1z3-WzE.js → CreatedOnDcom-fr-fr-LGhd51py.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-NrmWKrvi.js → CreatedOnDcom-pt-br-BLqHx-RQ.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-CKLASXM9.js → CreatedOnDcom-pt-pt-52goGQ1s.js} +1 -1
- package/lib/src/brand-page/components/image-gallery/ImageGallery.stories.js +3 -0
- package/lib/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.d.ts +1 -1
- package/lib/src/brand-page/components/images-section/ImagesSection.stories.js +2 -1
- package/lib/src/brand-page/components/social-links/SocialLinks.stories.js +3 -0
- package/lib/src/brand-page/components/testimonial-section/__fixtures__/data.js +3 -0
- package/lib/src/brand-page/components/text/Text.stories.js +2 -0
- package/lib/src/brand-page/models/index.d.ts +13 -0
- package/lib/src/brand-page/models/index.js +4 -0
- package/lib/src/brand-page/utils/migration/migration-01.js +2 -0
- package/lib/src/brand-page/utils/migration/migration-18.d.ts +14 -0
- package/lib/src/brand-page/utils/migration/migration-18.js +17 -0
- package/lib/src/brand-page/utils/migration.util.js +6 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +5 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.js +1 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js +1 -0
- package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +1 -1
- package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.js +4 -6
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +5 -0
- package/lib/src/brand-page-maker/composables/useQuickLinkBarVisibility.d.ts +17 -0
- package/lib/src/brand-page-maker/composables/useQuickLinkBarVisibility.js +23 -0
- package/lib/src/brand-page-maker/constants/config-settings-constant.js +4 -0
- package/lib/src/brand-page-maker/models/content-settings.js +4 -0
- package/lib/src/brand-page-maker/stores/ai-checkpoint/ai-checkpoint-store.d.ts +18 -0
- package/lib/src/css/library.brand-page-brandCrowd.min.css +29 -32
- package/lib/src/css/library.brand-page-brandPage.min.css +29 -32
- package/lib/src/css/library.brand-page-designCom.min.css +29 -32
- package/lib/src/css/library.brand-page-preview.min.css +29 -32
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-CHfUKgt-.js → lib-ClM5iHnZ.js} +19076 -18948
- package/lib/src/metadata-builder/ai-metadata-executor.js +24 -1
- package/lib/src/metadata-builder/builders/footer-builder.js +32 -41
- package/lib/src/metadata-builder/builders/item-id-utils.d.ts +54 -0
- package/lib/src/metadata-builder/builders/item-id-utils.js +96 -0
- package/lib/src/metadata-builder/builders/move-page-builder.d.ts +32 -0
- package/lib/src/metadata-builder/builders/move-page-builder.js +137 -0
- package/lib/src/metadata-builder/builders/nav-utils.d.ts +26 -0
- package/lib/src/metadata-builder/builders/nav-utils.js +95 -0
- package/lib/src/metadata-builder/builders/section-builders/image-gallery-builder.js +57 -68
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +58 -93
- package/lib/src/metadata-builder/builders/section-builders/move-section-builder.d.ts +13 -1
- package/lib/src/metadata-builder/builders/section-builders/move-section-builder.js +40 -30
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +66 -99
- package/lib/src/metadata-builder/builders/section-builders/social-links-builder.js +57 -17
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +51 -85
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +50 -74
- package/lib/src/metadata-builder/builders/section-field-maps.js +17 -0
- package/lib/src/metadata-builder/builders/set-page-visibility-builder.d.ts +23 -0
- package/lib/src/metadata-builder/builders/set-page-visibility-builder.js +83 -0
- package/lib/src/metadata-builder/metadata-executor.js +4 -0
- package/lib/src/metadata-builder/models.d.ts +2 -0
- package/lib/src/metadata-builder/models.js +2 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +31 -7
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +2 -0
- package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +84 -48
- package/lib/src/shared/content-settings/components/links-field/LinksField.mixin.js +2 -0
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -0
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +2 -0
- package/lib/src/utils/minify-brand-page-metadata.d.ts +2 -0
- package/lib/src/utils/minify-brand-page-metadata.js +8 -1
- package/package.json +1 -1
- package/src/brand-page/components/button/Button.vue +20 -0
- package/src/brand-page/components/button/Button.vue.test.ts +175 -0
- package/src/brand-page/components/image-gallery/ImageGallery.stories.ts +3 -0
- package/src/brand-page/components/image-gallery/ImageGallery.test.ts +1 -0
- package/src/brand-page/components/image-gallery/masonry/MasonryGallery.mixin.ts +2 -1
- package/src/brand-page/components/images-section/ImagesSection.stories.ts +2 -1
- package/src/brand-page/components/social-links/SocialLinks.stories.ts +3 -0
- package/src/brand-page/components/social-links/SocialLinks.vue.test.ts +5 -0
- package/src/brand-page/components/testimonial-section/__fixtures__/data.ts +3 -0
- package/src/brand-page/components/text/Text.stories.ts +2 -0
- package/src/brand-page/models/index.ts +17 -0
- package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +23 -3
- package/src/brand-page/utils/__snapshots__/migration2.util.test.ts.snap +6 -0
- package/src/brand-page/utils/__snapshots__/model.util.test.ts.snap +12 -0
- package/src/brand-page/utils/migration/migration-01.ts +2 -0
- package/src/brand-page/utils/migration/migration-18.test.ts +131 -0
- package/src/brand-page/utils/migration/migration-18.ts +22 -0
- package/src/brand-page/utils/migration.util.ts +7 -0
- package/src/brand-page/utils/personalisation.util.test.ts +4 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +5 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.stories.ts +1 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +2 -2
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +1 -0
- package/src/brand-page-maker/components/device/Device.vue +0 -1
- package/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.ts +4 -7
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +6 -0
- package/src/brand-page-maker/composables/useQuickLinkBarVisibility.test.ts +81 -0
- package/src/brand-page-maker/composables/useQuickLinkBarVisibility.ts +25 -0
- package/src/brand-page-maker/constants/config-settings-constant.ts +4 -0
- package/src/brand-page-maker/models/content-settings.ts +4 -0
- package/src/metadata-builder/ai-metadata-executor.ts +31 -1
- package/src/metadata-builder/builders/footer-builder.test.ts +335 -28
- package/src/metadata-builder/builders/footer-builder.ts +40 -57
- package/src/metadata-builder/builders/item-id-utils.test.ts +184 -0
- package/src/metadata-builder/builders/item-id-utils.ts +117 -0
- package/src/metadata-builder/builders/move-page-builder.ts +227 -0
- package/src/metadata-builder/builders/nav-utils.ts +141 -0
- package/src/metadata-builder/builders/section-builders/image-gallery-builder.ts +62 -88
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +66 -129
- package/src/metadata-builder/builders/section-builders/move-section-builder.ts +58 -35
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +105 -160
- package/src/metadata-builder/builders/section-builders/social-links-builder.ts +65 -20
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +83 -146
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +71 -122
- package/src/metadata-builder/builders/section-field-maps.ts +18 -0
- package/src/metadata-builder/builders/set-page-visibility-builder.ts +122 -0
- package/src/metadata-builder/metadata-executor.ts +4 -0
- package/src/metadata-builder/models.ts +2 -0
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +32 -7
- package/src/metadata-builder/parsers/section-tool-arguments.ts +84 -48
- package/src/shared/content-settings/components/links-field/LinksField.mixin.ts +2 -0
- package/src/utils/minify-brand-page-metadata.ts +14 -2
|
@@ -44,6 +44,7 @@ export const Carousel = () => {
|
|
|
44
44
|
content.galleryStyles = undefined;
|
|
45
45
|
content.images = new Array(10).fill(0).map((_, i) => {
|
|
46
46
|
return {
|
|
47
|
+
id: `gallery-carousel-item-${i}`,
|
|
47
48
|
imageUrl: `https://picsum.photos/${300 * ((i + 1) / 4)}/${300 * ((i + 1) / 4)}?random=${i}`,
|
|
48
49
|
width: 300,
|
|
49
50
|
height: 300,
|
|
@@ -71,6 +72,7 @@ export const Masonry = () => {
|
|
|
71
72
|
const content = createInitialImageGalleryContent();
|
|
72
73
|
content.images = new Array(10).fill(0).map((_, i) => {
|
|
73
74
|
return {
|
|
75
|
+
id: `gallery-masonry-item-${i}`,
|
|
74
76
|
imageUrl: `https://picsum.photos/${300 * ((i + 1) / 4)}/${300 * ((i + 1) / 4)}?random=${i}`,
|
|
75
77
|
width: 564,
|
|
76
78
|
height: 416,
|
|
@@ -98,6 +100,7 @@ export const Grid = () => {
|
|
|
98
100
|
const content = createInitialImageGalleryContent();
|
|
99
101
|
content.images = new Array(10).fill(0).map((_, i) => {
|
|
100
102
|
return {
|
|
103
|
+
id: `gallery-grid-item-${i}`,
|
|
101
104
|
imageUrl: `https://picsum.photos/${300 * ((i + 1) / 4)}/${300 * ((i + 1) / 4)}?random=${i}`,
|
|
102
105
|
width: 564,
|
|
103
106
|
height: 416,
|
|
@@ -2,7 +2,7 @@ import type { PropType } from 'vue';
|
|
|
2
2
|
import type { ImageGalleryViewModel } from '../../../view-models';
|
|
3
3
|
import type { DebounceHandle } from 'lodash.debounce';
|
|
4
4
|
import type { BrandPageContext, ImageGalleryItem } from '../../../models';
|
|
5
|
-
interface IndexedImageGalleryItem extends ImageGalleryItem {
|
|
5
|
+
interface IndexedImageGalleryItem extends Omit<ImageGalleryItem, 'id'> {
|
|
6
6
|
id: number;
|
|
7
7
|
}
|
|
8
8
|
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
@@ -41,8 +41,9 @@ export const Images = () => {
|
|
|
41
41
|
},
|
|
42
42
|
data() {
|
|
43
43
|
const content = createInitialImagesSectionContent();
|
|
44
|
-
content.items = new Array(2).fill(0).map(() => {
|
|
44
|
+
content.items = new Array(2).fill(0).map((_, i) => {
|
|
45
45
|
return {
|
|
46
|
+
id: `images-section-item-${i}`,
|
|
46
47
|
imageUrl: 'https://bc-user-uploads.brandcrowd.com/public/media-int/6b3a4d19-e95c-4d59-aa22-ac033a2cec2f/1116870a-c672-4306-b515-32f8d5d6e10c',
|
|
47
48
|
width: 564,
|
|
48
49
|
height: 416,
|
|
@@ -11,6 +11,7 @@ const viewModel = {
|
|
|
11
11
|
title: 'Follow us on',
|
|
12
12
|
links: [
|
|
13
13
|
{
|
|
14
|
+
id: 'social-link-facebook',
|
|
14
15
|
imageUrl: 'facebook',
|
|
15
16
|
url: '',
|
|
16
17
|
imageTitle: '',
|
|
@@ -21,6 +22,7 @@ const viewModel = {
|
|
|
21
22
|
imageLink: '',
|
|
22
23
|
},
|
|
23
24
|
{
|
|
25
|
+
id: 'social-link-instagram',
|
|
24
26
|
imageUrl: 'instagram',
|
|
25
27
|
url: 'https://www.instagram.com',
|
|
26
28
|
imageTitle: '',
|
|
@@ -31,6 +33,7 @@ const viewModel = {
|
|
|
31
33
|
imageLink: '',
|
|
32
34
|
},
|
|
33
35
|
{
|
|
36
|
+
id: 'social-link-empty',
|
|
34
37
|
imageUrl: '',
|
|
35
38
|
url: '',
|
|
36
39
|
imageTitle: '',
|
|
@@ -9,6 +9,7 @@ export const viewModel = {
|
|
|
9
9
|
displayStyle: 'centered',
|
|
10
10
|
items: [
|
|
11
11
|
{
|
|
12
|
+
id: 'testimonial-1',
|
|
12
13
|
testimonials: faker.lorem.paragraphs(1),
|
|
13
14
|
imageUrl: unsplashImage,
|
|
14
15
|
name: '1',
|
|
@@ -17,6 +18,7 @@ export const viewModel = {
|
|
|
17
18
|
colorReplacements: [],
|
|
18
19
|
},
|
|
19
20
|
{
|
|
21
|
+
id: 'testimonial-2',
|
|
20
22
|
testimonials: faker.lorem.paragraphs(3),
|
|
21
23
|
imageUrl: unsplashImage,
|
|
22
24
|
name: '2',
|
|
@@ -25,6 +27,7 @@ export const viewModel = {
|
|
|
25
27
|
colorReplacements: [],
|
|
26
28
|
},
|
|
27
29
|
{
|
|
30
|
+
id: 'testimonial-3',
|
|
28
31
|
testimonials: faker.lorem.paragraphs(5),
|
|
29
32
|
imageUrl: 'https://source.unsplash.com/random/200x200?3',
|
|
30
33
|
name: '3',
|
|
@@ -31,6 +31,7 @@ const BSviewModel = {
|
|
|
31
31
|
text: 'asdasjdlkasjmdlkmsad',
|
|
32
32
|
textItems: [
|
|
33
33
|
{
|
|
34
|
+
id: 'text-item-1',
|
|
34
35
|
text: 'lorem ipsum',
|
|
35
36
|
textStyle: {
|
|
36
37
|
fontSize: '1rem',
|
|
@@ -39,6 +40,7 @@ const BSviewModel = {
|
|
|
39
40
|
},
|
|
40
41
|
},
|
|
41
42
|
{
|
|
43
|
+
id: 'text-item-2',
|
|
42
44
|
text: 'lorem ipsum',
|
|
43
45
|
textStyle: {
|
|
44
46
|
fontSize: '1rem',
|
|
@@ -110,6 +110,13 @@ export interface ImageContent extends Content {
|
|
|
110
110
|
height?: number;
|
|
111
111
|
}
|
|
112
112
|
export interface ImageItem {
|
|
113
|
+
/**
|
|
114
|
+
* Stable per-item identifier. Mirrors the section-level `Content.id` one
|
|
115
|
+
* level deeper so AI tool calls can reference items by id rather than by
|
|
116
|
+
* positional index. Backfilled on load for persisted data that predates
|
|
117
|
+
* item ids (see ensureItemIds), so it is always present at runtime.
|
|
118
|
+
*/
|
|
119
|
+
id: string;
|
|
113
120
|
imageUrl: string;
|
|
114
121
|
imageTitle: string;
|
|
115
122
|
width: number;
|
|
@@ -311,6 +318,8 @@ export interface ShapeItem extends ImageItem {
|
|
|
311
318
|
paragraphOverride?: string;
|
|
312
319
|
}
|
|
313
320
|
export interface TestimonialItems {
|
|
321
|
+
/** Stable per-item identifier. See ImageItem.id. */
|
|
322
|
+
id: string;
|
|
314
323
|
imageUrl: string;
|
|
315
324
|
name: string;
|
|
316
325
|
position: string;
|
|
@@ -325,6 +334,8 @@ export interface TestimonialItems {
|
|
|
325
334
|
positionOverride?: string;
|
|
326
335
|
}
|
|
327
336
|
export interface TextItem {
|
|
337
|
+
/** Stable per-item identifier. See ImageItem.id. */
|
|
338
|
+
id: string;
|
|
328
339
|
text: string;
|
|
329
340
|
textStyle: TextStyleDeclaration;
|
|
330
341
|
textOverride?: string;
|
|
@@ -385,6 +396,8 @@ export interface AboutSectionContent extends Content {
|
|
|
385
396
|
size?: string;
|
|
386
397
|
}
|
|
387
398
|
export interface LinksItem {
|
|
399
|
+
/** Stable per-item identifier. See ImageItem.id. */
|
|
400
|
+
id: string;
|
|
388
401
|
imageUrl: string;
|
|
389
402
|
url: string;
|
|
390
403
|
size?: string;
|
|
@@ -11,6 +11,7 @@ import { NavigationDesktop, NavigationMobile } from './navigation-styles.model';
|
|
|
11
11
|
import { TEXT_STYLE_TYPES, TextStyles } from './styles.model';
|
|
12
12
|
import { EMPTY_LOGO_IMAGE_MODEL, LogoStyles } from './logo.model';
|
|
13
13
|
import cloneDeep from 'lodash.clonedeep';
|
|
14
|
+
import * as uuid from 'uuid';
|
|
14
15
|
export * from './brand-page-context.model';
|
|
15
16
|
export * from './payment.model';
|
|
16
17
|
export * from './content.model';
|
|
@@ -331,6 +332,7 @@ export class AbstractPageFooterStyles {
|
|
|
331
332
|
this.logoImageWidth = options.logoImageWidth || DEFAULT_LOGO_WIDTH;
|
|
332
333
|
this.socialLinks = options.socialLinks || [
|
|
333
334
|
{
|
|
335
|
+
id: uuid.v4(),
|
|
334
336
|
width: 0,
|
|
335
337
|
height: 0,
|
|
336
338
|
imageUrl: 'facebook',
|
|
@@ -340,6 +342,7 @@ export class AbstractPageFooterStyles {
|
|
|
340
342
|
imageLink: '',
|
|
341
343
|
},
|
|
342
344
|
{
|
|
345
|
+
id: uuid.v4(),
|
|
343
346
|
width: 0,
|
|
344
347
|
height: 0,
|
|
345
348
|
imageUrl: 'instagram',
|
|
@@ -349,6 +352,7 @@ export class AbstractPageFooterStyles {
|
|
|
349
352
|
imageLink: '',
|
|
350
353
|
},
|
|
351
354
|
{
|
|
355
|
+
id: uuid.v4(),
|
|
352
356
|
width: 0,
|
|
353
357
|
height: 0,
|
|
354
358
|
imageUrl: 'x',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as uuid from 'uuid';
|
|
1
2
|
import { getLogoVariationIndexFromLogoImageUrl, getLogoDraftTokenFromLogoImageUrl, safeGetLogoImageFromLogoImageUrl, } from '../logo.util';
|
|
2
3
|
import { DEFAULT_LETTER_SPACING, FOOTER_DISPLAY, NavigationDesktop, NavigationMobile, PageFooterDesktop, PageFooterMobile, PageHeaderDesktop, PageHeaderMobile, } from '../../';
|
|
3
4
|
import { ALIGN_CARD_CENTER_IMAGE, ALIGN_CARD_LEFT_IMAGE, ALIGN_CENTERED, ALIGN_LEFT_BIG_IMAGE, BIG_IMAGE, BRAND_PAGE_TYPES, DEFAULT_FONT_FAMILY_KEY, DEFAULT_LOGO_HEIGHT, DEFAULT_LOGO_WIDTH, DEFAULT_TEXT_ALIGN, FONT_FAMILY_CONFIGS, HEADER_DISPLAY, NAVIGATION_DISPLAY, LINE_HEIGHT_BODY, LINE_HEIGHT_HEADINGS, LINE_HEIGHT_TITLE, PAYMENT_OPTION_DISPLAY_TYPES, } from '../../';
|
|
@@ -25,6 +26,7 @@ export const applyTextContentTextToTextItemsMigration = (brandPageModel) => {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
const textItem = {
|
|
29
|
+
id: uuid.v4(),
|
|
28
30
|
text: item.text,
|
|
29
31
|
textStyle,
|
|
30
32
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MigrationData } from '../migration.util';
|
|
2
|
+
/**
|
|
3
|
+
* BP-5603: backfill a stable uuid `id` onto every nested item (gallery images,
|
|
4
|
+
* images/shapes/testimonial items, text items, section + footer social links)
|
|
5
|
+
* that predates the id-based edit model.
|
|
6
|
+
*
|
|
7
|
+
* The item `id` field is now non-nullable in the model, so every load path must
|
|
8
|
+
* guarantee it — not just the AI chat flow, which already stamps ids before
|
|
9
|
+
* minifying (see ensureBrandPageItemIds in useAiWebsiteBuilderChat). This
|
|
10
|
+
* migration is that guarantee for persisted data. Idempotent — existing ids are
|
|
11
|
+
* preserved, so re-running (e.g. render-only sites that never re-save) is a
|
|
12
|
+
* no-op beyond generating ids for items that still lack one.
|
|
13
|
+
*/
|
|
14
|
+
export declare const migration18: (migrationResult: MigrationData) => Promise<MigrationData>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ensureBrandPageItemIds } from '../../../metadata-builder/builders/item-id-utils';
|
|
2
|
+
/**
|
|
3
|
+
* BP-5603: backfill a stable uuid `id` onto every nested item (gallery images,
|
|
4
|
+
* images/shapes/testimonial items, text items, section + footer social links)
|
|
5
|
+
* that predates the id-based edit model.
|
|
6
|
+
*
|
|
7
|
+
* The item `id` field is now non-nullable in the model, so every load path must
|
|
8
|
+
* guarantee it — not just the AI chat flow, which already stamps ids before
|
|
9
|
+
* minifying (see ensureBrandPageItemIds in useAiWebsiteBuilderChat). This
|
|
10
|
+
* migration is that guarantee for persisted data. Idempotent — existing ids are
|
|
11
|
+
* preserved, so re-running (e.g. render-only sites that never re-save) is a
|
|
12
|
+
* no-op beyond generating ids for items that still lack one.
|
|
13
|
+
*/
|
|
14
|
+
export const migration18 = async (migrationResult) => {
|
|
15
|
+
ensureBrandPageItemIds(migrationResult.brandPageModel);
|
|
16
|
+
return migrationResult;
|
|
17
|
+
};
|
|
@@ -20,6 +20,7 @@ import { migration14 } from './migration/migration-14';
|
|
|
20
20
|
import { migration15 } from './migration/migration-15';
|
|
21
21
|
import { migration16 } from './migration/migration-16';
|
|
22
22
|
import { migration17 } from './migration/migration-17';
|
|
23
|
+
import { migration18 } from './migration/migration-18';
|
|
23
24
|
const MIGRATION_TABLE = [
|
|
24
25
|
{
|
|
25
26
|
version: 1,
|
|
@@ -132,6 +133,11 @@ const MIGRATION_TABLE = [
|
|
|
132
133
|
runAlways: true,
|
|
133
134
|
description: 'Padding Control backfill (BP-5699 Tier 2 + BP-5700 Store): backfill existing top/bottom spacing as explicit padding for text (12px), images/social links/shapes/booking (32px), store (16px), contact form (per layout), banner and about (per display style)',
|
|
134
135
|
},
|
|
136
|
+
{
|
|
137
|
+
version: 18,
|
|
138
|
+
migrateFn: migration18,
|
|
139
|
+
description: 'BP-5603: backfill stable item ids on all nested items (gallery/section/testimonial/text items, section + footer social links) — the item id is now non-nullable',
|
|
140
|
+
},
|
|
135
141
|
];
|
|
136
142
|
export const GetLatestModelVersion = () => Math.max(...MIGRATION_TABLE.map((x) => x.version));
|
|
137
143
|
export const migrateBrandPageModel = async (brandPageModel, options) => {
|
|
@@ -50,6 +50,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
50
50
|
isSaving: import("vue").ComputedRef<boolean>;
|
|
51
51
|
isPublishing: import("vue").ComputedRef<boolean>;
|
|
52
52
|
isPublished: import("vue").ComputedRef<boolean>;
|
|
53
|
+
shouldShowQuickLinkBar: import("vue").ComputedRef<boolean>;
|
|
53
54
|
isBrandPageOrIsBrandContact: import("vue").ComputedRef<boolean>;
|
|
54
55
|
brandPageViewModel: import("vue").ComputedRef<import("@brand-page").BrandPageViewModel>;
|
|
55
56
|
backUrl: import("vue").ComputedRef<string>;
|
|
@@ -13,6 +13,7 @@ import { UI_DEVICE_MODES, UI_SCREENSIZE_MODES, } from '@shared/models';
|
|
|
13
13
|
import { useBrandPageMakerStore, useBrandPageMakerUserStore, useLocalisedRouteStore, useUiStore, useSnapshotStore, useVideoStore, } from '@brand-page-maker/stores';
|
|
14
14
|
import { useHistoryStore } from '@brand-page-maker/stores/history/history-store';
|
|
15
15
|
import { useUndoRedoFlag } from '@brand-page-maker/composables/useUndoRedoFlag';
|
|
16
|
+
import { useQuickLinkBarVisibility } from '@brand-page-maker/composables/useQuickLinkBarVisibility';
|
|
16
17
|
import { useUiContentSettingsStore } from '@shared/content-settings/store';
|
|
17
18
|
import { useUiTemplateSettingsStore } from '@shared/template-settings/store';
|
|
18
19
|
import { useUiPageSettingsStore } from '@shared/page-settings/store';
|
|
@@ -73,6 +74,10 @@ export default defineComponent({
|
|
|
73
74
|
isSaving: computed(() => brandPageMakerStore.isSaving),
|
|
74
75
|
isPublishing: computed(() => brandPageMakerStore.isPublishing),
|
|
75
76
|
isPublished: computed(() => brandPageMakerStore.isPublished),
|
|
77
|
+
// Whether the QuickLinkBar renders — used to offset the preview (Device)
|
|
78
|
+
// and SideBar clear of the fixed bar on mobile. Must match the bar's own
|
|
79
|
+
// render condition, so it shares the same predicate.
|
|
80
|
+
shouldShowQuickLinkBar: useQuickLinkBarVisibility(),
|
|
76
81
|
isBrandPageOrIsBrandContact: computed(() => brandPageMakerStore.isBrandPageOrIsBrandContact),
|
|
77
82
|
brandPageViewModel: computed(() => brandPageMakerStore.brandPageViewModel),
|
|
78
83
|
backUrl: computed(() => localisedRouteStore.backToWebsiteManageUrlPath),
|
|
@@ -1281,6 +1281,7 @@ export const SampleImageGallery = () => {
|
|
|
1281
1281
|
const width = 300;
|
|
1282
1282
|
const height = 300;
|
|
1283
1283
|
imageGalleryContent.images.push({
|
|
1284
|
+
id: `gallery-item-${i}`,
|
|
1284
1285
|
width,
|
|
1285
1286
|
height,
|
|
1286
1287
|
imageUrl: `https://images.unsplash.com/photo-1659535915214-e7cbac112038?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMjQzOTV8MXwxfHNlYXJjaHw4fHxnYW1pbmd8ZW58MHx8fHwxNjY5MDc4ODE1&ixlib=rb-4.0.3&q=80&w=1080`,
|
package/lib/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.js
CHANGED
|
@@ -2212,6 +2212,7 @@ export const BRAND_PAGE_PERSONALISED = {
|
|
|
2212
2212
|
displayStyle: 'centered',
|
|
2213
2213
|
items: [
|
|
2214
2214
|
{
|
|
2215
|
+
id: 'shapes-section-item-1',
|
|
2215
2216
|
colorReplacements: [],
|
|
2216
2217
|
height: -1,
|
|
2217
2218
|
imageUrl: 'https://bcassetcdn.com/shapes/prod/00019160-9144-4bb3-af48-394a52845c37.svg',
|
|
@@ -292,11 +292,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
292
292
|
pushManageWebPageUnpublishClickEvent(): Promise<void>;
|
|
293
293
|
}>;
|
|
294
294
|
undoRedoEnabled: import("vue").ComputedRef<boolean>;
|
|
295
|
+
shouldShowBar: import("vue").ComputedRef<boolean>;
|
|
295
296
|
}, {
|
|
296
297
|
copied: boolean;
|
|
297
298
|
}, {
|
|
298
299
|
isPublished(): boolean;
|
|
299
|
-
shouldShowBar(): boolean;
|
|
300
300
|
brandPageUrl(): string;
|
|
301
301
|
copyButtonLabel(): string;
|
|
302
302
|
}, {
|
|
@@ -2,6 +2,7 @@ import { defineComponent } from 'vue';
|
|
|
2
2
|
import { CUSTOM_DOMAIN_STATUSES } from '@brand-page-maker/constants';
|
|
3
3
|
import { useBrandPageContainerStore, useEventManagerStore, } from '@brand-page-maker/stores';
|
|
4
4
|
import { useUndoRedoFlag } from '@brand-page-maker/composables/useUndoRedoFlag';
|
|
5
|
+
import { useQuickLinkBarVisibility } from '@brand-page-maker/composables/useQuickLinkBarVisibility';
|
|
5
6
|
import { quickLinkBarTr } from '@src/composables/useTranslate';
|
|
6
7
|
export default defineComponent({
|
|
7
8
|
props: {
|
|
@@ -19,6 +20,9 @@ export default defineComponent({
|
|
|
19
20
|
brandPageContainerStore: useBrandPageContainerStore(),
|
|
20
21
|
eventManagerStore: useEventManagerStore(),
|
|
21
22
|
undoRedoEnabled: useUndoRedoFlag(),
|
|
23
|
+
// Single source of truth for whether the bar renders — shared with the
|
|
24
|
+
// layout components (Device, SideBar) that offset content clear of it.
|
|
25
|
+
shouldShowBar: useQuickLinkBarVisibility(),
|
|
22
26
|
};
|
|
23
27
|
},
|
|
24
28
|
data() {
|
|
@@ -30,12 +34,6 @@ export default defineComponent({
|
|
|
30
34
|
isPublished() {
|
|
31
35
|
return this.brandPageContainerStore.isPublished;
|
|
32
36
|
},
|
|
33
|
-
// Only render the bar when at least one inner cluster has something to
|
|
34
|
-
// show. Otherwise we'd render an empty white strip — e.g. on an
|
|
35
|
-
// unpublished page with the undo flag off.
|
|
36
|
-
shouldShowBar() {
|
|
37
|
-
return Boolean(this.undoRedoEnabled) || this.isPublished;
|
|
38
|
-
},
|
|
39
37
|
brandPageUrl() {
|
|
40
38
|
if (this.brandPageContainerStore.isCustomDomainEnabled &&
|
|
41
39
|
this.brandPageContainerStore.customDomain &&
|
|
@@ -5,6 +5,7 @@ import { parseLogoThemeToCssStyles } from '../../../brand-page/utils/style.util'
|
|
|
5
5
|
import { AI_ASSISTANT_TOOL_NAMES } from '../../../metadata-builder/parsers/ai-toolcall-parser';
|
|
6
6
|
import { WebSocketGatewayClient, } from '../../../clients/websocket-gateway-client';
|
|
7
7
|
import { minifyBrandPageMetadata } from '../../../utils/minify-brand-page-metadata';
|
|
8
|
+
import { ensureBrandPageItemIds } from '../../../metadata-builder/builders/item-id-utils';
|
|
8
9
|
import { buildAssetManifest } from '../../../utils/build-asset-manifest';
|
|
9
10
|
import cloneDeep from 'lodash.clonedeep';
|
|
10
11
|
import { usePageNavigationStore } from '../../../shared/page-navigation/store/page-navigation-store';
|
|
@@ -179,6 +180,10 @@ export function useAiWebsiteBuilderChat() {
|
|
|
179
180
|
};
|
|
180
181
|
const buildMessagePayload = async (userPrompt) => {
|
|
181
182
|
const brandPageData = brandPageMakerStore.brandPageData;
|
|
183
|
+
// BP-5603: stamp stable uuid ids onto every nested item BEFORE minifying,
|
|
184
|
+
// so the id the AI is shown (and returns as `item_id`) is the exact id the
|
|
185
|
+
// executor matches when applying tool calls to this same live model.
|
|
186
|
+
ensureBrandPageItemIds(brandPageData);
|
|
182
187
|
const headerLogoDraftToken = brandPageData.pageHeaderDesktop?.logoImage?.logoDraftToken ??
|
|
183
188
|
uiStore.logoDraftToken;
|
|
184
189
|
const [assets, logoContext] = await Promise.all([
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ComputedRef } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Whether the QuickLinkBar is rendered in the maker.
|
|
4
|
+
*
|
|
5
|
+
* The bar shows when at least one of its inner clusters has something to
|
|
6
|
+
* display: the undo/redo controls (flag on, non-admin — see
|
|
7
|
+
* {@link useUndoRedoFlag}) OR the published-URL cluster (page published).
|
|
8
|
+
*
|
|
9
|
+
* This is the single source of truth shared by the bar itself
|
|
10
|
+
* (`QuickLinkBar`) and the layout components that offset their content to sit
|
|
11
|
+
* clear of the fixed bar on mobile (`Device`, `SideBar`). Keeping the offset
|
|
12
|
+
* bound to the same predicate the bar renders on prevents the two from
|
|
13
|
+
* drifting — a drift where the bar showed for the undo/redo reason but the
|
|
14
|
+
* offset only accounted for the published reason caused the bar to overlap
|
|
15
|
+
* the mobile preview.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useQuickLinkBarVisibility(): ComputedRef<boolean>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
import { useBrandPageContainerStore } from '@brand-page-maker/stores';
|
|
3
|
+
import { useUndoRedoFlag } from './useUndoRedoFlag';
|
|
4
|
+
/**
|
|
5
|
+
* Whether the QuickLinkBar is rendered in the maker.
|
|
6
|
+
*
|
|
7
|
+
* The bar shows when at least one of its inner clusters has something to
|
|
8
|
+
* display: the undo/redo controls (flag on, non-admin — see
|
|
9
|
+
* {@link useUndoRedoFlag}) OR the published-URL cluster (page published).
|
|
10
|
+
*
|
|
11
|
+
* This is the single source of truth shared by the bar itself
|
|
12
|
+
* (`QuickLinkBar`) and the layout components that offset their content to sit
|
|
13
|
+
* clear of the fixed bar on mobile (`Device`, `SideBar`). Keeping the offset
|
|
14
|
+
* bound to the same predicate the bar renders on prevents the two from
|
|
15
|
+
* drifting — a drift where the bar showed for the undo/redo reason but the
|
|
16
|
+
* offset only accounted for the published reason caused the bar to overlap
|
|
17
|
+
* the mobile preview.
|
|
18
|
+
*/
|
|
19
|
+
export function useQuickLinkBarVisibility() {
|
|
20
|
+
const containerStore = useBrandPageContainerStore();
|
|
21
|
+
const undoRedoEnabled = useUndoRedoFlag();
|
|
22
|
+
return computed(() => undoRedoEnabled.value || containerStore.isPublished);
|
|
23
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SOCIAL_LINKS_ICON_DISPLAY_STYLES, BRAND_PAGE_TYPES, DIVIDER_STYLES, MEDIA_TYPES, BUTTON_LINK_TYPE, FONT_SIZE_BODY, LINE_HEIGHT_BODY, MIN_TEXT_SIZE_PX, MAX_TEXT_SIZE_PX, TEXT_COLUMNS, DEFAULT_SHAPE_SIZE, PAYMENT_OPTION_DISPLAY_TYPES, PAYMENT_OPTION_IMAGE_TYPES, GettyVideoMedia, } from '@brand-page';
|
|
2
2
|
import { createInitialButtonContent, createInitialImageContent, createInitialProfileContent, createInitialTextContent, createInitialVideoContent, createInitialLogoContent, createInitialMapContent, createInitialImageGalleryContent, createInitialGeneralLinkContent, createInitialMailingListContent, createInitialRequestPaymentContent, createInitialSupportMeContent, createInitialContactFormContent, CONTENT_SETTINGS_DISPLAY_MODES, createInitialBannerSectionContent, createInitialSocialLinksContent, createInitialImagesSectionContent, createInitialTestimonialSectionContent, createInitialAboutSectionContent, createInitialDividerSectionContent, createInitialShapesSectionContent, VARIANT_DISPLAY_MODES, createInitialShopContent, createInitialBookingSectionContent, } from '../models';
|
|
3
|
+
import * as uuid from 'uuid';
|
|
3
4
|
import { colorConvertor, backgroundColorConvertor, borderColorConvertor, displayStyleConvertor, galleryTypeConvertor, imageAspectRatioConvertor, textAlignmentOptionsConvertor, videoContentStateConvertor, fillColorConvertor, bannerAlignDisplayStyleConvertor, aboutDisplayStyleConvertor, dividerStyleConvertor, shapeSizeOptionsConvertor, buttonLinkStyleConvertor, textSizeValueConvertor, textColumnStyleConvertor, contactLayoutStyleConvertor, paymentLinkDisplayStyleConvertor, shopDisplayConvertor, shopAspectRatioConvertor, } from '../convertors';
|
|
4
5
|
import { ALIGN_CENTERED, DISPLAY_STYLE_COLLAPSED, DISPLAY_STYLE_PREVIEW, } from '@brand-page';
|
|
5
6
|
import { imageFieldVisibilityAssessor, imageOptionVisibilityAssessor, imageGalleryFieldVisibilityAssessor, cardFillVisibilityAssessor, mediaSectionItemsFieldTypeAssessor, dividerToggleFieldVisibilityAssessor, shapeSectionItemsFieldTypeAssessor, colorReplacementVisibilityTypeAssessor, colorReplacementProfileVisibilityTypeAssessor, colorReplacementIconVisibilityTypeAssessor, imagesSectionCardStyleVisibilityAssessor, contactCardDisplayTypeVisibilityAssessor, imageUrlVisibilityAssessor, displayTypeVisibilityAssessor, logoFieldVisibilityAssessor, shapesSectionCardStyleVisibilityAssessor, shopImageOptionVisibilityAssessor, shopItemColorVisibility, personalisationOverrideVisibility, } from '../assessors';
|
|
@@ -167,6 +168,7 @@ const imageGalleryReplaceImageSettings = () => ({
|
|
|
167
168
|
content.images = [];
|
|
168
169
|
}
|
|
169
170
|
content.images.push({
|
|
171
|
+
id: uuid.v4(),
|
|
170
172
|
imageUrl: value.imageUrl,
|
|
171
173
|
imageTitle: value.imageTitle,
|
|
172
174
|
height: value.height,
|
|
@@ -372,6 +374,7 @@ const shapesImageReplaceImageSettings = () => ({
|
|
|
372
374
|
setContentMedia: (content, value, index) => {
|
|
373
375
|
if (index === undefined || index === null) {
|
|
374
376
|
content.items?.push({
|
|
377
|
+
id: uuid.v4(),
|
|
375
378
|
imageUrl: value.imageUrl,
|
|
376
379
|
imageTitle: '',
|
|
377
380
|
paragraph: '',
|
|
@@ -402,6 +405,7 @@ const textImageReplaceImageSettings = () => ({
|
|
|
402
405
|
setContentMedia: (content, value, index) => {
|
|
403
406
|
if (index === undefined || index === null) {
|
|
404
407
|
content.items?.push({
|
|
408
|
+
id: uuid.v4(),
|
|
405
409
|
imageUrl: value.imageUrl,
|
|
406
410
|
imageTitle: value.imageTitle,
|
|
407
411
|
paragraph: '',
|
|
@@ -153,6 +153,7 @@ export const createInitialTextContent = (options) => {
|
|
|
153
153
|
textItems: options?.brandPageType === 'brandSite'
|
|
154
154
|
? [
|
|
155
155
|
{
|
|
156
|
+
id: uuid.v4(),
|
|
156
157
|
text: contentSettingsTr(`defaultTextValue`),
|
|
157
158
|
textStyle: {
|
|
158
159
|
applyAutoScale: options?.brandPageType === BRAND_PAGE_TYPES.brandSite,
|
|
@@ -706,6 +707,7 @@ export const createInitialSocialLinksContent = (options) => {
|
|
|
706
707
|
title: contentSettingsTr(`followUsOnTitle`),
|
|
707
708
|
links: [
|
|
708
709
|
{
|
|
710
|
+
id: uuid.v4(),
|
|
709
711
|
imageUrl: 'facebook',
|
|
710
712
|
url: 'https://www.facebook.com',
|
|
711
713
|
imageTitle: '',
|
|
@@ -716,6 +718,7 @@ export const createInitialSocialLinksContent = (options) => {
|
|
|
716
718
|
imageLink: '',
|
|
717
719
|
},
|
|
718
720
|
{
|
|
721
|
+
id: uuid.v4(),
|
|
719
722
|
imageUrl: 'instagram',
|
|
720
723
|
url: 'https://www.instagram.com',
|
|
721
724
|
imageTitle: '',
|
|
@@ -726,6 +729,7 @@ export const createInitialSocialLinksContent = (options) => {
|
|
|
726
729
|
imageLink: '',
|
|
727
730
|
},
|
|
728
731
|
{
|
|
732
|
+
id: uuid.v4(),
|
|
729
733
|
imageUrl: 'x',
|
|
730
734
|
url: 'https://www.x.com',
|
|
731
735
|
imageTitle: '',
|