@myissue/vue-website-page-builder 3.3.61 → 3.3.62
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/dist/vue-website-page-builder.js +4151 -4138
- package/dist/vue-website-page-builder.umd.cjs +32 -32
- package/package.json +5 -2
- package/src/App.vue +2 -2
- package/src/Components/PageBuilder/EditorMenu/Editables/BackgroundColorEditor.vue +1 -1
- package/src/Components/PageBuilder/EditorMenu/Editables/TextColorEditor.vue +1 -1
- package/src/composables/builderInstance.ts +1 -1
- package/src/index.ts +1 -1
- package/src/services/LocalStorageManager.ts +162 -0
- package/src/{composables → services}/PageBuilderService.ts +17 -159
- package/src/{DemoComponents/HomeSection.vue → tests/PageBuilderTest.vue} +7 -10
- package/src/{DemoComponents/DemoMediaLibraryComponent.vue → tests/TestComponents/DemoMediaLibraryComponentTest.vue} +1 -1
- package/src/tests/pageBuilderService.test.ts +66 -0
- package/src/types/index.ts +1 -1
- package/src/DemoComponents/oldhtmlfromdb.json +0 -46
- package/src/DemoComponents/rawHTML.ts +0 -143
- /package/src/{DemoComponents → Components}/DemoUnsplash.vue +0 -0
- /package/src/{DemoComponents/DemoBuilderComponents.vue → tests/TestComponents/DemoBuilderComponentsTest.vue} +0 -0
- /package/src/{DemoComponents/html.json → tests/componentsArray.test.json} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myissue/vue-website-page-builder",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.62",
|
|
4
4
|
"description": "Vue 3 page builder component with drag & drop functionality.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/vue-website-page-builder.umd.cjs",
|
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
"type-check": "vue-tsc --build",
|
|
65
65
|
"lint": "eslint . --fix",
|
|
66
66
|
"format": "prettier --write src/",
|
|
67
|
-
"prepublishOnly": "npm run build:lib"
|
|
67
|
+
"prepublishOnly": "npm run build:lib",
|
|
68
|
+
"test": "vitest"
|
|
68
69
|
},
|
|
69
70
|
"dependencies": {
|
|
70
71
|
"@headlessui/vue": "^1.7.23",
|
|
@@ -95,6 +96,7 @@
|
|
|
95
96
|
"eslint": "^9.22.0",
|
|
96
97
|
"eslint-plugin-vue": "~10.0.0",
|
|
97
98
|
"jiti": "^2.4.2",
|
|
99
|
+
"jsdom": "^26.1.0",
|
|
98
100
|
"npm-run-all2": "^7.0.2",
|
|
99
101
|
"postcss": "^8.4.39",
|
|
100
102
|
"prettier": "3.5.3",
|
|
@@ -102,6 +104,7 @@
|
|
|
102
104
|
"typescript": "~5.8.0",
|
|
103
105
|
"vite": "^6.2.4",
|
|
104
106
|
"vite-plugin-vue-devtools": "^7.7.2",
|
|
107
|
+
"vitest": "^3.2.4",
|
|
105
108
|
"vue-tsc": "^2.2.8"
|
|
106
109
|
}
|
|
107
110
|
}
|
package/src/App.vue
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import Navbar from './Components/Homepage/Navbar.vue'
|
|
3
|
-
import
|
|
3
|
+
import PageBuilderTest from './tests/PageBuilderTest.vue'
|
|
4
4
|
import Footer from './Components/Homepage/Footer.vue'
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<template>
|
|
8
8
|
<div>
|
|
9
9
|
<Navbar></Navbar>
|
|
10
|
-
<
|
|
10
|
+
<PageBuilderTest></PageBuilderTest>
|
|
11
11
|
<Footer></Footer>
|
|
12
12
|
</div>
|
|
13
13
|
</template>
|
|
@@ -57,7 +57,7 @@ watch(
|
|
|
57
57
|
|
|
58
58
|
<ListboxButton
|
|
59
59
|
v-if="!globalPageLayout"
|
|
60
|
-
class="pbx-h-10 pbx-w-10 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white
|
|
60
|
+
class="pbx-h-10 pbx-w-10 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white focus-visible:pbx-ring-0"
|
|
61
61
|
>
|
|
62
62
|
<div class="pbx-flex pbx-flex-col">
|
|
63
63
|
<div class="pbx-flex pbx-gap-2 pbx-items-center">
|
|
@@ -57,7 +57,7 @@ watch(
|
|
|
57
57
|
|
|
58
58
|
<ListboxButton
|
|
59
59
|
v-if="!globalPageLayout"
|
|
60
|
-
class="pbx-h-10 pbx-w-10 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white
|
|
60
|
+
class="pbx-h-10 pbx-w-10 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-50 pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white focus-visible:pbx-ring-0"
|
|
61
61
|
>
|
|
62
62
|
<div class="pbx-flex pbx-flex-col">
|
|
63
63
|
<div class="pbx-flex pbx-gap-2 pbx-items-center">
|
package/src/index.ts
CHANGED
|
@@ -20,6 +20,6 @@ import './css/app.css'
|
|
|
20
20
|
// Export shared store instances for external access
|
|
21
21
|
export { sharedPageBuilderPinia, sharedPageBuilderStore } from './stores/shared-store'
|
|
22
22
|
|
|
23
|
-
// export { PageBuilderService } from './
|
|
23
|
+
// export { PageBuilderService } from './src/services/PageBuilderService.ts'
|
|
24
24
|
|
|
25
25
|
export { initPageBuilder, getPageBuilder } from './composables/builderInstance'
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { usePageBuilderStateStore } from '../stores/shared-store'
|
|
2
|
+
|
|
3
|
+
export class LocalStorageManager {
|
|
4
|
+
private pageBuilderStateStore: ReturnType<typeof usePageBuilderStateStore>
|
|
5
|
+
private sanitizeForLocalStorage: (input: string) => string
|
|
6
|
+
|
|
7
|
+
constructor(
|
|
8
|
+
pageBuilderStateStore: ReturnType<typeof usePageBuilderStateStore>,
|
|
9
|
+
sanitizeForLocalStorage: (input: string) => string,
|
|
10
|
+
) {
|
|
11
|
+
this.pageBuilderStateStore = pageBuilderStateStore
|
|
12
|
+
this.sanitizeForLocalStorage = sanitizeForLocalStorage
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public updateLocalStorageItemName(): void {
|
|
16
|
+
const formtype =
|
|
17
|
+
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
18
|
+
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
|
|
19
|
+
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType
|
|
20
|
+
|
|
21
|
+
const formname =
|
|
22
|
+
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
23
|
+
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
|
|
24
|
+
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formName
|
|
25
|
+
|
|
26
|
+
const resourceData =
|
|
27
|
+
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
28
|
+
this.pageBuilderStateStore.getPageBuilderConfig.resourceData
|
|
29
|
+
|
|
30
|
+
// Logic for create resource
|
|
31
|
+
if (formtype === 'create') {
|
|
32
|
+
if (formname && formname.length > 0) {
|
|
33
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
34
|
+
`page-builder-create-resource-${this.sanitizeForLocalStorage(formname)}`,
|
|
35
|
+
)
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
this.pageBuilderStateStore.setLocalStorageItemName(`page-builder-create-resource`)
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Logic for create
|
|
44
|
+
// Logic for update and with resource form name
|
|
45
|
+
if (formtype === 'update') {
|
|
46
|
+
if (typeof formname === 'string' && formname.length > 0) {
|
|
47
|
+
//
|
|
48
|
+
//
|
|
49
|
+
if (resourceData && resourceData != null && !resourceData.title) {
|
|
50
|
+
// Check if id is missing, null, undefined, or an empty string (after trimming)
|
|
51
|
+
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
52
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
53
|
+
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}`,
|
|
54
|
+
)
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Runs when resourceData has title but no ID
|
|
60
|
+
if (resourceData && resourceData != null) {
|
|
61
|
+
if (
|
|
62
|
+
resourceData.title &&
|
|
63
|
+
typeof resourceData.title === 'string' &&
|
|
64
|
+
resourceData.title.length > 0
|
|
65
|
+
) {
|
|
66
|
+
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
67
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
68
|
+
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(resourceData.title)}`,
|
|
69
|
+
)
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Runs when resourceData has ID but no title
|
|
76
|
+
if (resourceData && resourceData != null) {
|
|
77
|
+
if (!resourceData.title && typeof resourceData.title !== 'string') {
|
|
78
|
+
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
79
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
80
|
+
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
81
|
+
)
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Runs when resourceData has both title and ID
|
|
88
|
+
if (resourceData && resourceData != null) {
|
|
89
|
+
if (
|
|
90
|
+
resourceData.title &&
|
|
91
|
+
typeof resourceData.title === 'string' &&
|
|
92
|
+
resourceData.title.length > 0
|
|
93
|
+
) {
|
|
94
|
+
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
95
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
96
|
+
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(resourceData.title)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
97
|
+
)
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Logic for update without without formname
|
|
105
|
+
if (!formname || (typeof formname === 'string' && formname.length === 0)) {
|
|
106
|
+
//
|
|
107
|
+
//
|
|
108
|
+
if (resourceData && resourceData != null && !resourceData.title) {
|
|
109
|
+
// Check if id is missing, null, undefined, or an empty string (after trimming)
|
|
110
|
+
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
111
|
+
this.pageBuilderStateStore.setLocalStorageItemName(`page-builder-update-resource`)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Runs when resourceData has title but no ID
|
|
117
|
+
if (resourceData && resourceData != null) {
|
|
118
|
+
if (
|
|
119
|
+
resourceData.title &&
|
|
120
|
+
typeof resourceData.title === 'string' &&
|
|
121
|
+
resourceData.title.length > 0
|
|
122
|
+
) {
|
|
123
|
+
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
124
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
125
|
+
`page-builder-update-resource-${this.sanitizeForLocalStorage(resourceData.title)}`,
|
|
126
|
+
)
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Runs when resourceData has ID but no title
|
|
133
|
+
if (resourceData && resourceData != null) {
|
|
134
|
+
if (!resourceData.title && typeof resourceData.title !== 'string') {
|
|
135
|
+
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
136
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
137
|
+
`page-builder-update-resource-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
138
|
+
)
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Runs when resourceData has both title and ID
|
|
145
|
+
if (resourceData && resourceData != null) {
|
|
146
|
+
if (
|
|
147
|
+
resourceData.title &&
|
|
148
|
+
typeof resourceData.title === 'string' &&
|
|
149
|
+
resourceData.title.length > 0
|
|
150
|
+
) {
|
|
151
|
+
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
152
|
+
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
153
|
+
`page-builder-update-resource-${this.sanitizeForLocalStorage(resourceData.title)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
154
|
+
)
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { LocalStorageManager } from './LocalStorageManager'
|
|
2
|
+
|
|
1
3
|
// Type definitions
|
|
2
4
|
import type {
|
|
3
5
|
BuilderResourceData,
|
|
@@ -6,7 +8,6 @@ import type {
|
|
|
6
8
|
PageBuilderConfig,
|
|
7
9
|
StartBuilderResult,
|
|
8
10
|
} from '../types'
|
|
9
|
-
|
|
10
11
|
import type { usePageBuilderStateStore } from '../stores/page-builder-state'
|
|
11
12
|
|
|
12
13
|
import tailwindFontSizes from '../utils/builder/tailwind-font-sizes'
|
|
@@ -19,16 +20,16 @@ import tailwindBorderStyleWidthPlusColor from '../utils/builder/tailwind-border-
|
|
|
19
20
|
import { computed, ref, nextTick } from 'vue'
|
|
20
21
|
import type { ComputedRef } from 'vue'
|
|
21
22
|
import { v4 as uuidv4 } from 'uuid'
|
|
22
|
-
import { delay } from '
|
|
23
|
+
import { delay } from '../composables/delay'
|
|
23
24
|
import { isEmptyObject } from '../helpers/isEmptyObject'
|
|
24
|
-
import { extractCleanHTMLFromPageBuilder } from '
|
|
25
|
+
import { extractCleanHTMLFromPageBuilder } from '../composables/extractCleanHTMLFromPageBuilder'
|
|
25
26
|
|
|
26
27
|
export class PageBuilderService {
|
|
27
28
|
// Class properties with types
|
|
28
29
|
private fontSizeRegex =
|
|
29
30
|
/^(sm:|md:|lg:|xl:|2xl:)?pbx-text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
protected pageBuilderStateStore: ReturnType<typeof usePageBuilderStateStore>
|
|
32
33
|
private getLocalStorageItemName: ComputedRef<string | null>
|
|
33
34
|
private getApplyImageToSelection: ComputedRef<ImageObject>
|
|
34
35
|
private getHyberlinkEnable: ComputedRef<boolean>
|
|
@@ -46,8 +47,13 @@ export class PageBuilderService {
|
|
|
46
47
|
// Holds data to be mounted when #pagebuilder is not yet present in the DOM
|
|
47
48
|
private pendingMountData: BuilderResourceData | null = null
|
|
48
49
|
private isPageBuilderMissingOnStart: boolean = false
|
|
50
|
+
private localStorageManager: LocalStorageManager
|
|
49
51
|
|
|
50
52
|
constructor(pageBuilderStateStore: ReturnType<typeof usePageBuilderStateStore>) {
|
|
53
|
+
this.localStorageManager = new LocalStorageManager(
|
|
54
|
+
pageBuilderStateStore,
|
|
55
|
+
this.sanitizeForLocalStorage,
|
|
56
|
+
)
|
|
51
57
|
this.hasStartedEditing = false
|
|
52
58
|
this.pageBuilderStateStore = pageBuilderStateStore
|
|
53
59
|
|
|
@@ -276,7 +282,7 @@ export class PageBuilderService {
|
|
|
276
282
|
validation = this.#validateUserProvidedComponents(passedComponentsArray)
|
|
277
283
|
|
|
278
284
|
// Update the localStorage key name based on the config/resource
|
|
279
|
-
this
|
|
285
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
280
286
|
|
|
281
287
|
// Page Builder is not Present in the DOM but Components have been passed to the Builder
|
|
282
288
|
if (!pagebuilder) {
|
|
@@ -1298,7 +1304,7 @@ export class PageBuilderService {
|
|
|
1298
1304
|
}
|
|
1299
1305
|
}
|
|
1300
1306
|
// Helper function to sanitize title for localStorage key
|
|
1301
|
-
|
|
1307
|
+
public sanitizeForLocalStorage(input: string): string {
|
|
1302
1308
|
return input
|
|
1303
1309
|
.trim() // Remove leading/trailing spaces
|
|
1304
1310
|
.toLowerCase() // Convert to lowercase
|
|
@@ -1308,154 +1314,6 @@ export class PageBuilderService {
|
|
|
1308
1314
|
.replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
|
|
1309
1315
|
}
|
|
1310
1316
|
|
|
1311
|
-
#updateLocalStorageItemName(): void {
|
|
1312
|
-
const formtype =
|
|
1313
|
-
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
1314
|
-
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
|
|
1315
|
-
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType
|
|
1316
|
-
|
|
1317
|
-
const formname =
|
|
1318
|
-
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
1319
|
-
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
|
|
1320
|
-
this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formName
|
|
1321
|
-
|
|
1322
|
-
const resourceData =
|
|
1323
|
-
this.pageBuilderStateStore.getPageBuilderConfig &&
|
|
1324
|
-
this.pageBuilderStateStore.getPageBuilderConfig.resourceData
|
|
1325
|
-
|
|
1326
|
-
// Logic for create resource
|
|
1327
|
-
if (formtype === 'create') {
|
|
1328
|
-
if (formname && formname.length > 0) {
|
|
1329
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1330
|
-
`page-builder-create-resource-${this.sanitizeForLocalStorage(formname)}`,
|
|
1331
|
-
)
|
|
1332
|
-
return
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
this.pageBuilderStateStore.setLocalStorageItemName(`page-builder-create-resource`)
|
|
1336
|
-
return
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
// Logic for create
|
|
1340
|
-
// Logic for update and with resource form name
|
|
1341
|
-
if (formtype === 'update') {
|
|
1342
|
-
if (typeof formname === 'string' && formname.length > 0) {
|
|
1343
|
-
//
|
|
1344
|
-
//
|
|
1345
|
-
if (resourceData && resourceData != null && !resourceData.title) {
|
|
1346
|
-
// Check if id is missing, null, undefined, or an empty string (after trimming)
|
|
1347
|
-
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
1348
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1349
|
-
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}`,
|
|
1350
|
-
)
|
|
1351
|
-
return
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
// Runs when resourceData has title but no ID
|
|
1356
|
-
if (resourceData && resourceData != null) {
|
|
1357
|
-
if (
|
|
1358
|
-
resourceData.title &&
|
|
1359
|
-
typeof resourceData.title === 'string' &&
|
|
1360
|
-
resourceData.title.length > 0
|
|
1361
|
-
) {
|
|
1362
|
-
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
1363
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1364
|
-
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(resourceData.title)}`,
|
|
1365
|
-
)
|
|
1366
|
-
return
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
|
|
1371
|
-
// Runs when resourceData has ID but no title
|
|
1372
|
-
if (resourceData && resourceData != null) {
|
|
1373
|
-
if (!resourceData.title && typeof resourceData.title !== 'string') {
|
|
1374
|
-
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
1375
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1376
|
-
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
1377
|
-
)
|
|
1378
|
-
return
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
|
-
// Runs when resourceData has both title and ID
|
|
1384
|
-
if (resourceData && resourceData != null) {
|
|
1385
|
-
if (
|
|
1386
|
-
resourceData.title &&
|
|
1387
|
-
typeof resourceData.title === 'string' &&
|
|
1388
|
-
resourceData.title.length > 0
|
|
1389
|
-
) {
|
|
1390
|
-
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
1391
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1392
|
-
`page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(resourceData.title)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
1393
|
-
)
|
|
1394
|
-
return
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
// Logic for update without without formname
|
|
1401
|
-
if (!formname || (typeof formname === 'string' && formname.length === 0)) {
|
|
1402
|
-
//
|
|
1403
|
-
//
|
|
1404
|
-
if (resourceData && resourceData != null && !resourceData.title) {
|
|
1405
|
-
// Check if id is missing, null, undefined, or an empty string (after trimming)
|
|
1406
|
-
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
1407
|
-
this.pageBuilderStateStore.setLocalStorageItemName(`page-builder-update-resource`)
|
|
1408
|
-
return
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
// Runs when resourceData has title but no ID
|
|
1413
|
-
if (resourceData && resourceData != null) {
|
|
1414
|
-
if (
|
|
1415
|
-
resourceData.title &&
|
|
1416
|
-
typeof resourceData.title === 'string' &&
|
|
1417
|
-
resourceData.title.length > 0
|
|
1418
|
-
) {
|
|
1419
|
-
if (!resourceData.id || typeof resourceData.id === 'string') {
|
|
1420
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1421
|
-
`page-builder-update-resource-${this.sanitizeForLocalStorage(resourceData.title)}`,
|
|
1422
|
-
)
|
|
1423
|
-
return
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
|
-
// Runs when resourceData has ID but no title
|
|
1429
|
-
if (resourceData && resourceData != null) {
|
|
1430
|
-
if (!resourceData.title && typeof resourceData.title !== 'string') {
|
|
1431
|
-
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
1432
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1433
|
-
`page-builder-update-resource-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
1434
|
-
)
|
|
1435
|
-
return
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
// Runs when resourceData has both title and ID
|
|
1441
|
-
if (resourceData && resourceData != null) {
|
|
1442
|
-
if (
|
|
1443
|
-
resourceData.title &&
|
|
1444
|
-
typeof resourceData.title === 'string' &&
|
|
1445
|
-
resourceData.title.length > 0
|
|
1446
|
-
) {
|
|
1447
|
-
if (resourceData.id || typeof resourceData.id === 'number') {
|
|
1448
|
-
this.pageBuilderStateStore.setLocalStorageItemName(
|
|
1449
|
-
`page-builder-update-resource-${this.sanitizeForLocalStorage(resourceData.title)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
|
|
1450
|
-
)
|
|
1451
|
-
return
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
|
|
1459
1317
|
/**
|
|
1460
1318
|
* Returns a clone of the given element with [hovered] and [selected] attributes
|
|
1461
1319
|
* removed from itself and all descendants. Does NOT mutate the live DOM.
|
|
@@ -1501,7 +1359,7 @@ export class PageBuilderService {
|
|
|
1501
1359
|
* Saves the current DOM state (components) to localStorage.
|
|
1502
1360
|
*/
|
|
1503
1361
|
#saveDomComponentsToLocalStorage() {
|
|
1504
|
-
this
|
|
1362
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1505
1363
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
1506
1364
|
if (!pagebuilder) return
|
|
1507
1365
|
|
|
@@ -1540,7 +1398,7 @@ export class PageBuilderService {
|
|
|
1540
1398
|
}
|
|
1541
1399
|
}
|
|
1542
1400
|
async removeCurrentComponentsFromLocalStorage() {
|
|
1543
|
-
this
|
|
1401
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1544
1402
|
await nextTick()
|
|
1545
1403
|
|
|
1546
1404
|
const key = this.getLocalStorageItemName.value
|
|
@@ -1609,7 +1467,7 @@ export class PageBuilderService {
|
|
|
1609
1467
|
|
|
1610
1468
|
//
|
|
1611
1469
|
async resumeEditingFromDraft() {
|
|
1612
|
-
this
|
|
1470
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1613
1471
|
|
|
1614
1472
|
const localStorageData = this.loadStoredComponentsFromStorage()
|
|
1615
1473
|
|
|
@@ -1629,7 +1487,7 @@ export class PageBuilderService {
|
|
|
1629
1487
|
}
|
|
1630
1488
|
|
|
1631
1489
|
async restoreOriginalContent() {
|
|
1632
|
-
this
|
|
1490
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1633
1491
|
|
|
1634
1492
|
this.pageBuilderStateStore.setIsRestoring(true)
|
|
1635
1493
|
await delay(400)
|
|
@@ -1653,7 +1511,7 @@ export class PageBuilderService {
|
|
|
1653
1511
|
}
|
|
1654
1512
|
|
|
1655
1513
|
loadStoredComponentsFromStorage() {
|
|
1656
|
-
this
|
|
1514
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1657
1515
|
if (!this.getLocalStorageItemName.value) return false
|
|
1658
1516
|
|
|
1659
1517
|
if (
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import FullWidthElement from '../Components/Layouts/FullWidthElement.vue'
|
|
3
3
|
import PageBuilder from '../PageBuilder/PageBuilder.vue'
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import DemoBuilderComponents from './DemoBuilderComponents.vue'
|
|
4
|
+
import DemoMediaLibraryComponentTest from '../tests/TestComponents/DemoMediaLibraryComponentTest.vue'
|
|
5
|
+
import DemoBuilderComponentsTest from '../tests/TestComponents/DemoBuilderComponentsTest.vue'
|
|
7
6
|
import { onMounted } from 'vue'
|
|
8
|
-
import
|
|
9
|
-
import html from './html.json'
|
|
10
|
-
import { rawHTML } from './rawHTML'
|
|
7
|
+
import componentsArray from '../tests/componentsArray.test.json'
|
|
11
8
|
|
|
12
9
|
import { getPageBuilder } from '../composables/builderInstance'
|
|
13
10
|
const pageBuilderService = getPageBuilder()
|
|
@@ -61,7 +58,7 @@ const configPageBuilder = {
|
|
|
61
58
|
image: '/jane_doe.jpg',
|
|
62
59
|
},
|
|
63
60
|
updateOrCreate: {
|
|
64
|
-
formType: '
|
|
61
|
+
formType: 'update',
|
|
65
62
|
formName: 'collection',
|
|
66
63
|
},
|
|
67
64
|
pageBuilderLogo: {
|
|
@@ -90,7 +87,7 @@ const configPageBuilder = {
|
|
|
90
87
|
} as const
|
|
91
88
|
|
|
92
89
|
onMounted(async () => {
|
|
93
|
-
const result = await pageBuilderService.startBuilder(configPageBuilder)
|
|
90
|
+
const result = await pageBuilderService.startBuilder(configPageBuilder, componentsArray)
|
|
94
91
|
console.log('Page Builder Result:', result)
|
|
95
92
|
//
|
|
96
93
|
//
|
|
@@ -132,8 +129,8 @@ onMounted(async () => {
|
|
|
132
129
|
</div>
|
|
133
130
|
</div>
|
|
134
131
|
<div class="pbx-m-4">
|
|
135
|
-
<!-- :CustomBuilderComponents="
|
|
136
|
-
<PageBuilder :CustomMediaLibraryComponent="
|
|
132
|
+
<!-- :CustomBuilderComponents="DemoBuilderComponentsTest" -->
|
|
133
|
+
<PageBuilder :CustomMediaLibraryComponent="DemoMediaLibraryComponentTest"></PageBuilder>
|
|
137
134
|
</div>
|
|
138
135
|
</div>
|
|
139
136
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { describe, it, expect, vi, beforeEach, beforeAll } from 'vitest'
|
|
3
|
+
import { PageBuilderService } from '../services/PageBuilderService'
|
|
4
|
+
import { usePageBuilderStateStore } from '../stores/page-builder-state'
|
|
5
|
+
import componentsArray from './componentsArray.test.json'
|
|
6
|
+
|
|
7
|
+
// Mock store (replace with your actual store or a better mock if needed)
|
|
8
|
+
const mockStore: ReturnType<typeof usePageBuilderStateStore> = {
|
|
9
|
+
setBuilderStarted: vi.fn(),
|
|
10
|
+
setPageBuilderConfig: vi.fn(),
|
|
11
|
+
getPageBuilderConfig: {},
|
|
12
|
+
setComponents: vi.fn(),
|
|
13
|
+
setIsLoadingGlobal: vi.fn(),
|
|
14
|
+
setIsRestoring: vi.fn(),
|
|
15
|
+
setIsLoadingResumeEditing: vi.fn(),
|
|
16
|
+
setHasLocalDraftForUpdate: vi.fn(),
|
|
17
|
+
setComponent: vi.fn(),
|
|
18
|
+
setElement: vi.fn(),
|
|
19
|
+
getLocalStorageItemName: 'test-key',
|
|
20
|
+
setLocalStorageItemName: vi.fn(),
|
|
21
|
+
// ...add more as needed for your test
|
|
22
|
+
} as unknown as ReturnType<typeof usePageBuilderStateStore>
|
|
23
|
+
|
|
24
|
+
const configPageBuilder = {
|
|
25
|
+
updateOrCreate: {
|
|
26
|
+
formType: 'update',
|
|
27
|
+
formName: 'collection',
|
|
28
|
+
},
|
|
29
|
+
// ...other config options as needed
|
|
30
|
+
} as const
|
|
31
|
+
|
|
32
|
+
beforeAll(() => {
|
|
33
|
+
// Create a fake #pagebuilder element in the DOM for the test
|
|
34
|
+
const div = document.createElement('div')
|
|
35
|
+
div.id = 'pagebuilder'
|
|
36
|
+
document.body.appendChild(div)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
describe('PageBuilderService', () => {
|
|
40
|
+
let service: PageBuilderService
|
|
41
|
+
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
// Reset mocks before each test
|
|
44
|
+
Object.values(mockStore).forEach(
|
|
45
|
+
(fn) =>
|
|
46
|
+
typeof fn === 'function' &&
|
|
47
|
+
typeof (fn as { mockClear?: () => void }).mockClear === 'function' &&
|
|
48
|
+
(fn as { mockClear: () => void }).mockClear(),
|
|
49
|
+
)
|
|
50
|
+
service = new PageBuilderService(mockStore)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should start builder and return a success message', async () => {
|
|
54
|
+
const result = await service.startBuilder(configPageBuilder, componentsArray)
|
|
55
|
+
expect(result).toHaveProperty('message', 'Page builder started successfully.')
|
|
56
|
+
expect(mockStore.setBuilderStarted).toHaveBeenCalledWith(true)
|
|
57
|
+
expect(mockStore.setPageBuilderConfig).toHaveBeenCalledWith(configPageBuilder)
|
|
58
|
+
// Add more assertions as needed
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('should handle missing components array gracefully', async () => {
|
|
62
|
+
const result = await service.startBuilder(configPageBuilder)
|
|
63
|
+
expect(result).toHaveProperty('message', 'Page builder started successfully.')
|
|
64
|
+
// Add more assertions for this scenario
|
|
65
|
+
})
|
|
66
|
+
})
|
package/src/types/index.ts
CHANGED