@myissue/vue-website-page-builder 3.2.77 → 3.2.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/vue-website-page-builder.js +8022 -7939
- package/dist/vue-website-page-builder.umd.cjs +50 -50
- package/package.json +1 -1
- package/src/Components/Modals/DynamicModalBuilder.vue +18 -1
- package/src/DemoComponents/HomeSection.vue +1 -1
- package/src/PageBuilder/PageBuilder.vue +68 -2
- package/src/composables/PageBuilderClass.ts +66 -0
package/package.json
CHANGED
|
@@ -17,6 +17,11 @@ defineProps({
|
|
|
17
17
|
default: false,
|
|
18
18
|
required: false,
|
|
19
19
|
},
|
|
20
|
+
isLoading: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: false,
|
|
23
|
+
required: false,
|
|
24
|
+
},
|
|
20
25
|
disabledWhichButton: {
|
|
21
26
|
type: String,
|
|
22
27
|
default: '',
|
|
@@ -97,7 +102,7 @@ const thirdButtonBuilder = function () {
|
|
|
97
102
|
</div>
|
|
98
103
|
</div>
|
|
99
104
|
|
|
100
|
-
<template v-if="simpleModal !== true">
|
|
105
|
+
<template v-if="simpleModal !== true && !isLoading">
|
|
101
106
|
<div class="py-4 flex sm:justify-end justify-center border-t border-gray-200 mt-4">
|
|
102
107
|
<slot name="footer" />
|
|
103
108
|
<div
|
|
@@ -362,6 +367,18 @@ const thirdButtonBuilder = function () {
|
|
|
362
367
|
</div>
|
|
363
368
|
</div>
|
|
364
369
|
</template>
|
|
370
|
+
<template v-if="isLoading">
|
|
371
|
+
<div class="flex items-center my-2 py-4 px-2 justify-end">
|
|
372
|
+
<div
|
|
373
|
+
class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]"
|
|
374
|
+
>
|
|
375
|
+
<span
|
|
376
|
+
class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
|
|
377
|
+
>Loading...</span
|
|
378
|
+
>
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
</template>
|
|
365
382
|
</ModalBuilder>
|
|
366
383
|
</template>
|
|
367
384
|
|
|
@@ -12,12 +12,13 @@ import { updateOrCreateIsFalsy } from '../helpers/passedPageBuilderConfig'
|
|
|
12
12
|
import ToolbarOption from '../Components/PageBuilder/ToolbarOption/ToolbarOption.vue'
|
|
13
13
|
import { delay } from '../composables/delay'
|
|
14
14
|
import { useDebounce } from '../composables/useDebounce.ts'
|
|
15
|
+
import DynamicModalBuilder from '../Components/Modals/DynamicModalBuilder.vue'
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Props for PageBuilder component
|
|
18
19
|
* @typedef {Object} Props
|
|
19
20
|
* @property {Object|null} CustomMediaLibraryComponent - Custom media component
|
|
20
|
-
* @property {Object|null} CustomBuilderComponents - Custom
|
|
21
|
+
* @property {Object|null} CustomBuilderComponents - Custom component
|
|
21
22
|
* @property {Object} configPageBuilder - Configuration object containing:
|
|
22
23
|
*/
|
|
23
24
|
const props = defineProps({
|
|
@@ -192,6 +193,47 @@ watch(
|
|
|
192
193
|
},
|
|
193
194
|
{ immediate: true },
|
|
194
195
|
)
|
|
196
|
+
const gridColumnModalResumeEditing = ref(Number(1))
|
|
197
|
+
const typeModal = ref('')
|
|
198
|
+
const showModalResumeEditing = ref(false)
|
|
199
|
+
const titleModalResumeEditing = ref('')
|
|
200
|
+
const descriptionModalResumeEditing = ref('')
|
|
201
|
+
const firstButtonResumeEditing = ref('')
|
|
202
|
+
const secondButtonResumeEditing = ref(null)
|
|
203
|
+
const thirdButtonResumeEditing = ref(null)
|
|
204
|
+
const firstModalButtonResumeEditingFunction = ref(null)
|
|
205
|
+
const secondModalButtonResumeEditingFunction = ref(null)
|
|
206
|
+
const thirdModalButtonResumeEditingFunction = ref(null)
|
|
207
|
+
|
|
208
|
+
const isLoadingResumeEditing = ref(null)
|
|
209
|
+
|
|
210
|
+
const handlerRumeEditingForUpdate = async function () {
|
|
211
|
+
await pageBuilderClass.clearHtmlSelection()
|
|
212
|
+
|
|
213
|
+
typeModal.value = 'default'
|
|
214
|
+
titleModalResumeEditing.value = 'Continue Your Work?'
|
|
215
|
+
descriptionModalResumeEditing.value =
|
|
216
|
+
'We noticed you have some changes that weren’t saved last time. Would you like to pick up where you left off, or use the version that’s currently saved?'
|
|
217
|
+
firstButtonResumeEditing.value = 'Use Saved Version'
|
|
218
|
+
secondButtonResumeEditing.value = null
|
|
219
|
+
thirdButtonResumeEditing.value = 'Continue Where I Left Off'
|
|
220
|
+
showModalResumeEditing.value = true
|
|
221
|
+
|
|
222
|
+
firstModalButtonResumeEditingFunction.value = function () {
|
|
223
|
+
showModalResumeEditing.value = false
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
secondModalButtonResumeEditingFunction.value = function () {}
|
|
227
|
+
thirdModalButtonResumeEditingFunction.value = async function () {
|
|
228
|
+
isLoadingResumeEditing.value = true
|
|
229
|
+
await delay(1000)
|
|
230
|
+
await pageBuilderClass.resumeEditingForUpdate()
|
|
231
|
+
isLoadingResumeEditing.value = false
|
|
232
|
+
showModalResumeEditing.value = false
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// end modal
|
|
236
|
+
}
|
|
195
237
|
|
|
196
238
|
onMounted(async () => {
|
|
197
239
|
const config = getConfigPageBuilder.value
|
|
@@ -204,6 +246,10 @@ onMounted(async () => {
|
|
|
204
246
|
await pageBuilderClass.clearHtmlSelection()
|
|
205
247
|
|
|
206
248
|
await pageBuilderClass.setEventListenersForElements()
|
|
249
|
+
|
|
250
|
+
if (await pageBuilderClass.hasLocalDraftForUpdate()) {
|
|
251
|
+
handlerRumeEditingForUpdate()
|
|
252
|
+
}
|
|
207
253
|
})
|
|
208
254
|
</script>
|
|
209
255
|
|
|
@@ -266,6 +312,24 @@ onMounted(async () => {
|
|
|
266
312
|
<Preview></Preview>
|
|
267
313
|
</ModalBuilder>
|
|
268
314
|
|
|
315
|
+
<DynamicModalBuilder
|
|
316
|
+
:showDynamicModalBuilder="showModalResumeEditing"
|
|
317
|
+
:isLoading="isLoadingResumeEditing"
|
|
318
|
+
:type="typeModal"
|
|
319
|
+
:gridColumnAmount="gridColumnModalResumeEditing"
|
|
320
|
+
:title="titleModalResumeEditing"
|
|
321
|
+
:description="descriptionModalResumeEditing"
|
|
322
|
+
:firstButtonText="firstButtonResumeEditing"
|
|
323
|
+
:secondButtonText="secondButtonResumeEditing"
|
|
324
|
+
:thirdButtonText="thirdButtonResumeEditing"
|
|
325
|
+
@firstModalButtonFunctionDynamicModalBuilder="firstModalButtonResumeEditingFunction"
|
|
326
|
+
@secondModalButtonFunctionDynamicModalBuilder="secondModalButtonResumeEditingFunction"
|
|
327
|
+
@thirdModalButtonFunctionDynamicModalBuilder="thirdModalButtonResumeEditingFunction"
|
|
328
|
+
>
|
|
329
|
+
<header></header>
|
|
330
|
+
<main></main>
|
|
331
|
+
</DynamicModalBuilder>
|
|
332
|
+
|
|
269
333
|
<div>
|
|
270
334
|
<div class="relative h-full flex pb-2 gap-2">
|
|
271
335
|
<div
|
|
@@ -306,7 +370,7 @@ onMounted(async () => {
|
|
|
306
370
|
class="flex myPrimaryGap items-center pt-4 pb-2 pl-2 h-24 w-full min-w-36"
|
|
307
371
|
>
|
|
308
372
|
<button
|
|
309
|
-
class="
|
|
373
|
+
class="mySecondaryButton h-6 flex gap-2"
|
|
310
374
|
@click.stop="
|
|
311
375
|
async () => {
|
|
312
376
|
await pageBuilderClass.clearHtmlSelection()
|
|
@@ -335,6 +399,8 @@ onMounted(async () => {
|
|
|
335
399
|
</div>
|
|
336
400
|
<div>Save</div>
|
|
337
401
|
</button>
|
|
402
|
+
|
|
403
|
+
<!-- Continue editing # end -->
|
|
338
404
|
</div>
|
|
339
405
|
|
|
340
406
|
<div
|
|
@@ -46,10 +46,13 @@ class PageBuilderClass {
|
|
|
46
46
|
private NoneListernesTags: string[]
|
|
47
47
|
private delay: (ms?: number) => Promise<void>
|
|
48
48
|
private observer?: MutationObserverType
|
|
49
|
+
private hasStartedEditing: boolean = false
|
|
49
50
|
|
|
50
51
|
constructor(pageBuilderStateStore: ReturnType<typeof usePageBuilderStateStore>) {
|
|
51
52
|
this.nextTick = nextTick()
|
|
52
53
|
|
|
54
|
+
this.hasStartedEditing = false
|
|
55
|
+
|
|
53
56
|
this.containsPagebuilder = document.querySelector('#contains-pagebuilder')
|
|
54
57
|
|
|
55
58
|
this.pageBuilderStateStore = pageBuilderStateStore
|
|
@@ -275,6 +278,7 @@ class PageBuilderClass {
|
|
|
275
278
|
}
|
|
276
279
|
|
|
277
280
|
handleAutoSave = async () => {
|
|
281
|
+
this.startEditing()
|
|
278
282
|
const passedConfig = this.pageBuilderStateStore.getConfigPageBuilder
|
|
279
283
|
|
|
280
284
|
// Check if config is set
|
|
@@ -312,6 +316,7 @@ class PageBuilderClass {
|
|
|
312
316
|
}
|
|
313
317
|
|
|
314
318
|
handleManualSave = async () => {
|
|
319
|
+
this.startEditing()
|
|
315
320
|
const passedConfig = this.pageBuilderStateStore.getConfigPageBuilder
|
|
316
321
|
|
|
317
322
|
// Check if config is set
|
|
@@ -1215,6 +1220,66 @@ class PageBuilderClass {
|
|
|
1215
1220
|
}
|
|
1216
1221
|
}
|
|
1217
1222
|
|
|
1223
|
+
async hasLocalDraftForUpdate(): Promise<boolean> {
|
|
1224
|
+
if (this.hasStartedEditing) return false
|
|
1225
|
+
|
|
1226
|
+
if (
|
|
1227
|
+
this.pageBuilderStateStore.getConfigPageBuilder &&
|
|
1228
|
+
this.pageBuilderStateStore.getConfigPageBuilder.updateOrCreate &&
|
|
1229
|
+
typeof this.pageBuilderStateStore.getConfigPageBuilder.updateOrCreate.formType === 'string' &&
|
|
1230
|
+
this.pageBuilderStateStore.getConfigPageBuilder.updateOrCreate.formType === 'update'
|
|
1231
|
+
) {
|
|
1232
|
+
const key = this.getLocalStorageItemName.value
|
|
1233
|
+
if (typeof key === 'string') {
|
|
1234
|
+
const draft = localStorage.getItem(key)
|
|
1235
|
+
if (draft) {
|
|
1236
|
+
try {
|
|
1237
|
+
await this.delay(1000)
|
|
1238
|
+
const draftParsed = JSON.parse(draft)
|
|
1239
|
+
const dbComponents = this.getComponents.value
|
|
1240
|
+
return JSON.stringify(draftParsed.components) !== JSON.stringify(dbComponents)
|
|
1241
|
+
} catch (e) {
|
|
1242
|
+
return false
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return false
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// Call this when the user starts editing (e.g., on first change or when resuming a draft)
|
|
1251
|
+
startEditing() {
|
|
1252
|
+
this.hasStartedEditing = true
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
async resumeEditingForUpdate() {
|
|
1256
|
+
if (
|
|
1257
|
+
this.pageBuilderStateStore.getConfigPageBuilder &&
|
|
1258
|
+
this.pageBuilderStateStore.getConfigPageBuilder.updateOrCreate &&
|
|
1259
|
+
typeof this.pageBuilderStateStore.getConfigPageBuilder.updateOrCreate.formType === 'string' &&
|
|
1260
|
+
this.pageBuilderStateStore.getConfigPageBuilder.updateOrCreate.formType === 'update'
|
|
1261
|
+
) {
|
|
1262
|
+
const key = this.getLocalStorageItemName.value
|
|
1263
|
+
if (typeof key === 'string') {
|
|
1264
|
+
const savedCurrentDesign = localStorage.getItem(key)
|
|
1265
|
+
if (savedCurrentDesign) {
|
|
1266
|
+
try {
|
|
1267
|
+
const parsed = JSON.parse(savedCurrentDesign)
|
|
1268
|
+
if (parsed && Array.isArray(parsed.components)) {
|
|
1269
|
+
this.pageBuilderStateStore.setComponents(parsed.components)
|
|
1270
|
+
localStorage.removeItem(key)
|
|
1271
|
+
await nextTick()
|
|
1272
|
+
await this.setEventListenersForElements()
|
|
1273
|
+
await this.handleAutoSave()
|
|
1274
|
+
}
|
|
1275
|
+
} catch (e) {
|
|
1276
|
+
console.error('Failed to parse local draft:', e)
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1218
1283
|
getStorageItemNameForResource(): string | null {
|
|
1219
1284
|
return this.getLocalStorageItemName.value
|
|
1220
1285
|
}
|
|
@@ -1223,6 +1288,7 @@ class PageBuilderClass {
|
|
|
1223
1288
|
|
|
1224
1289
|
if (
|
|
1225
1290
|
this.getLocalStorageItemName.value &&
|
|
1291
|
+
typeof this.getLocalStorageItemName.value === 'string' &&
|
|
1226
1292
|
localStorage.getItem(this.getLocalStorageItemName.value)
|
|
1227
1293
|
) {
|
|
1228
1294
|
const savedCurrentDesign = localStorage.getItem(this.getLocalStorageItemName.value)
|