@myissue/vue-website-page-builder 3.3.61 → 3.3.63
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 +4253 -4236
- 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 +23 -160
- package/src/{DemoComponents/HomeSection.vue → tests/PageBuilderTest.vue} +6 -9
- 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.63",
|
|
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) {
|
|
@@ -335,7 +341,12 @@ export class PageBuilderService {
|
|
|
335
341
|
//
|
|
336
342
|
if (formType === 'update' || formType === 'create') {
|
|
337
343
|
if (!this.pendingMountData) {
|
|
338
|
-
//
|
|
344
|
+
//
|
|
345
|
+
//
|
|
346
|
+
if (!passedComponentsArray && !this.isPageBuilderMissingOnStart && localStorageData) {
|
|
347
|
+
await this.#completeMountProcess(localStorageData)
|
|
348
|
+
return
|
|
349
|
+
}
|
|
339
350
|
if (passedComponentsArray && !localStorageData) {
|
|
340
351
|
await this.#completeMountProcess(JSON.stringify(passedComponentsArray), true)
|
|
341
352
|
return
|
|
@@ -1298,7 +1309,7 @@ export class PageBuilderService {
|
|
|
1298
1309
|
}
|
|
1299
1310
|
}
|
|
1300
1311
|
// Helper function to sanitize title for localStorage key
|
|
1301
|
-
|
|
1312
|
+
public sanitizeForLocalStorage(input: string): string {
|
|
1302
1313
|
return input
|
|
1303
1314
|
.trim() // Remove leading/trailing spaces
|
|
1304
1315
|
.toLowerCase() // Convert to lowercase
|
|
@@ -1308,154 +1319,6 @@ export class PageBuilderService {
|
|
|
1308
1319
|
.replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
|
|
1309
1320
|
}
|
|
1310
1321
|
|
|
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
1322
|
/**
|
|
1460
1323
|
* Returns a clone of the given element with [hovered] and [selected] attributes
|
|
1461
1324
|
* removed from itself and all descendants. Does NOT mutate the live DOM.
|
|
@@ -1501,7 +1364,7 @@ export class PageBuilderService {
|
|
|
1501
1364
|
* Saves the current DOM state (components) to localStorage.
|
|
1502
1365
|
*/
|
|
1503
1366
|
#saveDomComponentsToLocalStorage() {
|
|
1504
|
-
this
|
|
1367
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1505
1368
|
const pagebuilder = document.querySelector('#pagebuilder')
|
|
1506
1369
|
if (!pagebuilder) return
|
|
1507
1370
|
|
|
@@ -1540,7 +1403,7 @@ export class PageBuilderService {
|
|
|
1540
1403
|
}
|
|
1541
1404
|
}
|
|
1542
1405
|
async removeCurrentComponentsFromLocalStorage() {
|
|
1543
|
-
this
|
|
1406
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1544
1407
|
await nextTick()
|
|
1545
1408
|
|
|
1546
1409
|
const key = this.getLocalStorageItemName.value
|
|
@@ -1609,7 +1472,7 @@ export class PageBuilderService {
|
|
|
1609
1472
|
|
|
1610
1473
|
//
|
|
1611
1474
|
async resumeEditingFromDraft() {
|
|
1612
|
-
this
|
|
1475
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1613
1476
|
|
|
1614
1477
|
const localStorageData = this.loadStoredComponentsFromStorage()
|
|
1615
1478
|
|
|
@@ -1629,7 +1492,7 @@ export class PageBuilderService {
|
|
|
1629
1492
|
}
|
|
1630
1493
|
|
|
1631
1494
|
async restoreOriginalContent() {
|
|
1632
|
-
this
|
|
1495
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1633
1496
|
|
|
1634
1497
|
this.pageBuilderStateStore.setIsRestoring(true)
|
|
1635
1498
|
await delay(400)
|
|
@@ -1653,7 +1516,7 @@ export class PageBuilderService {
|
|
|
1653
1516
|
}
|
|
1654
1517
|
|
|
1655
1518
|
loadStoredComponentsFromStorage() {
|
|
1656
|
-
this
|
|
1519
|
+
this.localStorageManager.updateLocalStorageItemName()
|
|
1657
1520
|
if (!this.getLocalStorageItemName.value) return false
|
|
1658
1521
|
|
|
1659
1522
|
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: {
|
|
@@ -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