@myissue/vue-website-page-builder 3.3.13 → 3.3.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myissue/vue-website-page-builder",
3
- "version": "v3.3.13",
3
+ "version": "v3.3.15",
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",
@@ -164,8 +164,8 @@ const openHTMLSettings = function () {
164
164
  <!-- Main Settings Start -->
165
165
  <button
166
166
  @click="
167
- () => {
168
- pageBuilderService.clearHtmlSelection()
167
+ async () => {
168
+ await pageBuilderService.clearHtmlSelection()
169
169
  openMainSettings()
170
170
  }
171
171
  "
@@ -83,7 +83,7 @@ const configPageBuilder = {
83
83
 
84
84
  onMounted(async () => {
85
85
  const result = await pageBuilderService.startBuilder(configPageBuilder, html)
86
- //
86
+ console.log('Page Builder Result:', result)
87
87
  //
88
88
  //
89
89
  //
@@ -149,7 +149,6 @@ watch(getElementAttributes, async (newAttributes, oldAttributes) => {
149
149
  newAttributes?.dataImage !== oldAttributes?.dataImage
150
150
  ) {
151
151
  debounce(async () => {
152
- await pageBuilderService.handleAutoSave()
153
152
  await pageBuilderService.initializeElementStyles()
154
153
  }, 200)
155
154
  }
@@ -237,7 +236,7 @@ const handleRestoreOriginalContent = async function () {
237
236
 
238
237
  titleModalRestore.value = 'Do you want to reset this page?'
239
238
  descriptionModalRestore.value =
240
- 'Are you sure you want to reset this page? This will overwrite your current page work.'
239
+ 'Are you sure you want to reset this page? This will overwrite your current changes.'
241
240
  firstButtonRestore.value = 'Close'
242
241
  secondButtonRestore.value = null
243
242
  thirdButtonRestore.value = 'Reset changes'
@@ -279,7 +278,7 @@ onMounted(async () => {
279
278
 
280
279
  <template>
281
280
  <div
282
- class="pbx-font-sans pbx-max-w-full pbx-m-1 pbx-border pbx-border-gray-400 pbx-inset-x-0 pbx-z-10 pbx-bg-white pbx-overflow-x-scroll"
281
+ class="pbx-font-sans pbx-max-w-full pbx-m-1 pbx-border pbx-border-gray-400 pbx-inset-x-0 pbx-z-10 pbx-bg-white pbx-overflow-x-auto"
283
282
  >
284
283
  <div id="pagebuilder-top-area" class="lg:pbx-px-4 pbx-pt-2 pbx-pb-4 pbx-mx-4 pbx-mb-4 pbx-mt-2">
285
284
  <GlobalLoader v-if="getIsLoadingGlobal & !openAppNotStartedModal"></GlobalLoader>
@@ -296,11 +295,21 @@ onMounted(async () => {
296
295
  the builder by running the startBuilder method for this resource.
297
296
  </ModalBuilder>
298
297
  <div
299
- @click.self="pageBuilderService.clearHtmlSelection()"
298
+ @click.self="
299
+ async () => {
300
+ await pageBuilderService.clearHtmlSelection()
301
+ }
302
+ "
300
303
  class="pbx-min-h-24 pbx-flex pbx-justify-between pbx-items-center pbx-pb-2 pbx-border-b pbx-border-gray-200"
301
304
  >
302
305
  <!-- Logo # start -->
303
- <div @click="pageBuilderService.clearHtmlSelection()">
306
+ <div
307
+ @click="
308
+ async () => {
309
+ await pageBuilderService.clearHtmlSelection()
310
+ }
311
+ "
312
+ >
304
313
  <div
305
314
  v-if="
306
315
  getPageBuilderConfig &&
@@ -386,7 +395,11 @@ onMounted(async () => {
386
395
  <div>
387
396
  <div class="pbx-relative pbx-h-full pbx-flex pbx-pb-2 pbx-gap-2">
388
397
  <div
389
- @click.self="pageBuilderService.clearHtmlSelection()"
398
+ @click.self="
399
+ async () => {
400
+ await pageBuilderService.clearHtmlSelection()
401
+ }
402
+ "
390
403
  id="pagebuilder-left-area"
391
404
  class="pbx-min-w-[3.5rem] pbx-pt-7 pbx-pb-2 pbx-ml-2 pbx-bg-myPrimaryLightGrayColor pbx-rounded-full pbx-shadow-sm"
392
405
  >
@@ -405,7 +418,13 @@ onMounted(async () => {
405
418
  <span class="pbx-myMediumIcon material-symbols-outlined"> interests </span>
406
419
  </button>
407
420
  </div>
408
- <div @click.self="pageBuilderService.clearHtmlSelection()">
421
+ <div
422
+ @click.self="
423
+ async () => {
424
+ await pageBuilderService.clearHtmlSelection()
425
+ }
426
+ "
427
+ >
409
428
  <ComponentTopMenu v-if="getElement"></ComponentTopMenu>
410
429
  </div>
411
430
  </div>
@@ -419,7 +438,11 @@ onMounted(async () => {
419
438
  class="pbx-flex pbx-items-center pbx-justify-between pbx-rounded-t-2xl pbx-min-w-[30rem] pbx-bg-myPrimaryLightGrayColor pbx-border-b pbx-border-gray-200"
420
439
  >
421
440
  <div
422
- @click.self="pageBuilderService.clearHtmlSelection()"
441
+ @click.self="
442
+ async () => {
443
+ await pageBuilderService.clearHtmlSelection()
444
+ }
445
+ "
423
446
  class="pbx-min-w-max pbx-pr-2 pbx-flex pbx-myPrimaryGap pbx-items-center pbx-pt-2 pbx-pb-2 pbx-pl-2 pbx-h-24 pbx-w-full"
424
447
  >
425
448
  <!-- Save Start -->
@@ -504,11 +527,19 @@ onMounted(async () => {
504
527
  </div>
505
528
 
506
529
  <div
507
- @click.self="pageBuilderService.clearHtmlSelection()"
530
+ @click.self="
531
+ async () => {
532
+ await pageBuilderService.clearHtmlSelection()
533
+ }
534
+ "
508
535
  class="pbx-flex pbx-justify-end pbx-py-2 pbx-pr-2 pbx-h-24 pbx-w-full"
509
536
  >
510
537
  <div
511
- @click.self="pageBuilderService.clearHtmlSelection()"
538
+ @click.self="
539
+ async () => {
540
+ await pageBuilderService.clearHtmlSelection()
541
+ }
542
+ "
512
543
  class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-4"
513
544
  >
514
545
  <button
@@ -535,10 +566,10 @@ onMounted(async () => {
535
566
  <button
536
567
  type="button"
537
568
  @click="
538
- () => {
569
+ async () => {
539
570
  pageBuilderStateStore.setMenuRight(false)
540
571
  pageBuilderStateStore.setElement(null)
541
- pageBuilderService.clearHtmlSelection()
572
+ await pageBuilderService.clearHtmlSelection()
542
573
  handlePageBuilderPreview()
543
574
  }
544
575
  "
@@ -558,11 +589,19 @@ onMounted(async () => {
558
589
  </div>
559
590
 
560
591
  <div
561
- @click.self="pageBuilderService.clearHtmlSelection()"
592
+ @click.self="
593
+ async () => {
594
+ await pageBuilderService.clearHtmlSelection()
595
+ }
596
+ "
562
597
  class="pbx-flex pbx-justify-end pbx-py-2 pbx-pr-2 pbx-w-full pbx-h-24"
563
598
  >
564
599
  <div
565
- @click.self="pageBuilderService.clearHtmlSelection()"
600
+ @click.self="
601
+ async () => {
602
+ await pageBuilderService.clearHtmlSelection()
603
+ }
604
+ "
566
605
  class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-4"
567
606
  >
568
607
  <button
@@ -604,43 +643,12 @@ onMounted(async () => {
604
643
  </div>
605
644
  </div>
606
645
  <!-- Added Components to DOM # end -->
607
-
608
- <!-- Add Component # start -->
609
-
610
- <div
611
- @click="pageBuilderService.clearHtmlSelection()"
612
- id="pagebuilder-bottom-components-area"
613
- class="pbx-pt-8 pbx-pb-12 pbx-text-center focus:pbx-outline-none focus:pbx-ring-2 focus:pbx-ring-indigo-500 focus:pbx-ring-offset-2 pbx-my-2 pbx-mx-4"
614
- :class="{ 'pbx-border-t pbx-border-gray-200': getComponents.length > 0 }"
615
- >
616
- <div class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-2 pbx-font-medium">
617
- <span class="lg:pbx-block pbx-hidden">
618
- <div>Add new components to the bottom of the page</div>
619
- </span>
620
- </div>
621
-
622
- <div class="pbx-mt-6 pbx-flex pbx-items-center pbx-gap-2 pbx-justify-center">
623
- <button
624
- @click="
625
- () => {
626
- pageBuilderStateStore.setComponentArrayAddMethod('unshift')
627
- handleAddComponent()
628
- }
629
- "
630
- type="button"
631
- class="pbx-myPrimaryButton pbx-flex pbx-items-center pbx-gap-2 pbx-justify-center"
632
- >
633
- <span class="pbx-myMediumIcon material-symbols-outlined"> interests </span>
634
- <span class="pbx-font-medium"> Add new Components </span>
635
- </button>
636
- </div>
637
- </div>
638
- <!-- Add Component # end -->
639
646
  </div>
640
647
  </div>
641
- <!-- Add Component # end -->
642
648
  </main>
643
649
 
650
+ <!-- Add Component # end -->
651
+
644
652
  <aside
645
653
  aria-label="Menu"
646
654
  id="pagebuilder-right-area"
@@ -654,6 +662,31 @@ onMounted(async () => {
654
662
  </RightSidebarEditor>
655
663
  </aside>
656
664
  </div>
665
+ <div
666
+ class="pbx-flex pbx-items-center pbx-justify-center pbx-border-t pbx-border-gray-200 pbx-cursor-pointer pbx-py-4"
667
+ >
668
+ <div
669
+ @click="
670
+ () => {
671
+ pageBuilderStateStore.setComponentArrayAddMethod('push')
672
+ handleAddComponent()
673
+ }
674
+ "
675
+ class="pbx-flex pbx-items-center pbx-justify-center pbx-gap-2"
676
+ >
677
+ <span class="lg:pbx-block pbx-hidden">
678
+ <div class="pbx-whitespace-nowrap">Add to the bottom</div>
679
+ </span>
680
+ <div class="pbx-flex pbx-gap-2 pbx-items-center pbx-justify-center">
681
+ <button
682
+ type="button"
683
+ class="pbx-h-10 pbx-w-10 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-myPrimaryLinkColor hover:pbx-text-white focus-visible:pbx-ring-0"
684
+ >
685
+ <span class="pbx-myMediumIcon material-symbols-outlined"> interests </span>
686
+ </button>
687
+ </div>
688
+ </div>
689
+ </div>
657
690
  </div>
658
691
  </div>
659
692
  </template>
@@ -181,10 +181,6 @@ export class PageBuilderService {
181
181
  this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate &&
182
182
  this.pageBuilderStateStore.getPageBuilderConfig.updateOrCreate.formType
183
183
 
184
- if (Array.isArray(components) && components.length === 0) {
185
- return { error: false as const, message: 'No components provided (empty array).' }
186
- }
187
-
188
184
  if (
189
185
  Array.isArray(components) &&
190
186
  components.length >= 1 &&
@@ -198,14 +194,6 @@ export class PageBuilderService {
198
194
  status: 'validation_failed',
199
195
  }
200
196
  }
201
- if (formType === 'create' && components) {
202
- return {
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',
207
- }
208
- }
209
197
 
210
198
  // Must be an array
211
199
  if (!Array.isArray(components)) {
@@ -218,20 +206,7 @@ export class PageBuilderService {
218
206
  // Check that the first item looks like a component
219
207
  const first = components[0]
220
208
 
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
- }
232
-
233
209
  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.")
235
210
  return {
236
211
  error: true as const,
237
212
  reason: "The 'html_code' property in the first object must be a string.",
@@ -239,16 +214,17 @@ export class PageBuilderService {
239
214
  }
240
215
 
241
216
  // 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.",
217
+ if (Array.isArray(components) && components.length >= 1) {
218
+ if (!first || !('html_code' in first)) {
219
+ return {
220
+ error: true as const,
221
+ reason: "The first object in the array must include an 'html_code' key.",
222
+ }
247
223
  }
248
224
  }
249
225
 
250
226
  // No errors found
251
- return { error: false as const }
227
+ return
252
228
  }
253
229
 
254
230
  #validateConfig(config: PageBuilderConfig): void {
@@ -291,11 +267,16 @@ export class PageBuilderService {
291
267
  }
292
268
 
293
269
  async tryMountPendingComponents() {
270
+ // Always clear DOM and store before mounting new resource
271
+ this.deleteAllComponentsFromDOM()
272
+
273
+ const localStorageData = this.loadStoredComponentsFromStorage()
274
+
294
275
  this.pageBuilderStateStore.setIsLoadingGlobal(true)
295
276
  await delay(200)
296
277
  const config = this.pageBuilderStateStore.getPageBuilderConfig
297
278
  const formType = config && config.updateOrCreate && config.updateOrCreate.formType
298
- const localStorageData = this.loadStoredComponentsFromStorage()
279
+
299
280
  //
300
281
  if (!config) return
301
282
  //
@@ -399,11 +380,24 @@ export class PageBuilderService {
399
380
  this.#completeBuilderInitialization(passedComponentsArray)
400
381
  }
401
382
 
402
- // Return both the success message and validation info if present
403
- return {
383
+ // result to end user
384
+
385
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
386
+ const result: any = {
404
387
  message: 'Page builder started successfully.',
405
- ...(validation || {}),
406
388
  }
389
+
390
+ if (validation) {
391
+ result.validation = validation
392
+ }
393
+
394
+ // passedComponentsArray
395
+ if (Array.isArray(passedComponentsArray) && passedComponentsArray.length >= 0) {
396
+ result.passedComponentsArray = passedComponentsArray
397
+ }
398
+
399
+ // Return messages, validation info if present etc.
400
+ return result
407
401
  } catch (err) {
408
402
  console.error('Not able to start the Page Builder', err)
409
403
  this.pageBuilderStateStore.setIsLoadingGlobal(false)
@@ -447,18 +441,6 @@ export class PageBuilderService {
447
441
  }
448
442
  }
449
443
  //
450
- //
451
- //
452
- //
453
- //
454
- //
455
- //
456
- //
457
- //
458
- //
459
- //
460
- //
461
- //
462
444
 
463
445
  // Wait for Vue to finish DOM updates before attaching event listeners. This ensure elements exist in the DOM.
464
446
  await nextTick()
@@ -549,6 +531,8 @@ export class PageBuilderService {
549
531
  e.preventDefault()
550
532
  e.stopPropagation()
551
533
 
534
+ await this.handleAutoSave()
535
+
552
536
  const pagebuilder = document.querySelector('#pagebuilder')
553
537
 
554
538
  if (!pagebuilder) return
@@ -712,25 +696,20 @@ export class PageBuilderService {
712
696
  const pageBuilder = document.querySelector('#contains-pagebuilder')
713
697
  // scoll to top or bottom # end
714
698
  if (pageBuilder) {
715
- if (
716
- this.getComponentArrayAddMethod.value === 'unshift' ||
717
- this.getComponentArrayAddMethod.value === 'push'
718
- ) {
719
- // push to top
720
- if (this.getComponentArrayAddMethod.value === 'unshift') {
721
- pageBuilder.scrollTo({
722
- top: 0,
723
- behavior: 'smooth',
724
- })
725
- }
699
+ // push to top
700
+ if (this.getComponentArrayAddMethod.value === 'unshift') {
701
+ pageBuilder.scrollTo({
702
+ top: 0,
703
+ behavior: 'smooth',
704
+ })
705
+ }
726
706
 
727
- // push to bottom
728
- if (this.getComponentArrayAddMethod.value === 'push') {
729
- pageBuilder.scrollTo({
730
- top: 0,
731
- behavior: 'smooth',
732
- })
733
- }
707
+ // push to bottom
708
+ if (this.getComponentArrayAddMethod.value === 'push') {
709
+ pageBuilder.scrollTo({
710
+ top: pageBuilder.scrollHeight + 400,
711
+ behavior: 'smooth',
712
+ })
734
713
  }
735
714
  }
736
715
 
@@ -1478,6 +1457,7 @@ export class PageBuilderService {
1478
1457
  * Saves the current DOM state (components) to localStorage.
1479
1458
  */
1480
1459
  #saveDomComponentsToLocalStorage() {
1460
+ this.#updateLocalStorageItemName()
1481
1461
  const pagebuilder = document.querySelector('#pagebuilder')
1482
1462
  if (!pagebuilder) return
1483
1463
 
@@ -1512,6 +1492,7 @@ export class PageBuilderService {
1512
1492
  }
1513
1493
 
1514
1494
  async removeCurrentComponentsFromLocalStorage() {
1495
+ this.#updateLocalStorageItemName()
1515
1496
  await nextTick()
1516
1497
 
1517
1498
  const key = this.getLocalStorageItemName.value
@@ -1580,6 +1561,7 @@ export class PageBuilderService {
1580
1561
 
1581
1562
  //
1582
1563
  async resumeEditingForUpdate() {
1564
+ this.#updateLocalStorageItemName()
1583
1565
  const config = this.pageBuilderStateStore.getPageBuilderConfig
1584
1566
  const formType = config && config.updateOrCreate && config.updateOrCreate.formType
1585
1567
 
@@ -1595,7 +1577,6 @@ export class PageBuilderService {
1595
1577
 
1596
1578
  if (typeof updateDraftFromLocalStorage === 'string') {
1597
1579
  this.pageBuilderStateStore.setIsLoadingResumeEditing(true)
1598
- localStorage.removeItem(key)
1599
1580
  await delay(300)
1600
1581
  await this.#updateComponentsFromString(updateDraftFromLocalStorage)
1601
1582
  this.pageBuilderStateStore.setIsLoadingResumeEditing(false)
@@ -1611,6 +1592,7 @@ export class PageBuilderService {
1611
1592
  }
1612
1593
 
1613
1594
  async restoreOriginalContent() {
1595
+ this.#updateLocalStorageItemName()
1614
1596
  const config = this.pageBuilderStateStore.getPageBuilderConfig
1615
1597
  const formType = config && config.updateOrCreate && config.updateOrCreate.formType
1616
1598
 
@@ -1638,6 +1620,7 @@ export class PageBuilderService {
1638
1620
  }
1639
1621
 
1640
1622
  loadStoredComponentsFromStorage() {
1623
+ this.#updateLocalStorageItemName()
1641
1624
  if (!this.getLocalStorageItemName.value) return false
1642
1625
 
1643
1626
  if (
package/src/css/app.css CHANGED
@@ -372,3 +372,16 @@ h2 {
372
372
  h3 {
373
373
  @apply pbx-text-2xl pbx-mt-4 pbx-mb-3 pbx-font-medium;
374
374
  }
375
+
376
+ /* CSS for content inside page builder # start */
377
+ #page-builder-editor .tiptap {
378
+ outline: none !important;
379
+ box-shadow: none !important;
380
+ background: #fff;
381
+ min-height: 25rem;
382
+ border: 1px solid #aaa;
383
+ border-radius: 10px;
384
+ padding: 6px;
385
+ margin-bottom: 20px;
386
+ padding-bottom: 100px;
387
+ }
@@ -12,18 +12,6 @@ These styles affect all HTML elements (like input, button, h1, etc.) in the cons
12
12
  #pagebuilder a {
13
13
  pointer-events: none;
14
14
  }
15
- /* CSS for content inside page builder # start */
16
- #page-builder-editor .tiptap {
17
- outline: none !important;
18
- box-shadow: none !important;
19
- background: #fff;
20
- min-height: 25rem;
21
- border: 1px solid #aaa;
22
- border-radius: 10px;
23
- padding: 6px;
24
- margin-bottom: 20px;
25
- padding-bottom: 100px;
26
- }
27
15
 
28
16
  #pagebuilder #youtube-video::before {
29
17
  content: 'Select Video Element';