@myissue/vue-website-page-builder 3.4.18 → 3.4.19

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": "3.4.18",
3
+ "version": "3.4.19",
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",
@@ -25,6 +25,9 @@ const elementTag = computed(() => {
25
25
  return getElement.value?.tagName
26
26
  })
27
27
 
28
+ const canMoveUp = computed(() => pageBuilderService.canMoveUp())
29
+ const canMoveDown = computed(() => pageBuilderService.canMoveDown())
30
+
28
31
  const getShowModalTipTap = computed(() => {
29
32
  const result = pageBuilderStateStore.getShowModalTipTap
30
33
 
@@ -39,36 +42,36 @@ const getComponent = computed(() => {
39
42
  })
40
43
 
41
44
  // hanlde Tip Tap modal
42
- const typeModal = ref('')
43
- const gridColumnModal = ref(Number(1))
44
- const titleModal = ref('')
45
- const descriptionModal = ref('')
46
- const firstButtonModal = ref('')
47
- const secondButtonModal = ref(null)
48
- const thirdButtonModal = ref(null)
45
+ const typeModalTipTap = ref('')
46
+ const gridColumnModalTipTap = ref(Number(1))
47
+ const titleModalTipTap = ref('')
48
+ const descriptionModalTipTap = ref('')
49
+ const firstButtonModalTipTap = ref('')
50
+ const secondButtonModalTipTap = ref(null)
51
+ const thirdButtonModalTipTap = ref(null)
49
52
  // set dynamic modal handle functions
50
- const firstModalButtonFunctionDynamicModalBuilder = ref(null)
51
- const secondModalButtonFunctionDynamicModalBuilder = ref(null)
52
- const thirdModalButtonFunctionDynamicModalBuilder = ref(null)
53
+ const firstModalButtonFunctionDynamicModalBuilderTipTap = ref(null)
54
+ const secondModalButtonFunctionDynamicModalBuilderTipTap = ref(null)
55
+ const thirdModalButtonFunctionDynamicModalBuilderTipTap = ref(null)
53
56
 
54
57
  const handleModalPreviewTiptap = function () {
55
58
  pageBuilderService.toggleTipTapModal(true)
56
59
 
57
- typeModal.value = 'success'
58
- gridColumnModal.value = 2
59
- titleModal.value = translate('Manage Content')
60
- descriptionModal.value = null
61
- firstButtonModal.value = null
62
- secondButtonModal.value = null
63
- thirdButtonModal.value = 'Save'
60
+ typeModalTipTap.value = 'success'
61
+ gridColumnModalTipTap.value = 2
62
+ titleModalTipTap.value = translate('Manage Content')
63
+ descriptionModalTipTap.value = null
64
+ firstButtonModalTipTap.value = null
65
+ secondButtonModalTipTap.value = null
66
+ thirdButtonModalTipTap.value = 'Save'
64
67
 
65
68
  // handle click
66
69
 
67
- firstModalButtonFunctionDynamicModalBuilder.value = function () {
70
+ firstModalButtonFunctionDynamicModalBuilderTipTap.value = function () {
68
71
  pageBuilderService.toggleTipTapModal(false)
69
72
  }
70
73
 
71
- thirdModalButtonFunctionDynamicModalBuilder.value = function () {
74
+ thirdModalButtonFunctionDynamicModalBuilderTipTap.value = function () {
72
75
  pageBuilderService.toggleTipTapModal(true)
73
76
  }
74
77
  }
@@ -146,20 +149,20 @@ const handleModalIframeSrc = function () {
146
149
  // open modal to true
147
150
  showModalIframeSrc.value = true
148
151
 
149
- typeModal.value = 'success'
150
- gridColumnModal.value = 2
151
- titleModal.value = 'Add video url'
152
- descriptionModal.value = null
153
- firstButtonModal.value = translate('Close')
154
- secondButtonModal.value = 'Save'
155
- thirdButtonModal.value = null
152
+ typeModalTipTap.value = 'success'
153
+ gridColumnModalTipTap.value = 2
154
+ titleModalTipTap.value = 'Add video url'
155
+ descriptionModalTipTap.value = null
156
+ firstButtonModalTipTap.value = translate('Close')
157
+ secondButtonModalTipTap.value = 'Save'
158
+ thirdButtonModalTipTap.value = null
156
159
 
157
160
  // handle click
158
- firstModalButtonFunctionDynamicModalBuilder.value = function () {
161
+ firstModalButtonFunctionDynamicModalBuilderTipTap.value = function () {
159
162
  showModalIframeSrc.value = false
160
163
  }
161
164
  // handle click
162
- secondModalButtonFunctionDynamicModalBuilder.value = function () {
165
+ secondModalButtonFunctionDynamicModalBuilderTipTap.value = function () {
163
166
  const isNotValidated = validateURL()
164
167
  if (isNotValidated) {
165
168
  return
@@ -190,22 +193,72 @@ const handleModalIframeSrc = function () {
190
193
  }
191
194
 
192
195
  const openOptionsMoreOpen = ref(false)
196
+
197
+ const handleShowHTMLEditor = async () => {
198
+ openOptionsMoreOpen.value = false
199
+ pageBuilderStateStore.setShowModalHTMLEditor(true)
200
+ }
201
+
202
+ const showModalDeleteComponent = ref(false)
203
+ // use dynamic model
204
+ const typeModal = ref('')
205
+ const gridColumnModal = ref(Number(1))
206
+ const titleModal = ref('')
207
+ const descriptionModal = ref('')
208
+ const firstButtonModal = ref('')
209
+ const secondButtonModal = ref(null)
210
+ const thirdButtonModal = ref(null)
211
+ // set dynamic modal handle functions
212
+ const firstModalButtonFunctionDynamicModalBuilder = ref(null)
213
+ const secondModalButtonFunctionDynamicModalBuilder = ref(null)
214
+ const thirdModalButtonFunctionDynamicModalBuilder = ref(null)
215
+
216
+ // remove component
217
+ const handleDelete = function () {
218
+ showModalDeleteComponent.value = true
219
+ typeModal.value = 'delete'
220
+ gridColumnModal.value = 2
221
+ titleModal.value = translate('Remove Component?')
222
+ descriptionModal.value = translate('Are you sure you want to remove this Component?')
223
+ firstButtonModal.value = translate('Close')
224
+ secondButtonModal.value = null
225
+ thirdButtonModal.value = translate('Delete')
226
+
227
+ // handle click
228
+ firstModalButtonFunctionDynamicModalBuilder.value = function () {
229
+ showModalDeleteComponent.value = false
230
+ }
231
+ //
232
+ // handle click
233
+ thirdModalButtonFunctionDynamicModalBuilder.value = async function () {
234
+ await pageBuilderService.deleteComponentFromDOM()
235
+
236
+ showModalDeleteComponent.value = false
237
+ }
238
+ // end modal
239
+ }
193
240
  </script>
194
241
  <template v-if="getElement">
195
242
  <div>
196
243
  <DynamicModalBuilder
197
244
  :showDynamicModalBuilder="showModalIframeSrc"
198
245
  maxWidth="2xl"
199
- :type="typeModal"
200
- :gridColumnAmount="gridColumnModal"
201
- :title="titleModal"
202
- :description="descriptionModal"
203
- :firstButtonText="firstButtonModal"
204
- :secondButtonText="secondButtonModal"
205
- :thirdButtonText="thirdButtonModal"
206
- @firstModalButtonFunctionDynamicModalBuilder="firstModalButtonFunctionDynamicModalBuilder"
207
- @secondModalButtonFunctionDynamicModalBuilder="secondModalButtonFunctionDynamicModalBuilder"
208
- @thirdModalButtonFunctionDynamicModalBuilder="thirdModalButtonFunctionDynamicModalBuilder"
246
+ :type="typeModalTipTap"
247
+ :gridColumnAmount="gridColumnModalTipTap"
248
+ :title="titleModalTipTap"
249
+ :description="descriptionModalTipTap"
250
+ :firstButtonText="firstButtonModalTipTap"
251
+ :secondButtonText="secondButtonModalTipTap"
252
+ :thirdButtonText="thirdButtonModalTipTap"
253
+ @firstModalButtonFunctionDynamicModalBuilderTipTap="
254
+ firstModalButtonFunctionDynamicModalBuilderTipTap
255
+ "
256
+ @secondModalButtonFunctionDynamicModalBuilderTipTap="
257
+ secondModalButtonFunctionDynamicModalBuilderTipTap
258
+ "
259
+ @thirdModalButtonFunctionDynamicModalBuilderTipTap="
260
+ thirdModalButtonFunctionDynamicModalBuilderTipTap
261
+ "
209
262
  >
210
263
  <header></header>
211
264
  <main>
@@ -237,6 +290,30 @@ const openOptionsMoreOpen = ref(false)
237
290
  :simpleModal="true"
238
291
  :showDynamicModalBuilder="getShowModalTipTap"
239
292
  maxWidth="6xl"
293
+ :type="typeModalTipTap"
294
+ :gridColumnAmount="gridColumnModalTipTap"
295
+ :title="titleModalTipTap"
296
+ :description="descriptionModalTipTap"
297
+ :firstButtonText="firstButtonModalTipTap"
298
+ :secondButtonText="secondButtonModalTipTap"
299
+ :thirdButtonText="thirdButtonModalTipTap"
300
+ @firstModalButtonFunctionDynamicModalBuilder="
301
+ firstModalButtonFunctionDynamicModalBuilderTipTap
302
+ "
303
+ @secondModalButtonFunctionDynamicModalBuilder="
304
+ secondModalButtonFunctionDynamicModalBuilderTipTap
305
+ "
306
+ @thirdModalButtonFunctionDynamicModalBuilder="
307
+ thirdModalButtonFunctionDynamicModalBuilderTipTap
308
+ "
309
+ >
310
+ <header></header>
311
+ <main class="pbx-overflow-y-auto">
312
+ <TipTapInput></TipTapInput>
313
+ </main>
314
+ </DynamicModalBuilder>
315
+ <DynamicModalBuilder
316
+ :showDynamicModalBuilder="showModalDeleteComponent"
240
317
  :type="typeModal"
241
318
  :gridColumnAmount="gridColumnModal"
242
319
  :title="titleModal"
@@ -249,11 +326,8 @@ const openOptionsMoreOpen = ref(false)
249
326
  @thirdModalButtonFunctionDynamicModalBuilder="thirdModalButtonFunctionDynamicModalBuilder"
250
327
  >
251
328
  <header></header>
252
- <main class="pbx-overflow-y-auto">
253
- <TipTapInput></TipTapInput>
254
- </main>
329
+ <main></main>
255
330
  </DynamicModalBuilder>
256
-
257
331
  <MediaLibraryModal
258
332
  :open="showMediaLibraryModal"
259
333
  :title="titleMedia"
@@ -365,28 +439,69 @@ const openOptionsMoreOpen = ref(false)
365
439
  <transition name="popup-fade">
366
440
  <div
367
441
  v-if="openOptionsMoreOpen"
368
- class="pbx-fixed pbx-z-40 pbx-top-10 pbx-right-0 lg:pbx-w-72 md:pbx-w-64 pbx-w-full pbx-select-none"
442
+ class="pbx-fixed pbx-z-40 pbx-top-10 pbx-right-0 lg:pbx-w-72 md:pbx-w-72 pbx-w-full pbx-select-none"
369
443
  >
370
444
  <div
371
445
  class="pbx-rounded-3xl pbx-border pbx-border-gray-100 pbx-bg-white pbx-shadow-lg pbx-pt-4 pbx-pb-4 pbx-flex pbx-flex-col pbx-overflow-y-auto pbx-max-h-[80vh] pbx-mx-4 pbx-px-2"
372
446
  >
373
- <div
374
- class="pbx-flex pbx-gap-2 pbx-items-center pbx-justify-between pbx-border-b pbx-border-gray-200 pbx-pb-4 pbx-pl-2"
375
- >
376
- <span class="pbx-text-black pbx-font-medium">Options</span>
447
+ <div class="pbx-flex pbx-flex-col">
448
+ <!-- content start -->
449
+ <!-- move up and down start -->
450
+ <div
451
+ v-if="getElement && getComponent"
452
+ @click="pageBuilderService.reorderComponent(-1)"
453
+ :disabled="!canMoveUp"
454
+ class="pbx-flex pbx-items-center pbx-justify-start pbx-gap-2 pbx-cursor-pointer hover:pbx-bg-red-50 pbx-py-2 pbx-px-2 pbx-rounded-full"
455
+ >
456
+ <div
457
+ class="pbx-h-8 pbx-w-8 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-200 pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white focus-visible:pbx-ring-0 pbx-text-myPrimaryDarkGrayColor"
458
+ :class="[
459
+ canMoveUp
460
+ ? 'hover:pbx-bg-myPrimaryLinkColor hover:pbx-text-white focus-visible:pbx-ring-0 pbx-cursor-pointer'
461
+ : 'pbx-cursor-not-allowed pbx-bg-opacity-20 hover:pbx-bg-gray-200',
462
+ ]"
463
+ >
464
+ <span class="material-symbols-outlined"> move_up </span>
465
+ </div>
466
+ <div class="pbx-text-sm">Move up</div>
467
+ </div>
468
+ <div
469
+ v-if="getElement && getComponent"
470
+ @click="pageBuilderService.reorderComponent(1)"
471
+ :disabled="!canMoveDown"
472
+ class="pbx-flex pbx-items-center pbx-justify-start pbx-gap-2 pbx-cursor-pointer hover:pbx-bg-red-50 pbx-py-2 pbx-px-2 pbx-rounded-full"
473
+ >
474
+ <div
475
+ class="pbx-h-8 pbx-w-8 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-200 pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white focus-visible:pbx-ring-0 pbx-text-myPrimaryDarkGrayColor"
476
+ :class="[
477
+ canMoveDown
478
+ ? 'hover:pbx-bg-myPrimaryLinkColor hover:pbx-text-white focus-visible:pbx-ring-0 pbx-cursor-pointer'
479
+ : 'pbx-cursor-not-allowed pbx-bg-opacity-20 hover:pbx-bg-gray-200',
480
+ ]"
481
+ >
482
+ <span class="material-symbols-outlined"> move_down </span>
483
+ </div>
484
+ <div class="pbx-text-sm">Move down</div>
485
+ </div>
486
+ <!-- move up and down end -->
487
+
488
+ <!-- delete component start -->
377
489
 
378
- <!-- Close Modal start -->
379
490
  <div
380
- @click="openOptionsMoreOpen = !openOptionsMoreOpen"
381
- class="pbx-h-8 pbx-w-8 pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-black pbx-text-white pbx-aspect-square hover:pbx-fill-white focus-visible:pbx-ring-0 hover:pbx-outline-3 hover:pbx-outline-offset-2 hover:pbx-outline-black pbx-transition-all pbx-duration-100"
491
+ v-if="getElement && getComponent"
492
+ @click="handleDelete()"
493
+ class="pbx-flex pbx-items-center pbx-justify-start pbx-gap-2 pbx-cursor-pointer hover:pbx-bg-red-50 pbx-py-2 pbx-px-2 pbx-rounded-full"
382
494
  >
383
- <span class="material-symbols-outlined"> close_small </span>
495
+ <div
496
+ class="pbx-h- pbx-w-8 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-myPrimaryErrorColor hover:pbx-text-white pbx-text-myPrimaryErrorColor"
497
+ >
498
+ <span class="material-symbols-outlined"> delete_forever </span>
499
+ </div>
500
+ <div class="pbx-text-sm">Delete component</div>
384
501
  </div>
385
- <!-- Close Modal Start -->
386
- </div>
387
502
 
388
- <div class="pbx-flex pbx-flex-col pbx-gap-4 pbx-mt-6">
389
- <!-- content start -->
503
+ <!-- delete component end -->
504
+
390
505
  <div
391
506
  v-if="getElement && getComponent"
392
507
  @click="
@@ -395,7 +510,7 @@ const openOptionsMoreOpen = ref(false)
395
510
  pageBuilderService.duplicateComponent()
396
511
  }
397
512
  "
398
- class="pbx-flex pbx-items-center pbx-justify-start pbx-gap-2 pbx-cursor-pointer"
513
+ class="pbx-flex pbx-items-center pbx-justify-start pbx-gap-2 pbx-cursor-pointer hover:pbx-bg-red-50 pbx-py-2 pbx-px-2 pbx-rounded-full"
399
514
  >
400
515
  <div
401
516
  class="pbx-h-8 pbx-w-8 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-200 pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white focus-visible:pbx-ring-0 pbx-text-myPrimaryDarkGrayColor"
@@ -404,6 +519,19 @@ const openOptionsMoreOpen = ref(false)
404
519
  </div>
405
520
  <div class="pbx-text-sm">Duplicate component</div>
406
521
  </div>
522
+ <div
523
+ v-if="getElement && getComponent"
524
+ @click="handleShowHTMLEditor"
525
+ class="pbx-flex pbx-items-center pbx-justify-start pbx-gap-2 pbx-cursor-pointer hover:pbx-bg-red-50 pbx-py-2 pbx-px-2 pbx-rounded-full"
526
+ >
527
+ <div
528
+ class="pbx-h-8 pbx-w-8 pbx-flex-end pbx-cursor-pointer pbx-rounded-full pbx-flex pbx-items-center pbx-border-none pbx-justify-center pbx-bg-gray-200 pbx-aspect-square hover:pbx-bg-gray-100 hover:pbx-fill-white focus-visible:pbx-ring-0 pbx-text-myPrimaryDarkGrayColor"
529
+ >
530
+ <span class="material-symbols-outlined"> deployed_code </span>
531
+ </div>
532
+ <div class="pbx-text-sm">{{ translate('HTML Editor') }}</div>
533
+ </div>
534
+
407
535
  <!-- content end -->
408
536
  </div>
409
537
  </div>
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { ref, computed, nextTick } from 'vue'
2
+ import { ref, computed, watch, nextTick } from 'vue'
3
3
  import { sharedPageBuilderStore } from '../../../../stores/shared-store'
4
4
  import ModalBuilder from '../../../../Components/Modals/ModalBuilder.vue'
5
5
  import EditorAccordion from '../EditorAccordion.vue'
@@ -18,6 +18,7 @@ const props = defineProps({
18
18
  })
19
19
 
20
20
  const getElement = computed(() => pageBuilderStateStore.getElement)
21
+ const getShowModalHTMLEditor = computed(() => pageBuilderStateStore.getShowModalHTMLEditor)
21
22
 
22
23
  const elementHTML = computed(() => {
23
24
  if (!getElement.value || !(getElement.value instanceof HTMLElement)) {
@@ -26,24 +27,26 @@ const elementHTML = computed(() => {
26
27
  return getElement.value.outerHTML
27
28
  })
28
29
 
29
- const showModalHTMLEditor = ref(false)
30
-
31
30
  const editableHtml = ref('')
32
31
  const editableComponents = ref('')
33
32
 
34
- const handleShowHTMLEditor = async () => {
35
- showModalHTMLEditor.value = true
33
+ watch(getShowModalHTMLEditor, async (newVal) => {
34
+ if (newVal) {
35
+ if (!props.globalPage) {
36
+ editableHtml.value = elementHTML.value
37
+ return
38
+ }
36
39
 
37
- if (!props.globalPage) {
38
- editableHtml.value = elementHTML.value
39
- return
40
+ editableComponents.value = await pageBuilderService.generateHtmlFromComponents()
40
41
  }
42
+ })
41
43
 
42
- editableComponents.value = await pageBuilderService.generateHtmlFromComponents()
44
+ const handleShowHTMLEditor = async () => {
45
+ pageBuilderStateStore.setShowModalHTMLEditor(true)
43
46
  }
44
47
 
45
48
  const handleCloseHTMLEditor = () => {
46
- showModalHTMLEditor.value = false
49
+ pageBuilderStateStore.setShowModalHTMLEditor(false)
47
50
  }
48
51
 
49
52
  const isLoading = ref(false)
@@ -62,7 +65,7 @@ const handleSaveChangesElement = async () => {
62
65
  return
63
66
  }
64
67
 
65
- showModalHTMLEditor.value = false
68
+ pageBuilderStateStore.setShowModalHTMLEditor(false)
66
69
  isLoading.value = false
67
70
  }
68
71
 
@@ -80,7 +83,7 @@ const handleSaveChangesComponents = async () => {
80
83
  return
81
84
  }
82
85
 
83
- showModalHTMLEditor.value = false
86
+ pageBuilderStateStore.setShowModalHTMLEditor(false)
84
87
  isLoading.value = false
85
88
  }
86
89
  </script>
@@ -101,7 +104,7 @@ const handleSaveChangesComponents = async () => {
101
104
  </EditorAccordion>
102
105
  <ModalBuilder
103
106
  maxWidth="7xl"
104
- :showModalBuilder="showModalHTMLEditor"
107
+ :showModalBuilder="getShowModalHTMLEditor"
105
108
  :title="translate('HTML Editor')"
106
109
  @closeMainModalBuilder="handleCloseHTMLEditor"
107
110
  >
@@ -52,6 +52,7 @@ interface PageBuilderState {
52
52
  components: ComponentObject[]
53
53
  basePrimaryImage: string | null
54
54
  configPageBuilder: PageBuilderConfig | null
55
+ showModalHTMLEditor: boolean
55
56
 
56
57
  // Media Library State
57
58
  applyImageToSelection: ImageObject
@@ -114,6 +115,7 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
114
115
  components: [],
115
116
  basePrimaryImage: null,
116
117
  configPageBuilder: null,
118
+ showModalHTMLEditor: false,
117
119
 
118
120
  // Media Library State
119
121
  applyImageToSelection: { src: '' },
@@ -260,6 +262,9 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
260
262
  getPageBuilderConfig(state: PageBuilderState): PageBuilderConfig | null {
261
263
  return state.configPageBuilder
262
264
  },
265
+ getShowModalHTMLEditor(state: PageBuilderState): boolean {
266
+ return state.showModalHTMLEditor
267
+ },
263
268
 
264
269
  getApplyImageToSelection(state: PageBuilderState): ImageObject {
265
270
  return state.applyImageToSelection
@@ -450,6 +455,10 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
450
455
  this.configPageBuilder = payload
451
456
  },
452
457
 
458
+ setShowModalHTMLEditor(payload: boolean): void {
459
+ this.showModalHTMLEditor = payload
460
+ },
461
+
453
462
  setApplyImageToSelection(payload: ImageObject): void {
454
463
  this.applyImageToSelection = payload
455
464
  },