@myissue/vue-website-page-builder 3.3.12 → 3.3.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.
@@ -39,9 +39,9 @@ export class PageBuilderService {
39
39
  private delay: (ms?: number) => Promise<void>
40
40
  private hasStartedEditing: boolean = false
41
41
  // Hold data from Database or Backend for updated post
42
- private originalComponents: string | null = null
42
+ private originalComponents: BuilderResourceData | undefined = undefined
43
43
  // Holds data to be mounted when #pagebuilder is not yet present in the DOM
44
- private pendingMountData: string | null = null
44
+ private pendingMountData: BuilderResourceData | null = null
45
45
 
46
46
  constructor(pageBuilderStateStore: ReturnType<typeof usePageBuilderStateStore>) {
47
47
  this.hasStartedEditing = false
@@ -175,36 +175,80 @@ export class PageBuilderService {
175
175
  }
176
176
  }
177
177
 
178
- #validateUserProvidedComponents(components: BuilderResourceData) {
179
- // Must be an array
180
- if (!Array.isArray(components)) {
178
+ #validateUserProvidedComponents(components: unknown) {
179
+ const formType =
180
+ this.pageBuilderStateStore.getPageBuilderConfig &&
181
+ this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
182
+ this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType
183
+
184
+ if (Array.isArray(components) && components.length === 0) {
185
+ return { error: false as const, message: 'No components provided (empty array).' }
186
+ }
187
+
188
+ if (
189
+ Array.isArray(components) &&
190
+ components.length >= 1 &&
191
+ formType === 'create' &&
192
+ components
193
+ ) {
194
+ return {
195
+ error: true as const,
196
+ warning:
197
+ 'You cannot set formType to create in your configuration while also passing a components data array to the Page Builder. Please set formType to update.',
198
+ status: 'validation_failed',
199
+ }
200
+ }
201
+ if (formType === 'create' && components) {
181
202
  return {
182
- error: true,
183
- reason: "'components' must be an array.",
203
+ error: true as const,
204
+ warning:
205
+ 'You cannot set formType to create in your configuration while also passing a components data array to the Page Builder. Please set formType to update.',
206
+ status: 'validation_failed',
184
207
  }
185
208
  }
186
209
 
187
- // If empty array, that's acceptable
188
- if (components.length === 0) {
189
- return { error: false }
210
+ // Must be an array
211
+ if (!Array.isArray(components)) {
212
+ return {
213
+ error: true as const,
214
+ reason: 'Components data must be an array.',
215
+ }
190
216
  }
191
217
 
192
218
  // Check that the first item looks like a component
193
219
  const first = components[0]
194
220
 
195
- const isObject = typeof first === 'object' && first !== null
196
- const hasHtmlCodeKey = 'html_code' in first
221
+ // Check that the first item is not an empty object
222
+ if (isEmptyObject(first)) {
223
+ console.error(
224
+ 'The first object in the array is empty. Each component must be a non-empty object and include an html_code key.',
225
+ )
226
+ return {
227
+ error: true as const,
228
+ reason:
229
+ "The first object in the array is empty. Each component must be a non-empty object and include an 'html_code' key.",
230
+ }
231
+ }
197
232
 
198
- if (!isObject || !hasHtmlCodeKey) {
233
+ if (first && 'html_code' in first && typeof first.html_code !== 'string') {
234
+ console.error("The 'html_code' property in the first object must be a string.")
199
235
  return {
200
- error: true,
201
- reason: "Each component must be an object and include an 'html_code' key.",
236
+ error: true as const,
237
+ reason: "The 'html_code' property in the first object must be a string.",
202
238
  }
203
239
  }
204
240
 
205
- return {
206
- message: 'Everything looks good. Components structure is valid.',
241
+ // Check that the first item has an 'html_code' key
242
+ if (!first || !('html_code' in first)) {
243
+ console.error("The first object in the array must include an 'html_code' key.")
244
+ return {
245
+ error: true as const,
246
+ reason: "The first object in the array must include an 'html_code' key.",
247
+ }
207
248
  }
249
+
250
+ // No errors found
251
+ return { error: false as const }
208
252
  }
209
253
 
210
254
  #validateConfig(config: PageBuilderConfig): void {
@@ -225,6 +269,96 @@ export class PageBuilderService {
225
269
  }
226
270
  }
227
271
 
272
+ #handlePageBuilderNotPresent(passedDataComponents: BuilderResourceData) {
273
+ this.pendingMountData = passedDataComponents
274
+ }
275
+
276
+ async #mountPassedComponentsToDOM(components?: BuilderResourceData): Promise<void> {
277
+ const config = this.pageBuilderStateStore.getPageBuilderConfig
278
+ const formType = config && config.updateOrCreate && config.updateOrCreate.formType
279
+ const localStorageData = this.loadStoredComponentsFromStorage()
280
+
281
+ let dataToPass: string
282
+ if (typeof components === 'string') {
283
+ dataToPass = components
284
+ } else if (components !== undefined) {
285
+ dataToPass = JSON.stringify(components)
286
+ } else {
287
+ dataToPass = ''
288
+ }
289
+
290
+ await this.#updateComponentsFromString(dataToPass)
291
+ }
292
+
293
+ async tryMountPendingComponents() {
294
+ this.pageBuilderStateStore.setIsLoadingGlobal(true)
295
+ await delay(200)
296
+ const config = this.pageBuilderStateStore.getPageBuilderConfig
297
+ const formType = config && config.updateOrCreate && config.updateOrCreate.formType
298
+ const localStorageData = this.loadStoredComponentsFromStorage()
299
+ //
300
+ if (!config) return
301
+ //
302
+ if (
303
+ config &&
304
+ formType === 'update' &&
305
+ localStorageData &&
306
+ typeof localStorageData === 'string' &&
307
+ this.pendingMountData
308
+ ) {
309
+ this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
310
+ }
311
+ //
312
+ //
313
+ //
314
+ //
315
+ if (config && formType === 'update') {
316
+ if (this.pendingMountData) {
317
+ this.#completeBuilderInitialization(this.pendingMountData)
318
+ return
319
+ }
320
+
321
+ // Pending data for mount is null at this stage
322
+ if (typeof localStorageData === 'string') {
323
+ await this.#updateComponentsFromString(localStorageData)
324
+ this.#completeBuilderInitialization()
325
+ return
326
+ }
327
+
328
+ //
329
+ //
330
+ //
331
+ //
332
+ // Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
333
+ await nextTick()
334
+ // Attach event listeners to all editable elements in the Builder
335
+ await this.#addListenersToEditableElements()
336
+
337
+ this.pageBuilderStateStore.setIsRestoring(false)
338
+ this.pageBuilderStateStore.setIsLoadingGlobal(false)
339
+ }
340
+
341
+ if (config && formType === 'create') {
342
+ // Pending data for mount is null at this stage
343
+ if (typeof localStorageData === 'string') {
344
+ await this.#updateComponentsFromString(localStorageData)
345
+ this.#completeBuilderInitialization()
346
+ return
347
+ }
348
+
349
+ //
350
+ //
351
+ //
352
+ //
353
+ // Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
354
+ await nextTick()
355
+ // Attach event listeners to all editable elements in the Builder
356
+ await this.#addListenersToEditableElements()
357
+
358
+ this.pageBuilderStateStore.setIsRestoring(false)
359
+ this.pageBuilderStateStore.setIsLoadingGlobal(false)
360
+ }
361
+ }
228
362
  /**
229
363
  * - Entry point for initializing the Page Builder.
230
364
  * - Sets the builder as started in the state store.
@@ -237,62 +371,101 @@ export class PageBuilderService {
237
371
  */
238
372
  async startBuilder(
239
373
  config: PageBuilderConfig,
240
- components?: BuilderResourceData,
374
+ passedComponentsArray?: BuilderResourceData,
241
375
  ): Promise<StartBuilderResult> {
242
- console.log('start builder ran..', components)
243
- if (components) {
244
- this.#validateUserProvidedComponents(components)
245
- }
246
-
247
- return {
248
- message: 'Page builder started successfully with valid components.',
249
- }
250
-
251
376
  // Reactive flag signals to the UI that the builder has been successfully initialized
252
377
  // Prevents builder actions to prevent errors caused by missing DOM .
253
378
  this.pageBuilderStateStore.setBuilderStarted(true)
379
+ const pagebuilder = document.querySelector('#pagebuilder')
380
+ let validation
254
381
 
255
- // Show a global loading indicator while initializing
256
- this.pageBuilderStateStore.setIsLoadingGlobal(true)
257
-
258
- // Wait briefly to ensure UI updates and async processes settle
382
+ try {
383
+ this.originalComponents = passedComponentsArray
384
+ this.pageBuilderStateStore.setPageBuilderConfig(config)
385
+ // Validate and normalize the config (ensure required fields are present)
386
+ this.#validateConfig(config)
259
387
 
260
- // Store the provided config in the builder's state store
261
- this.pageBuilderStateStore.setPageBuilderConfig(config)
388
+ validation = this.#validateUserProvidedComponents(passedComponentsArray)
262
389
 
263
- // Validate and normalize the config (ensure required fields are present)
264
- this.#validateConfig(config)
390
+ // Update the localStorage key name based on the config/resource
391
+ this.#updateLocalStorageItemName()
265
392
 
266
- // Update the localStorage key name based on the config/resource
267
- this.#updateLocalStorageItemName()
393
+ // Page Builder is not Present in the DOM but Components have been passed to the Builder
394
+ if (passedComponentsArray && !pagebuilder) {
395
+ this.#handlePageBuilderNotPresent(passedComponentsArray)
396
+ }
397
+ // Page Builder is Present in the DOM & Components have been passed to the Builder
398
+ if (pagebuilder) {
399
+ this.#completeBuilderInitialization(passedComponentsArray)
400
+ }
268
401
 
269
- const formType = config.updateOrCreate && config.updateOrCreate.formType
270
- if (formType === 'create') {
271
- await this.mountComponentsToDOM('')
402
+ // Return both the success message and validation info if present
403
+ return {
404
+ message: 'Page builder started successfully.',
405
+ ...(validation || {}),
406
+ }
407
+ } catch (err) {
408
+ console.error('Not able to start the Page Builder', err)
409
+ this.pageBuilderStateStore.setIsLoadingGlobal(false)
410
+ return {
411
+ error: true as const,
412
+ reason: 'Failed to start the Page Builder due to an unexpected error.',
413
+ }
272
414
  }
273
415
  }
274
416
 
275
- async #completeBuilderInitialization() {
276
- console.log('complete builder..')
277
- const pagebuilder = document.querySelector('#pagebuilder')
278
- if (!pagebuilder) return
417
+ async #completeBuilderInitialization(passedComponentsArray?: BuilderResourceData): Promise<void> {
418
+ this.pageBuilderStateStore.setIsLoadingGlobal(true)
419
+ const localStorageData = this.loadStoredComponentsFromStorage()
420
+
421
+ await this.delay(300)
279
422
 
280
423
  // Deselect any selected or hovered elements in the builder UI
281
424
  await this.clearHtmlSelection()
282
- this.pageBuilderStateStore.setIsLoadingGlobal(true)
283
- await this.delay(300)
284
425
 
285
- // Hide the global loading indicator and mark the builder as started
286
- this.pageBuilderStateStore.setIsLoadingGlobal(false)
426
+ if (passedComponentsArray) {
427
+ // Prefer components from local storage if available for this resource
428
+ if (!this.pendingMountData && localStorageData && typeof localStorageData === 'string') {
429
+ await this.#updateComponentsFromString(localStorageData)
430
+ } else {
431
+ // If no local storage is found, use the components array provided by the user
432
+ await this.#mountPassedComponentsToDOM(passedComponentsArray)
433
+ this.pendingMountData = null
434
+ }
435
+ }
287
436
 
288
- if (await this.hasLocalDraftForUpdate()) {
289
- this.pageBuilderStateStore.setHasLocalDraftForUpdate(true)
437
+ //
438
+ //
439
+ //
440
+ if (!passedComponentsArray) {
441
+ // Prefer components from local storage if available for this resource
442
+ if (localStorageData && typeof localStorageData === 'string') {
443
+ await this.#updateComponentsFromString(localStorageData)
444
+ } else {
445
+ // If no local storage is found, use the components array provided by the user
446
+ await this.#mountPassedComponentsToDOM([])
447
+ }
290
448
  }
449
+ //
450
+ //
451
+ //
452
+ //
453
+ //
454
+ //
455
+ //
456
+ //
457
+ //
458
+ //
459
+ //
460
+ //
461
+ //
291
462
 
292
463
  // Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
293
464
  await nextTick()
294
465
  // Attach event listeners to all editable elements in the Builder
295
466
  await this.#addListenersToEditableElements()
467
+ // Show a global loading indicator while initializing
468
+ this.pageBuilderStateStore.setIsLoadingGlobal(false)
296
469
 
297
470
  // Clean up any old localStorage items related to previous builder sessions
298
471
  this.deleteOldPageBuilderLocalStorage()
@@ -480,7 +653,7 @@ export class PageBuilderService {
480
653
  // Deselect any selected or hovered elements in the builder UI
481
654
  //
482
655
  this.#saveDomComponentsToLocalStorage()
483
- await this.delay(500)
656
+ await this.delay(300)
484
657
  } catch (err) {
485
658
  console.error('Error trying auto save.', err)
486
659
  } finally {
@@ -1113,21 +1286,25 @@ export class PageBuilderService {
1113
1286
  }
1114
1287
 
1115
1288
  #updateLocalStorageItemName(): void {
1116
- const updateOrCreate =
1289
+ const formtype =
1117
1290
  this.pageBuilderStateStore.getPageBuilderConfig &&
1118
1291
  this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
1119
1292
  this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType
1120
1293
 
1121
- const resourceData = this.pageBuilderStateStore.getPageBuilderConfig?.resourceData
1294
+ const formname =
1295
+ this.pageBuilderStateStore.getPageBuilderConfig &&
1296
+ this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
1297
+ this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formName
1122
1298
 
1123
- const resourceFormName =
1124
- this.pageBuilderStateStore.getPageBuilderConfig?.updateOrCreate?.formName
1299
+ const resourceData =
1300
+ this.pageBuilderStateStore.getPageBuilderConfig &&
1301
+ this.pageBuilderStateStore.getPageBuilderConfig.resourceData
1125
1302
 
1126
1303
  // Logic for create resource
1127
- if (updateOrCreate === 'create') {
1128
- if (resourceFormName && resourceFormName.length > 0) {
1304
+ if (formtype === 'create') {
1305
+ if (formname && formname.length > 0) {
1129
1306
  this.pageBuilderStateStore.setLocalStorageItemName(
1130
- `page-builder-create-resource-${this.sanitizeForLocalStorage(resourceFormName)}`,
1307
+ `page-builder-create-resource-${this.sanitizeForLocalStorage(formname)}`,
1131
1308
  )
1132
1309
  return
1133
1310
  }
@@ -1138,15 +1315,15 @@ export class PageBuilderService {
1138
1315
 
1139
1316
  // Logic for create
1140
1317
  // Logic for update and with resource form name
1141
- if (updateOrCreate === 'update') {
1142
- if (typeof resourceFormName === 'string' && resourceFormName.length > 0) {
1318
+ if (formtype === 'update') {
1319
+ if (typeof formname === 'string' && formname.length > 0) {
1143
1320
  //
1144
1321
  //
1145
1322
  if (resourceData && resourceData != null && !resourceData.title) {
1146
1323
  // Check if id is missing, null, undefined, or an empty string (after trimming)
1147
1324
  if (!resourceData.id || typeof resourceData.id === 'string') {
1148
1325
  this.pageBuilderStateStore.setLocalStorageItemName(
1149
- `page-builder-update-resource-${this.sanitizeForLocalStorage(resourceFormName)}`,
1326
+ `page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}`,
1150
1327
  )
1151
1328
  return
1152
1329
  }
@@ -1161,7 +1338,7 @@ export class PageBuilderService {
1161
1338
  ) {
1162
1339
  if (!resourceData.id || typeof resourceData.id === 'string') {
1163
1340
  this.pageBuilderStateStore.setLocalStorageItemName(
1164
- `page-builder-update-resource-${this.sanitizeForLocalStorage(resourceFormName)}-${this.sanitizeForLocalStorage(resourceData.title)}`,
1341
+ `page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(resourceData.title)}`,
1165
1342
  )
1166
1343
  return
1167
1344
  }
@@ -1173,7 +1350,7 @@ export class PageBuilderService {
1173
1350
  if (!resourceData.title && typeof resourceData.title !== 'string') {
1174
1351
  if (resourceData.id || typeof resourceData.id === 'number') {
1175
1352
  this.pageBuilderStateStore.setLocalStorageItemName(
1176
- `page-builder-update-resource-${this.sanitizeForLocalStorage(resourceFormName)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
1353
+ `page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
1177
1354
  )
1178
1355
  return
1179
1356
  }
@@ -1189,7 +1366,7 @@ export class PageBuilderService {
1189
1366
  ) {
1190
1367
  if (resourceData.id || typeof resourceData.id === 'number') {
1191
1368
  this.pageBuilderStateStore.setLocalStorageItemName(
1192
- `page-builder-update-resource-${this.sanitizeForLocalStorage(resourceFormName)}-${this.sanitizeForLocalStorage(resourceData.title)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
1369
+ `page-builder-update-resource-${this.sanitizeForLocalStorage(formname)}-${this.sanitizeForLocalStorage(resourceData.title)}-${this.sanitizeForLocalStorage(String(resourceData.id))}`,
1193
1370
  )
1194
1371
  return
1195
1372
  }
@@ -1197,11 +1374,8 @@ export class PageBuilderService {
1197
1374
  }
1198
1375
  }
1199
1376
 
1200
- // Logic for update without without resourceFormName
1201
- if (
1202
- !resourceFormName ||
1203
- (typeof resourceFormName === 'string' && resourceFormName.length === 0)
1204
- ) {
1377
+ // Logic for update without without formname
1378
+ if (!formname || (typeof formname === 'string' && formname.length === 0)) {
1205
1379
  //
1206
1380
  //
1207
1381
  if (resourceData && resourceData != null && !resourceData.title) {
@@ -1348,12 +1522,10 @@ export class PageBuilderService {
1348
1522
 
1349
1523
  //
1350
1524
  deleteOldPageBuilderLocalStorage(): void {
1351
- if (
1352
- this.pageBuilderStateStore.getPageBuilderConfig &&
1353
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
1354
- typeof this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'string' &&
1355
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'update'
1356
- ) {
1525
+ const config = this.pageBuilderStateStore.getPageBuilderConfig
1526
+ const formType = config && config.updateOrCreate && config.updateOrCreate.formType
1527
+
1528
+ if (formType === 'update') {
1357
1529
  let oldCountLocalStorages = 0
1358
1530
  const deletedItemsLog: { Number: number; Key: string; SavedAt: string }[] = []
1359
1531
 
@@ -1401,38 +1573,6 @@ export class PageBuilderService {
1401
1573
  }
1402
1574
  }
1403
1575
 
1404
- async hasLocalDraftForUpdate(): Promise<boolean> {
1405
- const pagebuilder = document.querySelector('#pagebuilder')
1406
- if (!pagebuilder) {
1407
- return true
1408
- }
1409
-
1410
- if (this.hasStartedEditing) return false
1411
-
1412
- if (
1413
- this.pageBuilderStateStore.getPageBuilderConfig &&
1414
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
1415
- typeof this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'string' &&
1416
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'update'
1417
- ) {
1418
- const key = this.getLocalStorageItemName.value
1419
- if (typeof key === 'string') {
1420
- const draft = localStorage.getItem(key)
1421
- if (draft) {
1422
- try {
1423
- await this.delay(500)
1424
- this.pageBuilderStateStore.setHasLocalDraftForUpdate(false)
1425
- return true
1426
- } catch (err) {
1427
- console.error('Unable to mount components to DOM.', err)
1428
- return false
1429
- }
1430
- }
1431
- }
1432
- }
1433
- return false
1434
- }
1435
-
1436
1576
  // Call this when the user starts editing (e.g., on first change or when resuming a draft)
1437
1577
  startEditing() {
1438
1578
  this.hasStartedEditing = true
@@ -1440,40 +1580,48 @@ export class PageBuilderService {
1440
1580
 
1441
1581
  //
1442
1582
  async resumeEditingForUpdate() {
1443
- if (
1444
- this.pageBuilderStateStore.getPageBuilderConfig &&
1445
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
1446
- typeof this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'string' &&
1447
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'update'
1448
- ) {
1449
- const key = this.getLocalStorageItemName.value
1583
+ const config = this.pageBuilderStateStore.getPageBuilderConfig
1584
+ const formType = config && config.updateOrCreate && config.updateOrCreate.formType
1585
+
1586
+ if (formType !== 'update') return
1587
+ //
1588
+ //
1589
+ //
1450
1590
 
1451
- if (typeof key === 'string') {
1452
- const updateDraftFromLocalStorage = localStorage.getItem(key)
1591
+ const key = this.getLocalStorageItemName.value
1453
1592
 
1454
- if (typeof updateDraftFromLocalStorage === 'string') {
1455
- this.pageBuilderStateStore.setIsLoadingResumeEditing(true)
1456
- await delay(500)
1457
- this.mountComponentsToDOM(updateDraftFromLocalStorage)
1458
- this.pageBuilderStateStore.setIsLoadingResumeEditing(false)
1459
- }
1593
+ if (typeof key === 'string') {
1594
+ const updateDraftFromLocalStorage = localStorage.getItem(key)
1595
+
1596
+ if (typeof updateDraftFromLocalStorage === 'string') {
1597
+ this.pageBuilderStateStore.setIsLoadingResumeEditing(true)
1598
+ localStorage.removeItem(key)
1599
+ await delay(300)
1600
+ await this.#updateComponentsFromString(updateDraftFromLocalStorage)
1601
+ this.pageBuilderStateStore.setIsLoadingResumeEditing(false)
1460
1602
  }
1461
1603
  }
1604
+
1605
+ // Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
1606
+ await nextTick()
1607
+ // Attach event listeners to all editable elements in the Builder
1608
+ await this.#addListenersToEditableElements()
1609
+ // set loading to false
1610
+ this.pageBuilderStateStore.setIsLoadingResumeEditing(false)
1462
1611
  }
1463
1612
 
1464
1613
  async restoreOriginalContent() {
1465
- if (
1466
- this.pageBuilderStateStore.getPageBuilderConfig &&
1467
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
1468
- typeof this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'string' &&
1469
- this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType === 'update'
1470
- ) {
1614
+ const config = this.pageBuilderStateStore.getPageBuilderConfig
1615
+ const formType = config && config.updateOrCreate && config.updateOrCreate.formType
1616
+
1617
+ if (formType === 'update') {
1471
1618
  this.pageBuilderStateStore.setIsRestoring(true)
1472
1619
  await this.delay(300)
1473
1620
 
1474
1621
  // Restore the original content if available
1475
- if (this.originalComponents) {
1476
- this.mountComponentsToDOM(this.originalComponents)
1622
+ if (Array.isArray(this.originalComponents)) {
1623
+ await this.#mountPassedComponentsToDOM(this.originalComponents)
1624
+ this.removeCurrentComponentsFromLocalStorage()
1477
1625
  }
1478
1626
 
1479
1627
  // Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
@@ -1784,19 +1932,22 @@ export class PageBuilderService {
1784
1932
  * @param data - JSON string (e.g., '[{"html_code":"...","id":"123","title":"..."}]')
1785
1933
  * OR HTML string (e.g., '<section data-componentid="123">...</section>')
1786
1934
  */
1787
- async #setComponentsFromData(htmlString: string): Promise<void> {
1935
+ async #updateComponentsFromString(htmlString: string): Promise<void> {
1788
1936
  // Auto-detect if input is JSON or HTML
1789
1937
  const trimmedData = htmlString.trim()
1790
1938
 
1791
1939
  if (trimmedData.startsWith('[') || trimmedData.startsWith('{')) {
1792
1940
  // Looks like JSON - parse as JSON
1793
1941
  await this.#parseJSONComponents(trimmedData)
1794
- } else if (trimmedData.startsWith('<')) {
1942
+ return
1943
+ }
1944
+ if (trimmedData.startsWith('<')) {
1795
1945
  // Looks like HTML - parse as HTML
1796
1946
  await this.#parseHTMLComponents(trimmedData)
1797
- } else {
1798
- await this.#parseJSONComponents(trimmedData)
1947
+ return
1799
1948
  }
1949
+
1950
+ await this.#parseJSONComponents(trimmedData)
1800
1951
  }
1801
1952
 
1802
1953
  // Private method to parse JSON components and save pageBuilderContentSavedAt to localStorage
@@ -1917,145 +2068,6 @@ export class PageBuilderService {
1917
2068
  }
1918
2069
  }
1919
2070
 
1920
- async mountComponentsToDOM(passedData: string): Promise<void> {
1921
- const config = this.pageBuilderStateStore.getPageBuilderConfig
1922
- const formType = config && config.updateOrCreate && config.updateOrCreate.formType
1923
-
1924
- if (formType) {
1925
- const pagebuilder = document.querySelector('#pagebuilder')
1926
- const localStorageData = this.loadStoredComponentsFromStorage()
1927
-
1928
- if (!pagebuilder) {
1929
- await this.#handlePageBuilderNotPresent(passedData, formType)
1930
- return
1931
- }
1932
-
1933
- this.#handleOriginalComponentsForUpdate(passedData, formType)
1934
-
1935
- if (this.#isCreateFormType(formType)) {
1936
- await this.#handleCreateFormType(passedData, localStorageData)
1937
- return
1938
- }
1939
-
1940
- if (this.#isUpdateFormType(formType)) {
1941
- await this.#handleUpdateFormType(passedData, localStorageData)
1942
- return
1943
- }
1944
- }
1945
- }
1946
-
1947
- // --- Private helpers ---
1948
-
1949
- async #handlePageBuilderNotPresent(passedData: string, formType: string) {
1950
- if (formType === 'create') {
1951
- console.log('mountComponentsToDOM ran: m0')
1952
- this.pendingMountData = ''
1953
- return
1954
- }
1955
- console.log('mountComponentsToDOM ran: m1:')
1956
- this.pendingMountData = passedData
1957
- }
1958
-
1959
- #handleOriginalComponentsForUpdate(passedData: string, formType: string) {
1960
- if (formType === 'update' && passedData && !this.originalComponents) {
1961
- console.log('mountComponentsToDOM ran: m3')
1962
- this.originalComponents = passedData
1963
- }
1964
- }
1965
-
1966
- async #handleUpdateFormType(passedData: string, localStorageData: string | false) {
1967
- if (passedData) {
1968
- console.log('mountComponentsToDOM ran: m4')
1969
- await this.#setComponentsFromData(passedData)
1970
- return
1971
- }
1972
- if (localStorageData) {
1973
- console.log('mountComponentsToDOM ran: m5')
1974
- await this.#setComponentsFromData(localStorageData)
1975
- return
1976
- }
1977
- // If nothing, clear components
1978
- console.log('mountComponentsToDOM ran: m6')
1979
- this.deleteAllComponentsFromDOM()
1980
- }
1981
-
1982
- async #handleCreateFormType(passedData: string, localStorageData: string | false) {
1983
- if (localStorageData) {
1984
- console.log('mountComponentsToDOM ran: m7')
1985
- await this.#setComponentsFromData(localStorageData)
1986
- return
1987
- }
1988
- if (passedData) {
1989
- console.log('mountComponentsToDOM ran: m8')
1990
- await this.#setComponentsFromData(passedData)
1991
- return
1992
- }
1993
- }
1994
-
1995
- #isCreateFormType(formType: string): boolean {
1996
- return formType === 'create'
1997
- }
1998
-
1999
- #isUpdateFormType(formType: string): boolean {
2000
- return formType === 'update'
2001
- }
2002
-
2003
- async ensureBuilderInitializedForCreate() {
2004
- const pagebuilder = document.querySelector('#pagebuilder')
2005
- if (!pagebuilder) return
2006
-
2007
- const config = this.pageBuilderStateStore.getPageBuilderConfig
2008
- console.log('den er:', config)
2009
- const formType = config && config.updateOrCreate && config.updateOrCreate.formType
2010
-
2011
- if (formType === 'create') {
2012
- this.#completeBuilderInitialization()
2013
- await nextTick()
2014
-
2015
- if (
2016
- formType === 'create' &&
2017
- (!this.getComponents.value ||
2018
- (Array.isArray(this.getComponents.value) && this.getComponents.value.length === 0))
2019
- ) {
2020
- console.log('ensureBuilderInitializedForCreate e1')
2021
- await this.mountComponentsToDOM('')
2022
- this.pendingMountData = null
2023
- return
2024
- }
2025
-
2026
- console.log('ensureBuilderInitializedForCreate e2:')
2027
- await this.mountComponentsToDOM('')
2028
- await nextTick()
2029
- // Attach event listeners to all editable elements in the Builder
2030
- await this.#addListenersToEditableElements()
2031
- }
2032
- }
2033
-
2034
- async ensureBuilderInitializedForUpdate() {
2035
- const pagebuilder = document.querySelector('#pagebuilder')
2036
- if (!pagebuilder) return
2037
-
2038
- const config = this.pageBuilderStateStore.getPageBuilderConfig
2039
- const formType = config && config.updateOrCreate && config.updateOrCreate.formType
2040
-
2041
- if (formType === 'update') {
2042
- this.#completeBuilderInitialization()
2043
-
2044
- // Only for update/draft/demo: mount if pendingMountData is a non-empty string
2045
- if (this.pendingMountData && typeof this.pendingMountData === 'string') {
2046
- console.log('ensureBuilderInitializedForUpdate t1:')
2047
- await this.mountComponentsToDOM(this.pendingMountData)
2048
- this.pendingMountData = null
2049
- return
2050
- }
2051
-
2052
- console.log('ensureBuilderInitializedForUpdate t2:')
2053
- await nextTick()
2054
- // Always try to load latest from localStorage or fallback
2055
- await this.mountComponentsToDOM('')
2056
- }
2057
- }
2058
-
2059
2071
  async toggleTipTapModal(status: boolean): Promise<void> {
2060
2072
  this.pageBuilderStateStore.setShowModalTipTap(status)
2061
2073