@myissue/vue-website-page-builder 3.2.95 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -355
- package/dist/vue-website-page-builder.js +1242 -1223
- package/dist/vue-website-page-builder.umd.cjs +20 -20
- package/package.json +1 -1
- package/src/Components/PageBuilder/ToolbarOption/ToolbarOption.vue +1 -6
- package/src/DemoComponents/HomeSection.vue +2 -5
- package/src/PageBuilder/PageBuilder.vue +9 -12
- package/src/composables/PageBuilderService.ts +67 -23
- package/src/stores/page-builder-state.ts +2 -2
package/package.json
CHANGED
|
@@ -188,12 +188,7 @@ const openHTMLSettings = function () {
|
|
|
188
188
|
|
|
189
189
|
<!-- Delete Layout Start -->
|
|
190
190
|
<button
|
|
191
|
-
@click="
|
|
192
|
-
() => {
|
|
193
|
-
pageBuilderService.clearHtmlSelection()
|
|
194
|
-
deleteAllComponents()
|
|
195
|
-
}
|
|
196
|
-
"
|
|
191
|
+
@click="deleteAllComponents"
|
|
197
192
|
class="pbx-cursor-pointer lg:pbx-flex pbx-myPrimaryTag pbx-font-normal pbx-w-max pbx-border-none pbx-m-0 pbx-bg-myPrimaryErrorColor pbx-text-white"
|
|
198
193
|
type="button"
|
|
199
194
|
>
|
|
@@ -83,12 +83,9 @@ const configPageBuilder = {
|
|
|
83
83
|
|
|
84
84
|
onMounted(async () => {
|
|
85
85
|
await pageBuilderService.startBuilder(configPageBuilder)
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
// await pageBuilderService.mountComponentsToDOM(JSON.stringify(html))
|
|
86
|
+
await pageBuilderService.mountComponentsToDOM(JSON.stringify(html))
|
|
90
87
|
// await pageBuilderService.mountComponentsToDOM(JSON.stringify(oldhtmlfromdb))
|
|
91
|
-
await pageBuilderService.mountComponentsToDOM(rawHTML)
|
|
88
|
+
// await pageBuilderService.mountComponentsToDOM(rawHTML)
|
|
92
89
|
})
|
|
93
90
|
</script>
|
|
94
91
|
|
|
@@ -102,10 +102,6 @@ const handleAddComponent = async function () {
|
|
|
102
102
|
// end modal
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
const getHasLocalDraftForUpdate = computed(() => {
|
|
106
|
-
return pageBuilderStateStore.getHasLocalDraftForUpdate
|
|
107
|
-
})
|
|
108
|
-
|
|
109
105
|
const getElement = computed(() => {
|
|
110
106
|
return pageBuilderStateStore.getElement
|
|
111
107
|
})
|
|
@@ -114,6 +110,10 @@ const getComponents = computed(() => {
|
|
|
114
110
|
return pageBuilderStateStore.getComponents
|
|
115
111
|
})
|
|
116
112
|
|
|
113
|
+
const getHasLocalDraftForUpdate = computed(() => {
|
|
114
|
+
return pageBuilderStateStore.getHasLocalDraftForUpdate
|
|
115
|
+
})
|
|
116
|
+
|
|
117
117
|
watch(getHasLocalDraftForUpdate, (newVal) => {
|
|
118
118
|
if (newVal) {
|
|
119
119
|
handlerRumeEditingForUpdate()
|
|
@@ -168,11 +168,8 @@ const getIsSaving = computed(() => {
|
|
|
168
168
|
return pageBuilderStateStore.getIsSaving
|
|
169
169
|
})
|
|
170
170
|
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
handlerRumeEditingForUpdate()
|
|
174
|
-
}
|
|
175
|
-
return pageBuilderStateStore.getIsResumeEditing
|
|
171
|
+
const getIsLoadingResumeEditing = computed(() => {
|
|
172
|
+
return pageBuilderStateStore.getIsLoadingResumeEditing
|
|
176
173
|
})
|
|
177
174
|
const getIsRestoring = computed(() => {
|
|
178
175
|
return pageBuilderStateStore.getIsRestoring
|
|
@@ -269,11 +266,11 @@ onMounted(async () => {
|
|
|
269
266
|
}
|
|
270
267
|
|
|
271
268
|
// Check if Builder started
|
|
272
|
-
await delay(
|
|
269
|
+
await delay(10000)
|
|
273
270
|
ensureBuilderInitialized()
|
|
274
271
|
|
|
275
272
|
// Re-check if Builder started
|
|
276
|
-
await delay(
|
|
273
|
+
await delay(10000)
|
|
277
274
|
ensureBuilderInitialized()
|
|
278
275
|
})
|
|
279
276
|
</script>
|
|
@@ -340,7 +337,7 @@ onMounted(async () => {
|
|
|
340
337
|
|
|
341
338
|
<DynamicModalBuilder
|
|
342
339
|
:showDynamicModalBuilder="showModalResumeEditing"
|
|
343
|
-
:isLoading="
|
|
340
|
+
:isLoading="getIsLoadingResumeEditing"
|
|
344
341
|
:type="typeModal"
|
|
345
342
|
:gridColumnAmount="gridColumnModalResumeEditing"
|
|
346
343
|
:title="titleModalResumeEditing"
|
|
@@ -195,15 +195,24 @@ export class PageBuilderService {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
198
|
+
* - Entry point for initializing the Page Builder.
|
|
199
|
+
* - Sets the builder as started in the state store.
|
|
200
|
+
* - Shows a global loading indicator.
|
|
201
|
+
* - Stores and validates the provided configuration.
|
|
202
|
+
* - Updates the localStorage key name based on the config/resource.
|
|
203
|
+
* - Completes builder initialization if the DOM is ready.
|
|
204
|
+
*
|
|
205
|
+
* @param config - The configuration object for the Page Builder.
|
|
200
206
|
*/
|
|
201
207
|
async startBuilder(config: PageBuilderConfig): Promise<void> {
|
|
208
|
+
// Reactive flag signals to the UI that the builder has been successfully initialized
|
|
209
|
+
// Prevents builder actions to prevent errors caused by missing DOM .
|
|
210
|
+
this.pageBuilderStateStore.setBuilderStarted(true)
|
|
211
|
+
|
|
202
212
|
// Show a global loading indicator while initializing
|
|
203
213
|
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
204
214
|
|
|
205
215
|
// Wait briefly to ensure UI updates and async processes settle
|
|
206
|
-
await this.delay(300)
|
|
207
216
|
|
|
208
217
|
// Store the provided config in the builder's state store
|
|
209
218
|
this.pageBuilderStateStore.setPageBuilderConfig(config)
|
|
@@ -214,24 +223,32 @@ export class PageBuilderService {
|
|
|
214
223
|
// Update the localStorage key name based on the config/resource
|
|
215
224
|
this.#updateLocalStorageItemName()
|
|
216
225
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
|
|
220
|
-
}
|
|
226
|
+
this.completeBuilderInitialization()
|
|
227
|
+
}
|
|
221
228
|
|
|
222
|
-
|
|
223
|
-
|
|
229
|
+
async completeBuilderInitialization() {
|
|
230
|
+
const pagebuilder = document.querySelector('#pagebuilder')
|
|
231
|
+
if (!pagebuilder) return
|
|
224
232
|
|
|
225
233
|
// Deselect any selected or hovered elements in the builder UI
|
|
226
234
|
await this.clearHtmlSelection()
|
|
235
|
+
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
236
|
+
await this.delay(300)
|
|
237
|
+
|
|
238
|
+
// Hide the global loading indicator and mark the builder as started
|
|
239
|
+
this.pageBuilderStateStore.setIsLoadingGlobal(false)
|
|
240
|
+
|
|
241
|
+
if (await this.hasLocalDraftForUpdate()) {
|
|
242
|
+
this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
|
|
243
|
+
}
|
|
244
|
+
|
|
227
245
|
// Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
|
|
228
246
|
await nextTick()
|
|
229
247
|
// Attach event listeners to all editable elements in the Builder
|
|
230
248
|
await this.#addListenersToEditableElements()
|
|
231
249
|
|
|
232
|
-
//
|
|
233
|
-
this.
|
|
234
|
-
this.pageBuilderStateStore.setBuilderStarted(true)
|
|
250
|
+
// Clean up any old localStorage items related to previous builder sessions
|
|
251
|
+
this.deleteOldPageBuilderLocalStorage()
|
|
235
252
|
}
|
|
236
253
|
|
|
237
254
|
#applyElementClassChanges(
|
|
@@ -413,6 +430,8 @@ export class PageBuilderService {
|
|
|
413
430
|
|
|
414
431
|
try {
|
|
415
432
|
this.pageBuilderStateStore.setIsSaving(true)
|
|
433
|
+
// Deselect any selected or hovered elements in the builder UI
|
|
434
|
+
//
|
|
416
435
|
await this.saveComponentsLocalStorage()
|
|
417
436
|
await this.delay(500)
|
|
418
437
|
} catch (err) {
|
|
@@ -1161,7 +1180,26 @@ export class PageBuilderService {
|
|
|
1161
1180
|
}
|
|
1162
1181
|
|
|
1163
1182
|
/**
|
|
1164
|
-
*
|
|
1183
|
+
* Returns a clone of the given element with [hovered] and [selected] attributes
|
|
1184
|
+
* removed from itself and all descendants. Does NOT mutate the live DOM.
|
|
1185
|
+
* @param element The HTMLElement to clone and sanitize
|
|
1186
|
+
*/
|
|
1187
|
+
#cloneAndRemoveSelectionAttributes(element: HTMLElement): HTMLElement {
|
|
1188
|
+
// Deep clone the element
|
|
1189
|
+
const clone = element.cloneNode(true) as HTMLElement
|
|
1190
|
+
|
|
1191
|
+
// Remove [hovered] and [selected] from the clone and all descendants
|
|
1192
|
+
clone.querySelectorAll('[hovered]').forEach((el) => el.removeAttribute('hovered'))
|
|
1193
|
+
clone.querySelectorAll('[selected]').forEach((el) => el.removeAttribute('selected'))
|
|
1194
|
+
// Also remove from the root element itself if present
|
|
1195
|
+
clone.removeAttribute('hovered')
|
|
1196
|
+
clone.removeAttribute('selected')
|
|
1197
|
+
|
|
1198
|
+
return clone
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* Components from DOM → JS (not JS → DOM). øøø
|
|
1165
1203
|
* Saving the current DOM state into JS this.getComponents (for example, before saving to localStorage).
|
|
1166
1204
|
* This function Only copies the current DOM HTML into JS this.getComponents (component.html_code).
|
|
1167
1205
|
*/
|
|
@@ -1177,10 +1215,12 @@ export class PageBuilderService {
|
|
|
1177
1215
|
const componentsToSave: { html_code: string; id: string | null; title: string }[] = []
|
|
1178
1216
|
|
|
1179
1217
|
pagebuilder.querySelectorAll('section[data-componentid]').forEach((section) => {
|
|
1218
|
+
const sanitizedSection = this.#cloneAndRemoveSelectionAttributes(section as HTMLElement)
|
|
1219
|
+
|
|
1180
1220
|
componentsToSave.push({
|
|
1181
|
-
html_code:
|
|
1182
|
-
id:
|
|
1183
|
-
title:
|
|
1221
|
+
html_code: sanitizedSection.outerHTML,
|
|
1222
|
+
id: sanitizedSection.getAttribute('data-componentid'),
|
|
1223
|
+
title: sanitizedSection.getAttribute('data-component-title') || 'Untitled Component',
|
|
1184
1224
|
})
|
|
1185
1225
|
})
|
|
1186
1226
|
|
|
@@ -1270,7 +1310,12 @@ export class PageBuilderService {
|
|
|
1270
1310
|
}
|
|
1271
1311
|
}
|
|
1272
1312
|
|
|
1273
|
-
async
|
|
1313
|
+
async hasLocalDraftForUpdate(): Promise<boolean> {
|
|
1314
|
+
const pagebuilder = document.querySelector('#pagebuilder')
|
|
1315
|
+
if (!pagebuilder) {
|
|
1316
|
+
return true
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1274
1319
|
if (this.hasStartedEditing) return false
|
|
1275
1320
|
|
|
1276
1321
|
if (
|
|
@@ -1285,11 +1330,8 @@ export class PageBuilderService {
|
|
|
1285
1330
|
if (draft) {
|
|
1286
1331
|
try {
|
|
1287
1332
|
await this.delay(500)
|
|
1288
|
-
|
|
1333
|
+
this.pageBuilderStateStore.setHasLocalDraftForUpdate(false)
|
|
1289
1334
|
return true
|
|
1290
|
-
// const dbComponents = this.getComponents.value
|
|
1291
|
-
// const draftParsed = JSON.parse(draft)
|
|
1292
|
-
// return JSON.stringify(draftParsed.components) !== JSON.stringify(dbComponents)
|
|
1293
1335
|
} catch (err) {
|
|
1294
1336
|
console.error('Unable to mount components to DOM.', err)
|
|
1295
1337
|
return false
|
|
@@ -1319,10 +1361,10 @@ export class PageBuilderService {
|
|
|
1319
1361
|
const updateDraftFromLocalStorage = localStorage.getItem(key)
|
|
1320
1362
|
|
|
1321
1363
|
if (typeof updateDraftFromLocalStorage === 'string') {
|
|
1322
|
-
this.pageBuilderStateStore.
|
|
1364
|
+
this.pageBuilderStateStore.setIsLoadingResumeEditing(true)
|
|
1323
1365
|
await delay(500)
|
|
1324
1366
|
this.mountComponentsToDOM(updateDraftFromLocalStorage)
|
|
1325
|
-
this.pageBuilderStateStore.
|
|
1367
|
+
this.pageBuilderStateStore.setIsLoadingResumeEditing(false)
|
|
1326
1368
|
}
|
|
1327
1369
|
}
|
|
1328
1370
|
}
|
|
@@ -1355,6 +1397,7 @@ export class PageBuilderService {
|
|
|
1355
1397
|
getStorageItemNameForResource(): string | null {
|
|
1356
1398
|
return this.getLocalStorageItemName.value
|
|
1357
1399
|
}
|
|
1400
|
+
|
|
1358
1401
|
loadStoredComponentsFromStorage() {
|
|
1359
1402
|
if (!this.getLocalStorageItemName.value) return false
|
|
1360
1403
|
|
|
@@ -1858,6 +1901,7 @@ export class PageBuilderService {
|
|
|
1858
1901
|
if (this.pendingMountData && document.querySelector('#pagebuilder')) {
|
|
1859
1902
|
await this.mountComponentsToDOM(this.pendingMountData)
|
|
1860
1903
|
this.pendingMountData = null
|
|
1904
|
+
this.completeBuilderInitialization()
|
|
1861
1905
|
}
|
|
1862
1906
|
}
|
|
1863
1907
|
|
|
@@ -277,7 +277,7 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
|
|
|
277
277
|
getIsLoadingGlobal: (state: PageBuilderState): boolean => state.isLoadingGlobal,
|
|
278
278
|
getIsSaving: (state: PageBuilderState): boolean => state.isSaving,
|
|
279
279
|
getHasLocalDraftForUpdate: (state: PageBuilderState): boolean => state.hasLocalDraftForUpdate,
|
|
280
|
-
|
|
280
|
+
getIsLoadingResumeEditing: (state: PageBuilderState): boolean => state.isResumeEditing,
|
|
281
281
|
getIsRestoring: (state: PageBuilderState): boolean => state.isRestoring,
|
|
282
282
|
},
|
|
283
283
|
actions: {
|
|
@@ -475,7 +475,7 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
|
|
|
475
475
|
setHasLocalDraftForUpdate(payload: boolean): void {
|
|
476
476
|
this.hasLocalDraftForUpdate = payload
|
|
477
477
|
},
|
|
478
|
-
|
|
478
|
+
setIsLoadingResumeEditing(payload: boolean): void {
|
|
479
479
|
this.isResumeEditing = payload
|
|
480
480
|
},
|
|
481
481
|
setIsRestoring(payload: boolean): void {
|