@designcrowd/library.brand-page 6.0.11 → 6.0.13
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-DopPc6g2.js → CreatedOnBrandCrowd-de-de-CBjFFeBP.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-CSHmaAWm.js → CreatedOnBrandCrowd-en-us-NuNXF81K.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-C4vM0p2e.js → CreatedOnBrandCrowd-es-es-BJG8nfug.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-ArpBbnxm.js → CreatedOnBrandCrowd-fr-ca-uX-nL53e.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-ArpBbnxm.js → CreatedOnBrandCrowd-fr-fr-uX-nL53e.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-CGAQLXiX.js → CreatedOnBrandCrowd-pt-br-DTrgFGQV.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-CGAQLXiX.js → CreatedOnBrandCrowd-pt-pt-DTrgFGQV.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-3WVSgB6t.js → CreatedOnDcom-de-de-DSfpxioT.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-Dx-RHXrH.js → CreatedOnDcom-en-us-C7G4gKem.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-CfnEYFMA.js → CreatedOnDcom-es-es-DVckCaji.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-BSHZTiUO.js → CreatedOnDcom-fr-ca-C5GDrm_C.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-DtHssrQb.js → CreatedOnDcom-fr-fr-v5eMm-j2.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-CdX1aRI8.js → CreatedOnDcom-pt-br-Dq3-fPUc.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-jy044FNL.js → CreatedOnDcom-pt-pt-DFsncYax.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.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/composables/ai-chat/useAiWebsiteBuilderChat.js +5 -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/index.mjs +84 -83
- package/lib/src/{lib-Bx7xK4dn.js → lib-BG-pyXi9.js} +19585 -19807
- 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/tracker.d.ts +2 -0
- package/lib/src/tracker.js +12 -0
- package/lib/src/tracker.mjs +12 -0
- package/lib/src/useEventTracker-DmQ6AkNn.js +356 -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 +16 -1
- 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.stories.ts +1 -0
- package/src/brand-page-maker/components/brand-page-maker/__fixtures__/brand-page-examples.ts +1 -0
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +6 -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/tracker.ts +28 -0
- package/src/utils/minify-brand-page-metadata.ts +14 -2
- package/lib/src/metadata-builder/builders/reorder-pages-builder.d.ts +0 -13
- package/lib/src/metadata-builder/builders/reorder-pages-builder.js +0 -49
- package/src/metadata-builder/builders/reorder-pages-builder.ts +0 -80
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { BrandPageModel, NavOrder } from '../../brand-page/models';
|
|
2
|
+
import {
|
|
3
|
+
BaseMetadataBuilder,
|
|
4
|
+
type BuilderResult,
|
|
5
|
+
type MetadataBuilderRequest,
|
|
6
|
+
} from '../models';
|
|
7
|
+
import type { Logger } from '../logger';
|
|
8
|
+
import { syncPagesWithNavOrders } from './nav-utils';
|
|
9
|
+
|
|
10
|
+
export interface SetPageVisibilityPayload {
|
|
11
|
+
/** The page whose visibility is toggled (resolved from page_id). */
|
|
12
|
+
pageId: string;
|
|
13
|
+
/** true = hide the page from the navigation; false = show it. */
|
|
14
|
+
isHidden: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Toggle a page's navigation visibility (the AI-chat equivalent of the page-settings
|
|
19
|
+
* "Hide page / Show page" menu). Sets `isHidden` on BOTH the matching `NavRoute`
|
|
20
|
+
* (in `model.nav.routes`) and the `PageModel` (in `model.pages`) — the two places the
|
|
21
|
+
* editor keeps in sync. No slug/order recompute (the nav order is unchanged); the
|
|
22
|
+
* published-site nav already filters hidden pages via `isHidden`.
|
|
23
|
+
*/
|
|
24
|
+
export class SetPageVisibilityBuilder extends BaseMetadataBuilder<SetPageVisibilityPayload> {
|
|
25
|
+
constructor(
|
|
26
|
+
request: MetadataBuilderRequest<SetPageVisibilityPayload>,
|
|
27
|
+
logger?: Logger,
|
|
28
|
+
) {
|
|
29
|
+
super(request, logger);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async validateAsync(): Promise<{ errors: string[] }> {
|
|
33
|
+
const errors: string[] = [];
|
|
34
|
+
|
|
35
|
+
if (!this.request.payload?.pageId) {
|
|
36
|
+
errors.push('pageId is required for set_page_visibility');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return { errors };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async buildAsync(model: BrandPageModel): Promise<BuilderResult> {
|
|
43
|
+
this.log('Build called');
|
|
44
|
+
|
|
45
|
+
const validation = await this.validateAsync();
|
|
46
|
+
|
|
47
|
+
if (validation.errors.length) {
|
|
48
|
+
return { request: this.request, model, errors: validation.errors };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const { pageId, isHidden } = this.request.payload!;
|
|
52
|
+
|
|
53
|
+
const targetRoute = model.nav.routes.find((r) => r.pageId === pageId);
|
|
54
|
+
|
|
55
|
+
if (!targetRoute) {
|
|
56
|
+
return {
|
|
57
|
+
request: this.request,
|
|
58
|
+
model,
|
|
59
|
+
errors: [`Page with ID "${pageId}" not found`],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Guards apply only when HIDING; showing a page is always safe.
|
|
64
|
+
if (isHidden) {
|
|
65
|
+
// --- GUARD: the home page (orders[0]) cannot be hidden ---
|
|
66
|
+
const homeRouteId = model.nav.orders[0]?.routeId;
|
|
67
|
+
|
|
68
|
+
if (homeRouteId === targetRoute.id) {
|
|
69
|
+
return {
|
|
70
|
+
request: this.request,
|
|
71
|
+
model,
|
|
72
|
+
errors: [
|
|
73
|
+
`Home page "${pageId}" cannot be hidden from the navigation`,
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// --- GUARD: cannot hide the last remaining visible page ---
|
|
79
|
+
const visibleCount = model.nav.routes.filter((r) => !r.isHidden).length;
|
|
80
|
+
|
|
81
|
+
if (!targetRoute.isHidden && visibleCount <= 1) {
|
|
82
|
+
return {
|
|
83
|
+
request: this.request,
|
|
84
|
+
model,
|
|
85
|
+
errors: [
|
|
86
|
+
`Cannot hide "${pageId}" — at least one page must stay visible`,
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Set on the NavRoute (drives the nav) and the PageModel (drives header page lists).
|
|
93
|
+
targetRoute.isHidden = isHidden;
|
|
94
|
+
|
|
95
|
+
const targetPage = model.pages.find((p) => p.id === pageId);
|
|
96
|
+
|
|
97
|
+
if (targetPage) {
|
|
98
|
+
targetPage.isHidden = isHidden;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Match the editor's page-navigation store (reorderVisibleAndHiddenRoutes): after any
|
|
102
|
+
// visibility change, float visible pages to the top and sink hidden pages to the bottom
|
|
103
|
+
// of the top-level nav order, stable within each group. Top-level only — mirrors the
|
|
104
|
+
// editor, which does not re-partition nested subRoutes. `model.pages` is then re-synced
|
|
105
|
+
// to the new DFS order (same as MovePageBuilder).
|
|
106
|
+
const routeById = new Map(model.nav.routes.map((r) => [r.id, r]));
|
|
107
|
+
const isOrderHidden = (o: NavOrder) =>
|
|
108
|
+
Boolean(routeById.get(o.routeId)?.isHidden);
|
|
109
|
+
const visibleOrders = model.nav.orders.filter((o) => !isOrderHidden(o));
|
|
110
|
+
const hiddenOrders = model.nav.orders.filter((o) => isOrderHidden(o));
|
|
111
|
+
|
|
112
|
+
model.nav.orders = [...visibleOrders, ...hiddenOrders];
|
|
113
|
+
|
|
114
|
+
syncPagesWithNavOrders(model);
|
|
115
|
+
|
|
116
|
+
this.log({
|
|
117
|
+
message: `Set page "${pageId}" visibility — isHidden: ${isHidden}`,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return { request: this.request, model };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -31,6 +31,8 @@ import {
|
|
|
31
31
|
import { AddPageBuilder } from './builders/add-page-builder';
|
|
32
32
|
import { RemovePageBuilder } from './builders/remove-page-builder';
|
|
33
33
|
import { RenamePageBuilder } from './builders/rename-page-builder';
|
|
34
|
+
import { MovePageBuilder } from './builders/move-page-builder';
|
|
35
|
+
import { SetPageVisibilityBuilder } from './builders/set-page-visibility-builder';
|
|
34
36
|
import { FooterBuilder } from './builders/footer-builder';
|
|
35
37
|
import { GlobalStylesBuilder } from './builders/global-styles-builder';
|
|
36
38
|
import { HeaderBuilder } from './builders/header-builder';
|
|
@@ -111,6 +113,8 @@ const getBuilderRegistry = (): Record<BuilderType, BuilderConstructor> => ({
|
|
|
111
113
|
[BUILDER_TYPES.ADD_PAGE]: AddPageBuilder,
|
|
112
114
|
[BUILDER_TYPES.REMOVE_PAGE]: RemovePageBuilder,
|
|
113
115
|
[BUILDER_TYPES.RENAME_PAGE]: RenamePageBuilder,
|
|
116
|
+
[BUILDER_TYPES.MOVE_PAGE]: MovePageBuilder,
|
|
117
|
+
[BUILDER_TYPES.SET_PAGE_VISIBILITY]: SetPageVisibilityBuilder,
|
|
114
118
|
|
|
115
119
|
// Footer operations
|
|
116
120
|
[BUILDER_TYPES.UPDATE_FOOTER]: FooterBuilder,
|
|
@@ -52,6 +52,8 @@ export const AI_ASSISTANT_TOOL_NAMES = {
|
|
|
52
52
|
ADD_PAGE: 'add_page',
|
|
53
53
|
REMOVE_PAGE: 'remove_page',
|
|
54
54
|
RENAME_PAGE: 'rename_page',
|
|
55
|
+
MOVE_PAGE: 'move_page',
|
|
56
|
+
SET_PAGE_VISIBILITY: 'set_page_visibility',
|
|
55
57
|
|
|
56
58
|
// Footer operation tools
|
|
57
59
|
UPDATE_FOOTER: 'update_footer',
|
|
@@ -169,7 +171,11 @@ export interface DeleteSectionArguments {
|
|
|
169
171
|
|
|
170
172
|
export interface MoveSectionArguments {
|
|
171
173
|
content_id: string;
|
|
172
|
-
|
|
174
|
+
/**
|
|
175
|
+
* Relative anchor on the destination page: the content_id to insert this section
|
|
176
|
+
* BEFORE (a page's first content_id moves it to the top). Omit to append to the end.
|
|
177
|
+
*/
|
|
178
|
+
move_before_content_id?: string;
|
|
173
179
|
target_page_id?: string;
|
|
174
180
|
}
|
|
175
181
|
|
|
@@ -187,8 +193,18 @@ export interface RenamePageArguments {
|
|
|
187
193
|
page_name: string;
|
|
188
194
|
}
|
|
189
195
|
|
|
190
|
-
export interface
|
|
191
|
-
|
|
196
|
+
export interface MovePageArguments {
|
|
197
|
+
page_id: string;
|
|
198
|
+
/** Destination parent page_id, or null/omitted for top-level. */
|
|
199
|
+
parent_page_id?: string | null;
|
|
200
|
+
/** Sibling anchor page_id to insert before, or "__end__"/omitted to append. */
|
|
201
|
+
move_before_page_id?: string | null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface SetPageVisibilityArguments {
|
|
205
|
+
page_id: string;
|
|
206
|
+
/** true = hide the page from the navigation; false = show it. */
|
|
207
|
+
is_hidden: boolean;
|
|
192
208
|
}
|
|
193
209
|
|
|
194
210
|
/**
|
|
@@ -202,8 +218,17 @@ export interface ReorderPagesArguments {
|
|
|
202
218
|
export interface UndoArguments {}
|
|
203
219
|
|
|
204
220
|
export interface FooterSocialLinkItem {
|
|
205
|
-
|
|
206
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Stable id of the existing link to update or move. Omit to ADD a new link.
|
|
223
|
+
* Mirrors the section-level item_id convention (BP-5603).
|
|
224
|
+
*/
|
|
225
|
+
item_id?: string;
|
|
226
|
+
/**
|
|
227
|
+
* Id of an existing link to position this link before (insert for new links,
|
|
228
|
+
* move for existing ones). Use "__end__" for the end of the list. Omit to
|
|
229
|
+
* leave an existing link in place / append a new link.
|
|
230
|
+
*/
|
|
231
|
+
move_before_item_id?: string;
|
|
207
232
|
social_link_icon?: string;
|
|
208
233
|
url?: string;
|
|
209
234
|
}
|
|
@@ -227,8 +252,8 @@ export interface UpdateFooterArguments {
|
|
|
227
252
|
copyright_text_style?: TextStyleArguments;
|
|
228
253
|
social_links?: FooterSocialLinkItem[];
|
|
229
254
|
_replace_social_links?: boolean;
|
|
230
|
-
_remove_social_link_indices
|
|
231
|
-
|
|
255
|
+
/** Stable ids of social links to remove. Order-independent (replaces index-based _remove_social_link_indices). */
|
|
256
|
+
_remove_social_link_ids?: string[];
|
|
232
257
|
/** Desktop-only styling (display_style, background_color, icon_color, is_logo_visible, logo sizes). */
|
|
233
258
|
desktop?: ViewportFooterOverrides;
|
|
234
259
|
/** Mobile-only styling (display_style, background_color, icon_color, is_logo_visible, logo sizes). */
|
|
@@ -142,10 +142,15 @@ export interface ProfileSectionArguments {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
export interface TextSectionItem {
|
|
145
|
-
/**
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
|
|
145
|
+
/** Stable id of the existing item to update or move. Omit to ADD a new item. */
|
|
146
|
+
item_id?: string;
|
|
147
|
+
/**
|
|
148
|
+
* Id of an existing item to position this item before (insert for new items,
|
|
149
|
+
* move for existing ones). Use "__end__" for the end of the list. Omit to
|
|
150
|
+
* leave an existing item in place / append a new item. Mirrors the
|
|
151
|
+
* section-level move_before_content_id.
|
|
152
|
+
*/
|
|
153
|
+
move_before_item_id?: string;
|
|
149
154
|
text?: RichTextField;
|
|
150
155
|
text_style?: TextStyleArguments;
|
|
151
156
|
}
|
|
@@ -159,11 +164,11 @@ export interface TextSectionArguments {
|
|
|
159
164
|
/** Multiple text items (BrandSite) */
|
|
160
165
|
items?: TextSectionItem[];
|
|
161
166
|
_replace_items?: boolean;
|
|
162
|
-
/**
|
|
163
|
-
|
|
164
|
-
/** New order as array of current 0-based indices */
|
|
165
|
-
_reorder_items?: number[];
|
|
167
|
+
/** Stable ids of items to remove. Order-independent (no index shifting). */
|
|
168
|
+
_remove_item_ids?: string[];
|
|
166
169
|
background_color?: string | null;
|
|
170
|
+
padding_top?: number;
|
|
171
|
+
padding_bottom?: number;
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
export interface ImageSectionArguments {
|
|
@@ -172,10 +177,15 @@ export interface ImageSectionArguments {
|
|
|
172
177
|
}
|
|
173
178
|
|
|
174
179
|
export interface ImageGalleryItem {
|
|
175
|
-
/**
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
|
|
180
|
+
/** Stable id of the existing item to update or move. Omit to ADD a new item. */
|
|
181
|
+
item_id?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Id of an existing item to position this item before (insert for new items,
|
|
184
|
+
* move for existing ones). Use "__end__" for the end of the list. Omit to
|
|
185
|
+
* leave an existing item in place / append a new item. Mirrors the
|
|
186
|
+
* section-level move_before_content_id.
|
|
187
|
+
*/
|
|
188
|
+
move_before_item_id?: string;
|
|
179
189
|
image_url?: string;
|
|
180
190
|
caption?: string;
|
|
181
191
|
}
|
|
@@ -185,10 +195,10 @@ export interface ImageGallerySectionArguments {
|
|
|
185
195
|
gallery_type?: 'grid' | 'carousel' | 'masonry';
|
|
186
196
|
is_full_width?: boolean;
|
|
187
197
|
_replace_items?: boolean;
|
|
188
|
-
/**
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
198
|
+
/** Stable ids of items to remove. Order-independent (no index shifting). */
|
|
199
|
+
_remove_item_ids?: string[];
|
|
200
|
+
padding_top?: number;
|
|
201
|
+
padding_bottom?: number;
|
|
192
202
|
}
|
|
193
203
|
|
|
194
204
|
export interface GeneralLinkSectionArguments {
|
|
@@ -256,10 +266,15 @@ export interface TiktokSectionArguments {
|
|
|
256
266
|
}
|
|
257
267
|
|
|
258
268
|
export interface SocialLink {
|
|
259
|
-
/**
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
|
|
269
|
+
/** Stable id of the existing item to update or move. Omit to ADD a new item. */
|
|
270
|
+
item_id?: string;
|
|
271
|
+
/**
|
|
272
|
+
* Id of an existing item to position this item before (insert for new items,
|
|
273
|
+
* move for existing ones). Use "__end__" for the end of the list. Omit to
|
|
274
|
+
* leave an existing item in place / append a new item. Mirrors the
|
|
275
|
+
* section-level move_before_content_id.
|
|
276
|
+
*/
|
|
277
|
+
move_before_item_id?: string;
|
|
263
278
|
platform?:
|
|
264
279
|
| 'facebook'
|
|
265
280
|
| 'x'
|
|
@@ -280,10 +295,10 @@ export interface SocialLinksSectionArguments {
|
|
|
280
295
|
/** Style for the icon container background (used when icon_style is 'square' or 'circle'). */
|
|
281
296
|
icon_background_style?: TextStyleArguments;
|
|
282
297
|
_replace_items?: boolean;
|
|
283
|
-
/**
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
298
|
+
/** Stable ids of items to remove. Order-independent (no index shifting). */
|
|
299
|
+
_remove_item_ids?: string[];
|
|
300
|
+
padding_top?: number;
|
|
301
|
+
padding_bottom?: number;
|
|
287
302
|
}
|
|
288
303
|
|
|
289
304
|
export interface MailingListSectionArguments {
|
|
@@ -292,6 +307,8 @@ export interface MailingListSectionArguments {
|
|
|
292
307
|
accepted_fields?: 'emailOnly' | 'nameAndEmail';
|
|
293
308
|
title_style?: TextStyleArguments;
|
|
294
309
|
button_text_style?: ButtonTextStyleArguments;
|
|
310
|
+
padding_top?: number;
|
|
311
|
+
padding_bottom?: number;
|
|
295
312
|
}
|
|
296
313
|
|
|
297
314
|
export interface ContactFormFieldToggle {
|
|
@@ -324,6 +341,8 @@ export interface ContactFormSectionArguments {
|
|
|
324
341
|
fields?: ContactFormFieldToggle[];
|
|
325
342
|
background_color?: string | null;
|
|
326
343
|
card_style?: CardStyleArguments;
|
|
344
|
+
padding_top?: number;
|
|
345
|
+
padding_bottom?: number;
|
|
327
346
|
}
|
|
328
347
|
|
|
329
348
|
export interface BannerSectionArguments {
|
|
@@ -350,6 +369,8 @@ export interface BannerSectionArguments {
|
|
|
350
369
|
button_text_style?: ButtonTextStyleArguments;
|
|
351
370
|
background_color?: string | null;
|
|
352
371
|
card_style?: CardStyleArguments;
|
|
372
|
+
padding_top?: number;
|
|
373
|
+
padding_bottom?: number;
|
|
353
374
|
}
|
|
354
375
|
|
|
355
376
|
export interface AboutSectionArguments {
|
|
@@ -368,13 +389,20 @@ export interface AboutSectionArguments {
|
|
|
368
389
|
title_style?: TextStyleArguments;
|
|
369
390
|
paragraph_style?: TextStyleArguments;
|
|
370
391
|
background_color?: string | null;
|
|
392
|
+
padding_top?: number;
|
|
393
|
+
padding_bottom?: number;
|
|
371
394
|
}
|
|
372
395
|
|
|
373
396
|
export interface ImagesSectionItem {
|
|
374
|
-
/**
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
|
|
397
|
+
/** Stable id of the existing item to update or move. Omit to ADD a new item. */
|
|
398
|
+
item_id?: string;
|
|
399
|
+
/**
|
|
400
|
+
* Id of an existing item to position this item before (insert for new items,
|
|
401
|
+
* move for existing ones). Use "__end__" for the end of the list. Omit to
|
|
402
|
+
* leave an existing item in place / append a new item. Mirrors the
|
|
403
|
+
* section-level move_before_content_id.
|
|
404
|
+
*/
|
|
405
|
+
move_before_item_id?: string;
|
|
378
406
|
image_url?: string;
|
|
379
407
|
heading?: string;
|
|
380
408
|
text?: string;
|
|
@@ -393,10 +421,8 @@ export interface ImagesSectionArguments {
|
|
|
393
421
|
| 'center-card-aligned-image'
|
|
394
422
|
| 'alternate-image';
|
|
395
423
|
_replace_items?: boolean;
|
|
396
|
-
/**
|
|
397
|
-
|
|
398
|
-
/** New order as array of current 0-based indices */
|
|
399
|
-
_reorder_items?: number[];
|
|
424
|
+
/** Stable ids of items to remove. Order-independent (no index shifting). */
|
|
425
|
+
_remove_item_ids?: string[];
|
|
400
426
|
title_style?: TextStyleArguments;
|
|
401
427
|
description_style?: TextStyleArguments;
|
|
402
428
|
heading_style?: TextStyleArguments;
|
|
@@ -409,10 +435,15 @@ export interface ImagesSectionArguments {
|
|
|
409
435
|
}
|
|
410
436
|
|
|
411
437
|
export interface TestimonialItem {
|
|
412
|
-
/**
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
|
|
438
|
+
/** Stable id of the existing item to update or move. Omit to ADD a new item. */
|
|
439
|
+
item_id?: string;
|
|
440
|
+
/**
|
|
441
|
+
* Id of an existing item to position this item before (insert for new items,
|
|
442
|
+
* move for existing ones). Use "__end__" for the end of the list. Omit to
|
|
443
|
+
* leave an existing item in place / append a new item. Mirrors the
|
|
444
|
+
* section-level move_before_content_id.
|
|
445
|
+
*/
|
|
446
|
+
move_before_item_id?: string;
|
|
416
447
|
testimonial?: string;
|
|
417
448
|
name?: string;
|
|
418
449
|
position?: string;
|
|
@@ -426,23 +457,28 @@ export interface TestimonialSectionArguments {
|
|
|
426
457
|
items?: TestimonialItem[];
|
|
427
458
|
display_style?: 'centered' | 'big-image' | 'columns';
|
|
428
459
|
_replace_items?: boolean;
|
|
429
|
-
/**
|
|
430
|
-
|
|
431
|
-
/** New order as array of current 0-based indices */
|
|
432
|
-
_reorder_items?: number[];
|
|
460
|
+
/** Stable ids of items to remove. Order-independent (no index shifting). */
|
|
461
|
+
_remove_item_ids?: string[];
|
|
433
462
|
title_style?: TextStyleArguments;
|
|
434
463
|
testimonial_style?: TextStyleArguments;
|
|
435
464
|
name_style?: TextStyleArguments;
|
|
436
465
|
position_style?: TextStyleArguments;
|
|
437
466
|
background_style?: BackgroundStyleArguments;
|
|
438
467
|
card_style?: CardStyleArguments;
|
|
468
|
+
padding_top?: number;
|
|
469
|
+
padding_bottom?: number;
|
|
439
470
|
}
|
|
440
471
|
|
|
441
472
|
export interface ShapesSectionItem {
|
|
442
|
-
/**
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
|
|
473
|
+
/** Stable id of the existing item to update or move. Omit to ADD a new item. */
|
|
474
|
+
item_id?: string;
|
|
475
|
+
/**
|
|
476
|
+
* Id of an existing item to position this item before (insert for new items,
|
|
477
|
+
* move for existing ones). Use "__end__" for the end of the list. Omit to
|
|
478
|
+
* leave an existing item in place / append a new item. Mirrors the
|
|
479
|
+
* section-level move_before_content_id.
|
|
480
|
+
*/
|
|
481
|
+
move_before_item_id?: string;
|
|
446
482
|
icon_image_url?: string;
|
|
447
483
|
shape_url?: string;
|
|
448
484
|
color_theme?: string;
|
|
@@ -462,10 +498,8 @@ export interface ShapesSectionArguments {
|
|
|
462
498
|
| 'center-card-aligned-image'
|
|
463
499
|
| 'alternate-image';
|
|
464
500
|
_replace_items?: boolean;
|
|
465
|
-
/**
|
|
466
|
-
|
|
467
|
-
/** New order as array of current 0-based indices */
|
|
468
|
-
_reorder_items?: number[];
|
|
501
|
+
/** Stable ids of items to remove. Order-independent (no index shifting). */
|
|
502
|
+
_remove_item_ids?: string[];
|
|
469
503
|
title_style?: TextStyleArguments;
|
|
470
504
|
description_style?: TextStyleArguments;
|
|
471
505
|
heading_style?: TextStyleArguments;
|
|
@@ -485,6 +519,8 @@ export interface BookingSectionArguments {
|
|
|
485
519
|
description_style?: TextStyleArguments;
|
|
486
520
|
button_text_style?: ButtonTextStyleArguments;
|
|
487
521
|
background_color?: string | null;
|
|
522
|
+
padding_top?: number;
|
|
523
|
+
padding_bottom?: number;
|
|
488
524
|
}
|
|
489
525
|
|
|
490
526
|
export interface DividerSectionArguments {
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
UpdateItemValuePayload,
|
|
12
12
|
} from '../../models';
|
|
13
13
|
import cloneDeep from 'lodash.clonedeep';
|
|
14
|
+
import * as uuid from 'uuid';
|
|
14
15
|
|
|
15
16
|
const ACCEPTED_MIME_TYPES = 'image/png, image/jpeg, image/svg+xml';
|
|
16
17
|
|
|
@@ -88,6 +89,7 @@ export default defineComponent({
|
|
|
88
89
|
},
|
|
89
90
|
addNewItem(): void {
|
|
90
91
|
const newItem: LinksItem = {
|
|
92
|
+
id: uuid.v4(),
|
|
91
93
|
height: 0,
|
|
92
94
|
imageTitle: '',
|
|
93
95
|
width: 0,
|
package/src/tracker.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Lightweight subpath entry: `@designcrowd/library.brand-page/tracker`.
|
|
2
|
+
// Re-exports ONLY the analytics surface (useEventTracker + event constants),
|
|
3
|
+
// which depends solely on `vue`. This lets consumers import the tracker without
|
|
4
|
+
// pulling the full library graph (maker, TipTap, renderer). See
|
|
5
|
+
// docs/plans/multi-entrypoint-tree-shaking.md and the /tracker proposal.
|
|
6
|
+
//
|
|
7
|
+
// IMPORTANT: useEventTracker holds module-scoped pub/sub state (LISTENERS,
|
|
8
|
+
// GLOBAL_EVENT_PROPS). It MUST resolve to a single shared instance across this
|
|
9
|
+
// entry and the root `.` entry, or subscribers registered here won't receive
|
|
10
|
+
// events published via the root. The multi-entry build hoists it into a shared
|
|
11
|
+
// chunk (both `index` and `tracker` import it) — verified at build time.
|
|
12
|
+
export {
|
|
13
|
+
useEventTracker,
|
|
14
|
+
EVENTS,
|
|
15
|
+
SELECT_LOCATIONS,
|
|
16
|
+
UPGRADE_CTA_LOCATIONS,
|
|
17
|
+
AI_CTA_LOCATIONS,
|
|
18
|
+
TRIGGER_TYPE,
|
|
19
|
+
PUBLISH_MODAL_CONTINUATION_EVENTS,
|
|
20
|
+
GENERATE_TEXT_CONTINUATION_EVENTS,
|
|
21
|
+
PUBLISH_OPTION_MODAL_CONTINUATION_EVENTS,
|
|
22
|
+
} from './brand-page-maker/composables/useEventTracker';
|
|
23
|
+
export type {
|
|
24
|
+
EventTracker,
|
|
25
|
+
BpEventTrackerEvent,
|
|
26
|
+
BpGlobalEventProps,
|
|
27
|
+
BpUpsellEventProps,
|
|
28
|
+
} from './brand-page-maker/composables/useEventTracker';
|
|
@@ -19,7 +19,12 @@ import {
|
|
|
19
19
|
resolveLogoData,
|
|
20
20
|
} from './build-asset-manifest';
|
|
21
21
|
|
|
22
|
-
type MinifiedFooterSocialLink = {
|
|
22
|
+
type MinifiedFooterSocialLink = {
|
|
23
|
+
position: number;
|
|
24
|
+
id?: string;
|
|
25
|
+
imageUrl: string;
|
|
26
|
+
url: string;
|
|
27
|
+
};
|
|
23
28
|
|
|
24
29
|
type MinifiedFooter = {
|
|
25
30
|
displayStyle?: string;
|
|
@@ -284,6 +289,7 @@ const minifyContent = (
|
|
|
284
289
|
...(Array.isArray(c.items) && {
|
|
285
290
|
items: c.items.map((item: any, index: number) => ({
|
|
286
291
|
position: index + 1,
|
|
292
|
+
...(item.id && { id: item.id }),
|
|
287
293
|
...st('name', item.name, editor),
|
|
288
294
|
...st('jobTitle', item.position, editor),
|
|
289
295
|
...st('testimonials', item.testimonials, editor),
|
|
@@ -312,6 +318,7 @@ const minifyContent = (
|
|
|
312
318
|
...(Array.isArray(c.items) && {
|
|
313
319
|
items: c.items.map((item: any, index: number) => ({
|
|
314
320
|
position: index + 1,
|
|
321
|
+
...(item.id && { id: item.id }),
|
|
315
322
|
...includeImageWithKey(item.imageUrl),
|
|
316
323
|
...st('title', item.title, editor),
|
|
317
324
|
...st('paragraph', item.paragraph, editor),
|
|
@@ -342,6 +349,7 @@ const minifyContent = (
|
|
|
342
349
|
...(Array.isArray(c.textItems) && {
|
|
343
350
|
textItems: c.textItems.map((item: any, index: number) => ({
|
|
344
351
|
position: index + 1,
|
|
352
|
+
...(item.id && { id: item.id }),
|
|
345
353
|
...st('text', item.text, editor),
|
|
346
354
|
...(includeStyle(item.textStyle) && { textStyle: item.textStyle }),
|
|
347
355
|
})),
|
|
@@ -431,6 +439,7 @@ const minifyContent = (
|
|
|
431
439
|
...(Array.isArray(c.links) && {
|
|
432
440
|
links: c.links.map((link: any, index: number) => ({
|
|
433
441
|
position: index + 1,
|
|
442
|
+
...(link.id && { id: link.id }),
|
|
434
443
|
...(includeString(link.url) && { url: link.url }),
|
|
435
444
|
...includeImageWithKey(link.imageUrl),
|
|
436
445
|
})),
|
|
@@ -474,6 +483,7 @@ const minifyContent = (
|
|
|
474
483
|
...(Array.isArray(c.images) && {
|
|
475
484
|
images: c.images.map((img: any, index: number) => ({
|
|
476
485
|
position: index + 1,
|
|
486
|
+
...(img.id && { id: img.id }),
|
|
477
487
|
...includeImageWithKey(img.imageUrl),
|
|
478
488
|
...st('imageTitle', img.imageTitle, editor),
|
|
479
489
|
})),
|
|
@@ -523,7 +533,9 @@ const minifyFooter = (
|
|
|
523
533
|
logoImageWidth: footer.logoImageWidth || undefined,
|
|
524
534
|
...(logoAssetKey && { logoAssetKey }),
|
|
525
535
|
socialLinks: footer.socialLinks?.length
|
|
526
|
-
? footer.socialLinks.map((l) => ({
|
|
536
|
+
? footer.socialLinks.map((l, index) => ({
|
|
537
|
+
position: index + 1,
|
|
538
|
+
...(l.id && { id: l.id }),
|
|
527
539
|
imageUrl: l.imageUrl || '',
|
|
528
540
|
url: l.url || '',
|
|
529
541
|
}))
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { BrandPageModel } from '../../brand-page/models';
|
|
2
|
-
import { BaseMetadataBuilder, type BuilderResult, type MetadataBuilderRequest } from '../models';
|
|
3
|
-
import type { Logger } from '../logger';
|
|
4
|
-
export interface ReorderPagesPayload {
|
|
5
|
-
pageOrder: string[];
|
|
6
|
-
}
|
|
7
|
-
export declare class ReorderPagesBuilder extends BaseMetadataBuilder<ReorderPagesPayload> {
|
|
8
|
-
constructor(request: MetadataBuilderRequest<ReorderPagesPayload>, logger?: Logger);
|
|
9
|
-
validateAsync(): Promise<{
|
|
10
|
-
errors: string[];
|
|
11
|
-
}>;
|
|
12
|
-
buildAsync(model: BrandPageModel): Promise<BuilderResult>;
|
|
13
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { BaseMetadataBuilder, } from '../models';
|
|
2
|
-
export class ReorderPagesBuilder extends BaseMetadataBuilder {
|
|
3
|
-
constructor(request, logger) {
|
|
4
|
-
super(request, logger);
|
|
5
|
-
}
|
|
6
|
-
async validateAsync() {
|
|
7
|
-
const errors = [];
|
|
8
|
-
const payload = this.request.payload;
|
|
9
|
-
if (!payload?.pageOrder?.length) {
|
|
10
|
-
errors.push('page_order is required for reorder_pages');
|
|
11
|
-
}
|
|
12
|
-
return { errors };
|
|
13
|
-
}
|
|
14
|
-
async buildAsync(model) {
|
|
15
|
-
this.log('Build called');
|
|
16
|
-
const validation = await this.validateAsync();
|
|
17
|
-
if (validation.errors.length) {
|
|
18
|
-
return { request: this.request, model, errors: validation.errors };
|
|
19
|
-
}
|
|
20
|
-
const { pageOrder } = this.request.payload;
|
|
21
|
-
// Build pageId → routeId lookup from nav.routes
|
|
22
|
-
const pageIdToRouteId = new Map();
|
|
23
|
-
for (const route of model.nav.routes) {
|
|
24
|
-
pageIdToRouteId.set(route.pageId, route.id);
|
|
25
|
-
}
|
|
26
|
-
// Build new nav.orders from the flat page_order (array of pageIds)
|
|
27
|
-
const newOrders = [];
|
|
28
|
-
const seenRouteIds = new Set();
|
|
29
|
-
for (const pageId of pageOrder) {
|
|
30
|
-
const routeId = pageIdToRouteId.get(pageId);
|
|
31
|
-
if (!routeId)
|
|
32
|
-
continue;
|
|
33
|
-
newOrders.push({ routeId, subRoutes: [] });
|
|
34
|
-
seenRouteIds.add(routeId);
|
|
35
|
-
}
|
|
36
|
-
// Safety: append any routes not mentioned (don't lose pages)
|
|
37
|
-
for (const route of model.nav.routes) {
|
|
38
|
-
const routeId = pageIdToRouteId.get(route.pageId);
|
|
39
|
-
if (routeId && !seenRouteIds.has(routeId)) {
|
|
40
|
-
newOrders.push({ routeId, subRoutes: [] });
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
model.nav.orders = newOrders;
|
|
44
|
-
this.log({
|
|
45
|
-
message: `Reordered pages: ${pageOrder.join(', ')}`,
|
|
46
|
-
});
|
|
47
|
-
return { request: this.request, model };
|
|
48
|
-
}
|
|
49
|
-
}
|