@myissue/vue-website-page-builder 3.3.94 → 3.3.96
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/style.css +1 -1
- package/dist/vue-website-page-builder.js +4295 -4216
- package/dist/vue-website-page-builder.umd.cjs +56 -56
- package/package.json +1 -1
- package/src/Components/PageBuilder/EditorMenu/Editables/EditGetElement.vue +0 -4
- package/src/Components/PageBuilder/EditorMenu/RightSidebarEditor.vue +0 -1
- package/src/Components/PageBuilder/UndoRedo/UndoRedo.vue +46 -0
- package/src/PageBuilder/PageBuilder.vue +9 -25
- package/src/css/style.css +1 -0
- package/src/services/LocalStorageManager.ts +25 -1
- package/src/services/PageBuilderService.ts +129 -57
- package/src/stores/page-builder-state.ts +2 -24
- package/src/tests/PageBuilderTest.vue +32 -48
- package/src/utils/builder/tailwind-font-styles.ts +0 -1
- package/src/Components/PageBuilder/EditorMenu/Editables/DeleteElement.vue +0 -42
- package/src/Components/PageBuilder/EditorMenu/Editables/ElementEditor.vue +0 -62
package/package.json
CHANGED
|
@@ -188,10 +188,6 @@ const handleModalIframeSrc = function () {
|
|
|
188
188
|
showModalIframeSrc.value = false
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
-
|
|
192
|
-
const getRestoredElement = computed(() => {
|
|
193
|
-
return pageBuilderStateStore.getRestoredElement
|
|
194
|
-
})
|
|
195
191
|
</script>
|
|
196
192
|
<template v-if="getElement">
|
|
197
193
|
<div>
|
|
@@ -15,7 +15,6 @@ import Borders from './Editables/Borders.vue'
|
|
|
15
15
|
import LinkEditor from './Editables/LinkEditor.vue'
|
|
16
16
|
import TipTap from '../../TipTap/TipTap.vue'
|
|
17
17
|
import EditGetElement from './Editables/EditGetElement.vue'
|
|
18
|
-
import ElementEditor from './Editables/ElementEditor.vue'
|
|
19
18
|
import HTMLEditor from './Editables/HTMLEditor.vue'
|
|
20
19
|
import { getPageBuilder } from '../../../composables/builderInstance'
|
|
21
20
|
import EditorAccordion from '../EditorMenu/EditorAccordion.vue'
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { sharedPageBuilderStore } from '../../../stores/shared-store'
|
|
4
|
+
import GlobalLoader from '../../../Components/Loaders/GlobalLoader.vue'
|
|
5
|
+
import { getPageBuilder } from '../../../composables/builderInstance'
|
|
6
|
+
|
|
7
|
+
const pageBuilderService = getPageBuilder()
|
|
8
|
+
|
|
9
|
+
// Use shared store instance
|
|
10
|
+
const pageBuilderStateStore = sharedPageBuilderStore
|
|
11
|
+
|
|
12
|
+
const getIsLoadingGlobal = computed(() => {
|
|
13
|
+
return pageBuilderStateStore.getIsLoadingGlobal
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const handleUndo = async function () {
|
|
17
|
+
await pageBuilderService.undo()
|
|
18
|
+
}
|
|
19
|
+
const handleRedo = async function () {
|
|
20
|
+
await pageBuilderService.redo()
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<GlobalLoader v-if="getIsLoadingGlobal"></GlobalLoader>
|
|
26
|
+
<div class="pbx-flex-1 pbx-flex pbx-justify-center pbx-items-center pbx-py-2 pbx-w-full gap-2">
|
|
27
|
+
<!-- Undo Start -->
|
|
28
|
+
<button @click="handleUndo" type="button">
|
|
29
|
+
<div
|
|
30
|
+
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 focus-visible:pbx-ring-0 pbx-text-black hover:pbx-text-white"
|
|
31
|
+
>
|
|
32
|
+
<span class="material-symbols-outlined"> undo </span>
|
|
33
|
+
</div>
|
|
34
|
+
</button>
|
|
35
|
+
<!-- Undo End -->
|
|
36
|
+
<!-- Redo Start -->
|
|
37
|
+
<button @click="handleRedo" type="button">
|
|
38
|
+
<div
|
|
39
|
+
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 focus-visible:pbx-ring-0 pbx-text-black hover:pbx-text-white pbx-ml-2"
|
|
40
|
+
>
|
|
41
|
+
<span class="material-symbols-outlined"> redo </span>
|
|
42
|
+
</div>
|
|
43
|
+
</button>
|
|
44
|
+
<!-- Redo End -->
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
@@ -14,6 +14,7 @@ import DynamicModalBuilder from '../Components/Modals/DynamicModalBuilder.vue'
|
|
|
14
14
|
import GlobalLoader from '../Components/Loaders/GlobalLoader.vue'
|
|
15
15
|
import { useTranslations } from '../composables/useTranslations'
|
|
16
16
|
import { getPageBuilder } from '../composables/builderInstance'
|
|
17
|
+
import UndoRedo from '../Components/PageBuilder/UndoRedo/UndoRedo.vue'
|
|
17
18
|
const pageBuilderService = getPageBuilder()
|
|
18
19
|
/**
|
|
19
20
|
* Props for PageBuilder component
|
|
@@ -167,10 +168,6 @@ const getElement = computed(() => {
|
|
|
167
168
|
return pageBuilderStateStore.getElement
|
|
168
169
|
})
|
|
169
170
|
|
|
170
|
-
const getRestoredElement = computed(() => {
|
|
171
|
-
return pageBuilderStateStore.getRestoredElement
|
|
172
|
-
})
|
|
173
|
-
|
|
174
171
|
const getComponents = computed(() => {
|
|
175
172
|
return pageBuilderStateStore.getComponents
|
|
176
173
|
})
|
|
@@ -323,15 +320,13 @@ const ensureBuilderInitialized = function () {
|
|
|
323
320
|
}
|
|
324
321
|
}
|
|
325
322
|
|
|
326
|
-
const
|
|
327
|
-
|
|
323
|
+
const pageBuilderWrapper = ref(null)
|
|
328
324
|
let lastToolbarLeft = null
|
|
329
325
|
let lastToolbarTop = null
|
|
330
326
|
|
|
331
327
|
function updatePanelPosition() {
|
|
332
|
-
const container =
|
|
328
|
+
const container = pageBuilderWrapper.value
|
|
333
329
|
const editToolbarElement = container && container.querySelector('#pbxEditToolbar')
|
|
334
|
-
const restored = getRestoredElement.value
|
|
335
330
|
|
|
336
331
|
if (!container || !editToolbarElement) return
|
|
337
332
|
|
|
@@ -364,11 +359,6 @@ function updatePanelPosition() {
|
|
|
364
359
|
|
|
365
360
|
lastToolbarLeft = left
|
|
366
361
|
lastToolbarTop = top
|
|
367
|
-
} else if (restored && lastToolbarLeft !== null && lastToolbarTop !== null) {
|
|
368
|
-
editToolbarElement.style.position = 'absolute'
|
|
369
|
-
editToolbarElement.style.left = `${lastToolbarLeft}px`
|
|
370
|
-
editToolbarElement.style.top = `${lastToolbarTop}px`
|
|
371
|
-
editToolbarElement.classList.add('is-visible')
|
|
372
362
|
} else {
|
|
373
363
|
editToolbarElement.classList.remove('is-visible')
|
|
374
364
|
}
|
|
@@ -399,7 +389,7 @@ onMounted(async () => {
|
|
|
399
389
|
updatePanelPosition()
|
|
400
390
|
|
|
401
391
|
// Set up MutationObserver and event listeners
|
|
402
|
-
const container =
|
|
392
|
+
const container = pageBuilderWrapper.value
|
|
403
393
|
if (!container) return
|
|
404
394
|
|
|
405
395
|
const observer = new MutationObserver(updatePanelPosition)
|
|
@@ -538,6 +528,8 @@ onMounted(async () => {
|
|
|
538
528
|
</template>
|
|
539
529
|
<!-- Logo # end -->
|
|
540
530
|
|
|
531
|
+
<UndoRedo></UndoRedo>
|
|
532
|
+
|
|
541
533
|
<div
|
|
542
534
|
@click.self="
|
|
543
535
|
async () => {
|
|
@@ -866,7 +858,8 @@ onMounted(async () => {
|
|
|
866
858
|
<!-- Left Menu End -->
|
|
867
859
|
|
|
868
860
|
<main
|
|
869
|
-
ref="
|
|
861
|
+
ref="pageBuilderWrapper"
|
|
862
|
+
id="page-builder-wrapper"
|
|
870
863
|
class="pbx-transition-all pbx-duration-300 pbx-font-sans pbx-p-1 pbx-flex pbx-flex-col pbx-grow pbx-rounded-tr-2xl pbx-rounded-tl-2xl pbx-border-solid pbx-border pbx-border-gray-200 pbx-items-stretch pbx-text-black pbx-h-[100vh] pbx-overflow-y-auto"
|
|
871
864
|
:class="[getMenuRight ? 'pbx-w-full' : 'pbx-w-full']"
|
|
872
865
|
>
|
|
@@ -881,15 +874,6 @@ onMounted(async () => {
|
|
|
881
874
|
<template v-if="getElement">
|
|
882
875
|
<EditGetElement></EditGetElement>
|
|
883
876
|
</template>
|
|
884
|
-
<template v-if="getRestoredElement">
|
|
885
|
-
<button
|
|
886
|
-
@click="pageBuilderService.restoreDeletedElementToDOM"
|
|
887
|
-
type="button"
|
|
888
|
-
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 pbx-bg-gray-200 focus-visible:pbx-ring-0"
|
|
889
|
-
>
|
|
890
|
-
<span class="material-symbols-outlined"> undo </span>
|
|
891
|
-
</button>
|
|
892
|
-
</template>
|
|
893
877
|
</div>
|
|
894
878
|
<!-- Element Popover toolbar end -->
|
|
895
879
|
|
|
@@ -926,7 +910,7 @@ onMounted(async () => {
|
|
|
926
910
|
await pageBuilderService.clearHtmlSelection()
|
|
927
911
|
}
|
|
928
912
|
"
|
|
929
|
-
class="pbx-w-
|
|
913
|
+
class="pbx-w-18 pbx-bg-myPrimaryLightGrayColor pbx-pt-5 pbx-z-20 pbx-flex-shrink-0 pbx-overflow-hidden pbx-border-0 pbx-border-solid pbx-border-l-0 pbx-border-l-gray-600 pbx-rounded-l-2xl pbx-h-[100vh] pbx-pl-2 pbx-pr-2"
|
|
930
914
|
>
|
|
931
915
|
<div
|
|
932
916
|
@click.self="
|
package/src/css/style.css
CHANGED
|
@@ -1 +1,25 @@
|
|
|
1
|
-
export class LocalStorageManager {
|
|
1
|
+
export class LocalStorageManager {
|
|
2
|
+
private static readonly HISTORY_KEY_SUFFIX = '-history'
|
|
3
|
+
private static readonly MAX_HISTORY_SIZE = 10
|
|
4
|
+
|
|
5
|
+
public static getHistory(baseKey: string): any[] {
|
|
6
|
+
const historyKey = baseKey + this.HISTORY_KEY_SUFFIX
|
|
7
|
+
const historyJson = localStorage.getItem(historyKey)
|
|
8
|
+
return historyJson ? JSON.parse(historyJson) : []
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public static addToHistory(baseKey: string, data: any) {
|
|
12
|
+
const historyKey = baseKey + this.HISTORY_KEY_SUFFIX
|
|
13
|
+
let history = this.getHistory(baseKey)
|
|
14
|
+
history.push(data)
|
|
15
|
+
if (history.length > this.MAX_HISTORY_SIZE) {
|
|
16
|
+
history = history.slice(history.length - this.MAX_HISTORY_SIZE)
|
|
17
|
+
}
|
|
18
|
+
localStorage.setItem(historyKey, JSON.stringify(history))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public static clearHistory(baseKey: string) {
|
|
22
|
+
const historyKey = baseKey + this.HISTORY_KEY_SUFFIX
|
|
23
|
+
localStorage.removeItem(historyKey)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LocalStorageManager } from './LocalStorageManager'
|
|
1
2
|
import type {
|
|
2
3
|
BuilderResourceData,
|
|
3
4
|
ComponentObject,
|
|
@@ -60,9 +61,6 @@ export class PageBuilderService {
|
|
|
60
61
|
private getComponents: ComputedRef<ComponentObject[] | null>
|
|
61
62
|
private getComponent: ComputedRef<ComponentObject | null>
|
|
62
63
|
private getElement: ComputedRef<HTMLElement | null>
|
|
63
|
-
private getNextSibling: ComputedRef<HTMLElement | null>
|
|
64
|
-
private getParentElement: ComputedRef<HTMLElement | null>
|
|
65
|
-
private getRestoredElement: ComputedRef<string | null>
|
|
66
64
|
private getComponentArrayAddMethod: ComputedRef<string | null>
|
|
67
65
|
private NoneListernesTags: string[]
|
|
68
66
|
private hasStartedEditing: boolean = false
|
|
@@ -98,9 +96,6 @@ export class PageBuilderService {
|
|
|
98
96
|
this.getComponent = computed(() => this.pageBuilderStateStore.getComponent)
|
|
99
97
|
|
|
100
98
|
this.getElement = computed(() => this.pageBuilderStateStore.getElement)
|
|
101
|
-
this.getNextSibling = computed(() => this.pageBuilderStateStore.getNextSibling)
|
|
102
|
-
this.getParentElement = computed(() => this.pageBuilderStateStore.getParentElement)
|
|
103
|
-
this.getRestoredElement = computed(() => this.pageBuilderStateStore.getRestoredElement)
|
|
104
99
|
|
|
105
100
|
this.getComponentArrayAddMethod = computed(
|
|
106
101
|
() => this.pageBuilderStateStore.getComponentArrayAddMethod,
|
|
@@ -416,6 +411,7 @@ export class PageBuilderService {
|
|
|
416
411
|
|
|
417
412
|
// Update the localStorage key name based on the config/resource
|
|
418
413
|
this.updateLocalStorageItemName()
|
|
414
|
+
this.initializeHistory()
|
|
419
415
|
|
|
420
416
|
if (passedComponentsArray) {
|
|
421
417
|
this.savedMountComponents = passedComponentsArray
|
|
@@ -988,6 +984,19 @@ export class PageBuilderService {
|
|
|
988
984
|
await this.handleAutoSave()
|
|
989
985
|
}
|
|
990
986
|
|
|
987
|
+
private historyIndex: number = -1
|
|
988
|
+
private getHistoryBaseKey(): string | null {
|
|
989
|
+
return this.getLocalStorageItemName.value
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
private initializeHistory() {
|
|
993
|
+
const baseKey = this.getHistoryBaseKey()
|
|
994
|
+
if (baseKey) {
|
|
995
|
+
const history = LocalStorageManager.getHistory(baseKey)
|
|
996
|
+
this.historyIndex = history.length - 1
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
|
|
991
1000
|
/**
|
|
992
1001
|
* Triggers an auto-save of the current page builder content to local storage if enabled.
|
|
993
1002
|
*/
|
|
@@ -1052,12 +1061,12 @@ export class PageBuilderService {
|
|
|
1052
1061
|
// Deep clone clone component
|
|
1053
1062
|
const clonedComponent = { ...componentObject }
|
|
1054
1063
|
|
|
1055
|
-
const
|
|
1064
|
+
const pageBuilderWrapper = document.querySelector('#page-builder-wrapper')
|
|
1056
1065
|
// scoll to top or bottom
|
|
1057
|
-
if (
|
|
1066
|
+
if (pageBuilderWrapper) {
|
|
1058
1067
|
// push to top
|
|
1059
1068
|
if (this.getComponentArrayAddMethod.value === 'unshift') {
|
|
1060
|
-
|
|
1069
|
+
pageBuilderWrapper.scrollTo({
|
|
1061
1070
|
top: 0,
|
|
1062
1071
|
behavior: 'smooth',
|
|
1063
1072
|
})
|
|
@@ -1441,6 +1450,61 @@ export class PageBuilderService {
|
|
|
1441
1450
|
.forEach((section) => section.remove())
|
|
1442
1451
|
}
|
|
1443
1452
|
}
|
|
1453
|
+
//
|
|
1454
|
+
public async undo() {
|
|
1455
|
+
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
1456
|
+
await delay(300)
|
|
1457
|
+
const baseKey = this.getHistoryBaseKey()
|
|
1458
|
+
if (!baseKey) return
|
|
1459
|
+
|
|
1460
|
+
const history = LocalStorageManager.getHistory(baseKey)
|
|
1461
|
+
if (history.length > 1 && this.historyIndex > 0) {
|
|
1462
|
+
this.historyIndex--
|
|
1463
|
+
const data = history[this.historyIndex]
|
|
1464
|
+
const htmlString = this.renderComponentsToHtml(data.components)
|
|
1465
|
+
await this.mountComponentsToDOM(htmlString)
|
|
1466
|
+
}
|
|
1467
|
+
this.pageBuilderStateStore.setIsLoadingGlobal(false)
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
public async redo() {
|
|
1471
|
+
this.pageBuilderStateStore.setIsLoadingGlobal(true)
|
|
1472
|
+
await delay(300)
|
|
1473
|
+
const baseKey = this.getHistoryBaseKey()
|
|
1474
|
+
if (!baseKey) return
|
|
1475
|
+
|
|
1476
|
+
const history = LocalStorageManager.getHistory(baseKey)
|
|
1477
|
+
if (history.length > 0 && this.historyIndex < history.length - 1) {
|
|
1478
|
+
this.historyIndex++
|
|
1479
|
+
const data = history[this.historyIndex]
|
|
1480
|
+
const htmlString = this.renderComponentsToHtml(data.components)
|
|
1481
|
+
await this.mountComponentsToDOM(htmlString)
|
|
1482
|
+
}
|
|
1483
|
+
this.pageBuilderStateStore.setIsLoadingGlobal(false)
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
private hasVisibleContent(element: HTMLElement): boolean {
|
|
1487
|
+
if (!element) return false
|
|
1488
|
+
|
|
1489
|
+
// Check for meaningful elements
|
|
1490
|
+
const meaningfulContentSelector =
|
|
1491
|
+
'img, video, iframe, input, button, a, h1, h2, h3, h4, h5, h6, p, li, blockquote, pre, code, table'
|
|
1492
|
+
if (element.querySelector(meaningfulContentSelector)) return true
|
|
1493
|
+
|
|
1494
|
+
// Check for non-empty text nodes
|
|
1495
|
+
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null)
|
|
1496
|
+
while (walker.nextNode()) {
|
|
1497
|
+
if (walker.currentNode.nodeValue && walker.currentNode.nodeValue.trim() !== '') {
|
|
1498
|
+
return true
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
return false
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
private isSectionEmpty(section: HTMLElement): boolean {
|
|
1506
|
+
return !this.hasVisibleContent(section)
|
|
1507
|
+
}
|
|
1444
1508
|
|
|
1445
1509
|
/**
|
|
1446
1510
|
* Deletes the currently selected component from the DOM and the state.
|
|
@@ -1450,13 +1514,13 @@ export class PageBuilderService {
|
|
|
1450
1514
|
this.syncDomToStoreOnly()
|
|
1451
1515
|
await nextTick()
|
|
1452
1516
|
|
|
1453
|
-
const components = this.getComponents
|
|
1517
|
+
const components = this.pageBuilderStateStore.getComponents
|
|
1454
1518
|
|
|
1455
1519
|
if (!components) return
|
|
1456
1520
|
|
|
1457
1521
|
// Find the index of the component to be deleted.
|
|
1458
1522
|
const indexToDelete = components.findIndex(
|
|
1459
|
-
(component) => component.id === this.getComponent.value?.id,
|
|
1523
|
+
(component: ComponentObject) => component.id === this.getComponent.value?.id,
|
|
1460
1524
|
)
|
|
1461
1525
|
|
|
1462
1526
|
if (indexToDelete === -1) {
|
|
@@ -1509,15 +1573,35 @@ export class PageBuilderService {
|
|
|
1509
1573
|
return
|
|
1510
1574
|
}
|
|
1511
1575
|
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
this.
|
|
1517
|
-
|
|
1576
|
+
const parentSection = element.closest('section')
|
|
1577
|
+
|
|
1578
|
+
// If the element to be deleted is the section itself
|
|
1579
|
+
if (element.tagName === 'SECTION') {
|
|
1580
|
+
this.deleteComponentFromDOM()
|
|
1581
|
+
} else {
|
|
1582
|
+
// If the element is inside a section
|
|
1518
1583
|
element.remove()
|
|
1584
|
+
if (parentSection && this.isSectionEmpty(parentSection)) {
|
|
1585
|
+
const componentId = parentSection.getAttribute('data-componentid')
|
|
1586
|
+
if (componentId) {
|
|
1587
|
+
const components = this.pageBuilderStateStore.getComponents
|
|
1588
|
+
if (components) {
|
|
1589
|
+
const indexToDelete = components.findIndex((c: ComponentObject) => c.id === componentId)
|
|
1590
|
+
if (indexToDelete !== -1) {
|
|
1591
|
+
const newComponents = [
|
|
1592
|
+
...components.slice(0, indexToDelete),
|
|
1593
|
+
...components.slice(indexToDelete + 1),
|
|
1594
|
+
]
|
|
1595
|
+
this.pageBuilderStateStore.setComponents(newComponents)
|
|
1596
|
+
parentSection.remove() // Directly remove from DOM
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1519
1601
|
}
|
|
1520
1602
|
|
|
1603
|
+
this.handleAutoSave()
|
|
1604
|
+
|
|
1521
1605
|
// Clear the selection state.
|
|
1522
1606
|
this.pageBuilderStateStore.setComponent(null)
|
|
1523
1607
|
this.pageBuilderStateStore.setElement(null)
|
|
@@ -1530,39 +1614,6 @@ export class PageBuilderService {
|
|
|
1530
1614
|
await this.addListenersToEditableElements()
|
|
1531
1615
|
}
|
|
1532
1616
|
|
|
1533
|
-
/**
|
|
1534
|
-
* Restores the last deleted element to its previous position in the DOM.
|
|
1535
|
-
* @returns {Promise<void>}
|
|
1536
|
-
*/
|
|
1537
|
-
public async restoreDeletedElementToDOM() {
|
|
1538
|
-
// Retrieve the details of the element to be restored.
|
|
1539
|
-
const restoredHTML = this.getRestoredElement.value
|
|
1540
|
-
const parent = this.getParentElement.value
|
|
1541
|
-
const nextSibling = this.getNextSibling.value
|
|
1542
|
-
|
|
1543
|
-
if (restoredHTML && parent) {
|
|
1544
|
-
// Create a temporary container to parse the stored HTML.
|
|
1545
|
-
const container = document.createElement('div')
|
|
1546
|
-
container.innerHTML = restoredHTML
|
|
1547
|
-
|
|
1548
|
-
// Insert the restored element back into its original position.
|
|
1549
|
-
if (container.firstChild) {
|
|
1550
|
-
parent.insertBefore(container.firstChild, nextSibling)
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
// Clear the state related to the restored element.
|
|
1555
|
-
this.pageBuilderStateStore.setParentElement(null)
|
|
1556
|
-
this.pageBuilderStateStore.setRestoredElement(null)
|
|
1557
|
-
this.pageBuilderStateStore.setNextSibling(null)
|
|
1558
|
-
this.pageBuilderStateStore.setComponent(null)
|
|
1559
|
-
this.pageBuilderStateStore.setElement(null)
|
|
1560
|
-
|
|
1561
|
-
// Wait for the DOM to update before re-attaching event listeners.
|
|
1562
|
-
await nextTick()
|
|
1563
|
-
await this.addListenersToEditableElements()
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1566
1617
|
/**
|
|
1567
1618
|
* Removes a CSS class from the currently selected element.
|
|
1568
1619
|
* @param {string} userSelectedClass - The class to remove.
|
|
@@ -1823,10 +1874,31 @@ export class PageBuilderService {
|
|
|
1823
1874
|
pageSettings,
|
|
1824
1875
|
}
|
|
1825
1876
|
|
|
1826
|
-
const
|
|
1877
|
+
const baseKey = this.getHistoryBaseKey()
|
|
1878
|
+
if (baseKey) {
|
|
1879
|
+
localStorage.setItem(baseKey, JSON.stringify(dataToSave))
|
|
1880
|
+
let history = LocalStorageManager.getHistory(baseKey)
|
|
1827
1881
|
|
|
1828
|
-
|
|
1829
|
-
|
|
1882
|
+
const lastState = history[history.length - 1]
|
|
1883
|
+
if (lastState) {
|
|
1884
|
+
const lastComponents = JSON.stringify(lastState.components)
|
|
1885
|
+
const newComponents = JSON.stringify(dataToSave.components)
|
|
1886
|
+
const lastSettings = JSON.stringify(lastState.pageSettings)
|
|
1887
|
+
const newSettings = JSON.stringify(dataToSave.pageSettings)
|
|
1888
|
+
if (lastComponents === newComponents && lastSettings === newSettings) {
|
|
1889
|
+
return // Do not save duplicate state
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
if (this.historyIndex < history.length - 1) {
|
|
1894
|
+
history = history.slice(0, this.historyIndex + 1)
|
|
1895
|
+
}
|
|
1896
|
+
history.push(dataToSave)
|
|
1897
|
+
if (history.length > 10) {
|
|
1898
|
+
history = history.slice(history.length - 10)
|
|
1899
|
+
}
|
|
1900
|
+
localStorage.setItem(baseKey + '-history', JSON.stringify(history))
|
|
1901
|
+
this.historyIndex = history.length - 1
|
|
1830
1902
|
}
|
|
1831
1903
|
}
|
|
1832
1904
|
/**
|
|
@@ -2285,13 +2357,13 @@ export class PageBuilderService {
|
|
|
2285
2357
|
: 'push',
|
|
2286
2358
|
})
|
|
2287
2359
|
|
|
2288
|
-
const
|
|
2360
|
+
const pageBuilderWrapper = document.querySelector('#page-builder-wrapper')
|
|
2289
2361
|
// scoll to top or bottom
|
|
2290
|
-
if (
|
|
2362
|
+
if (pageBuilderWrapper) {
|
|
2291
2363
|
// push to bottom
|
|
2292
2364
|
if (this.getComponentArrayAddMethod.value === 'push') {
|
|
2293
|
-
|
|
2294
|
-
top:
|
|
2365
|
+
pageBuilderWrapper.scrollTo({
|
|
2366
|
+
top: pageBuilderWrapper.scrollHeight + 50,
|
|
2295
2367
|
behavior: 'smooth',
|
|
2296
2368
|
})
|
|
2297
2369
|
}
|
|
@@ -32,9 +32,6 @@ interface PageBuilderState {
|
|
|
32
32
|
opacity: string | null
|
|
33
33
|
backgroundOpacity: string | null
|
|
34
34
|
textAreaVueModel: string | null
|
|
35
|
-
nextSibling: HTMLElement | null
|
|
36
|
-
parentElement: HTMLElement | null
|
|
37
|
-
restoredElement: string | null
|
|
38
35
|
currentClasses: string[]
|
|
39
36
|
currentStyles: Record<string, string>
|
|
40
37
|
fontVerticalPadding: string | null
|
|
@@ -95,9 +92,6 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
|
|
|
95
92
|
opacity: null,
|
|
96
93
|
backgroundOpacity: null,
|
|
97
94
|
textAreaVueModel: null,
|
|
98
|
-
nextSibling: null,
|
|
99
|
-
parentElement: null,
|
|
100
|
-
restoredElement: null,
|
|
101
95
|
currentClasses: [],
|
|
102
96
|
currentStyles: {},
|
|
103
97
|
fontVerticalPadding: null,
|
|
@@ -200,15 +194,7 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
|
|
|
200
194
|
getTextAreaVueModel(state: PageBuilderState): string | null {
|
|
201
195
|
return state.textAreaVueModel
|
|
202
196
|
},
|
|
203
|
-
|
|
204
|
-
return state.nextSibling
|
|
205
|
-
},
|
|
206
|
-
getParentElement(state: PageBuilderState): HTMLElement | null {
|
|
207
|
-
return state.parentElement
|
|
208
|
-
},
|
|
209
|
-
getRestoredElement(state: PageBuilderState): string | null {
|
|
210
|
-
return state.restoredElement
|
|
211
|
-
},
|
|
197
|
+
|
|
212
198
|
getCurrentClasses(state: PageBuilderState): string[] {
|
|
213
199
|
return state.currentClasses
|
|
214
200
|
},
|
|
@@ -355,15 +341,7 @@ export const usePageBuilderStateStore = defineStore('pageBuilderState', {
|
|
|
355
341
|
setTextAreaVueModel(payload: string | null): void {
|
|
356
342
|
this.textAreaVueModel = payload
|
|
357
343
|
},
|
|
358
|
-
|
|
359
|
-
this.nextSibling = payload
|
|
360
|
-
},
|
|
361
|
-
setParentElement(payload: HTMLElement | null): void {
|
|
362
|
-
this.parentElement = payload
|
|
363
|
-
},
|
|
364
|
-
setRestoredElement(payload: string | null): void {
|
|
365
|
-
this.restoredElement = payload
|
|
366
|
-
},
|
|
344
|
+
|
|
367
345
|
setClass(payload: string): void {
|
|
368
346
|
this.currentClasses = [...this.currentClasses, payload]
|
|
369
347
|
},
|
|
@@ -24,63 +24,47 @@ const translatedComponents = computed(() => {
|
|
|
24
24
|
})
|
|
25
25
|
})
|
|
26
26
|
|
|
27
|
-
const { components, pageSettings } = pageBuilderService.parsePageBuilderHTML(
|
|
28
|
-
'<div id="pagebuilder" class="" style="">' +
|
|
29
|
-
translatedComponents.value.map((c) => c.html_code).join('\n') +
|
|
30
|
-
'</div>',
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
const configPageBuilder = {
|
|
34
|
-
userForPageBuilder: {
|
|
35
|
-
name: 'Jane Doe',
|
|
36
|
-
image: '/jane_doe.jpg',
|
|
37
|
-
},
|
|
38
|
-
updateOrCreate: {
|
|
39
|
-
formType: 'update',
|
|
40
|
-
formName: 'collection',
|
|
41
|
-
},
|
|
42
|
-
pageBuilderLogo: {
|
|
43
|
-
src: '/logo/mybuilder_new_lowercase.svg',
|
|
44
|
-
},
|
|
45
|
-
resourceData: {
|
|
46
|
-
title: 'Demo Article',
|
|
47
|
-
id: 1,
|
|
48
|
-
},
|
|
49
|
-
userSettings: {
|
|
50
|
-
theme: 'light',
|
|
51
|
-
language: {
|
|
52
|
-
default: 'en',
|
|
53
|
-
enable: ['en', 'zh-Hans', 'fr', 'ja', 'ru', 'es', 'pt', 'de', 'ar', 'hi'],
|
|
54
|
-
disableLanguageDropDown: false,
|
|
55
|
-
},
|
|
56
|
-
autoSave: true,
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
settings: {
|
|
60
|
-
brandColor: '#DB93B0',
|
|
61
|
-
},
|
|
62
|
-
pageSettings: pageSettings,
|
|
63
|
-
} as const
|
|
64
|
-
|
|
65
27
|
watch(currentTranslations, async () => {
|
|
66
|
-
const { components: newComponents, pageSettings:
|
|
28
|
+
const { components: newComponents, pageSettings: pageSettings } =
|
|
67
29
|
pageBuilderService.parsePageBuilderHTML(
|
|
68
30
|
'<div id="pagebuilder" class="" style="">' +
|
|
69
31
|
translatedComponents.value.map((c) => c.html_code).join('\n') +
|
|
70
32
|
'</div>',
|
|
71
33
|
)
|
|
72
34
|
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
35
|
+
const configPageBuilder = {
|
|
36
|
+
userForPageBuilder: {
|
|
37
|
+
name: 'Jane Doe',
|
|
38
|
+
image: '/jane_doe.jpg',
|
|
39
|
+
},
|
|
40
|
+
updateOrCreate: {
|
|
41
|
+
formType: 'update',
|
|
42
|
+
formName: 'collection',
|
|
43
|
+
},
|
|
44
|
+
pageBuilderLogo: {
|
|
45
|
+
src: '/logo/mybuilder_new_lowercase.svg',
|
|
46
|
+
},
|
|
47
|
+
resourceData: {
|
|
48
|
+
title: 'Demo Article',
|
|
49
|
+
id: 1,
|
|
50
|
+
},
|
|
51
|
+
userSettings: {
|
|
52
|
+
theme: 'light',
|
|
53
|
+
language: {
|
|
54
|
+
default: 'en',
|
|
55
|
+
enable: ['en', 'zh-Hans', 'fr', 'ja', 'ru', 'es', 'pt', 'de', 'ar', 'hi'],
|
|
56
|
+
disableLanguageDropDown: false,
|
|
57
|
+
},
|
|
58
|
+
autoSave: true,
|
|
59
|
+
},
|
|
77
60
|
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
settings: {
|
|
62
|
+
brandColor: '#DB93B0',
|
|
63
|
+
},
|
|
64
|
+
pageSettings: pageSettings,
|
|
65
|
+
} as const
|
|
80
66
|
|
|
81
|
-
|
|
82
|
-
const result = await pageBuilderService.startBuilder(configPageBuilder, components)
|
|
83
|
-
console.log('Page Builder result for message, status, or error::', result)
|
|
67
|
+
await pageBuilderService.startBuilder(configPageBuilder, newComponents)
|
|
84
68
|
})
|
|
85
69
|
</script>
|
|
86
70
|
|