@mixd-id/web-scaffold 0.1.230406146 → 0.1.230406147
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 +1 -1
- package/src/components/Alert.vue +0 -1
- package/src/components/Toast.vue +57 -37
- package/src/components/TreeView.vue +23 -16
- package/src/components/TreeViewItem.vue +53 -45
- package/src/utils/helpers.mjs +51 -14
- package/src/widgets/ReviewSetting.vue +46 -44
- package/src/widgets/WebPageBuilder.vue +192 -79
package/package.json
CHANGED
package/src/components/Alert.vue
CHANGED
package/src/components/Toast.vue
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
|
-
<Teleport to=".
|
|
4
|
-
<Transition name="
|
|
5
|
-
<div v-if="
|
|
6
|
-
<slot
|
|
3
|
+
<Teleport to=".YWxl">
|
|
4
|
+
<Transition name="YWxl">
|
|
5
|
+
<div v-if="isOpen" :class="$style.toast">
|
|
6
|
+
<slot>
|
|
7
|
+
<div class="p-6">
|
|
8
|
+
<div ref="item" :class="$style.item" @mouseover="onMouseOver" @mouseout="onMouseOut">
|
|
9
|
+
<div></div>
|
|
10
|
+
<div class="flex-1 break-all whitespace-pre-line">{{ text }}</div>
|
|
11
|
+
<div>
|
|
12
|
+
<button type="button" class="text-sm" @click="close">Dismiss</button>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</slot>
|
|
7
17
|
</div>
|
|
8
18
|
</Transition>
|
|
9
19
|
</Teleport>
|
|
@@ -14,48 +24,54 @@
|
|
|
14
24
|
|
|
15
25
|
export default{
|
|
16
26
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
state: [ Boolean, Number, String ],
|
|
20
|
-
|
|
21
|
-
dismissAfter: {
|
|
22
|
-
type: [ Number, String ],
|
|
23
|
-
default: 3000
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
emits: [ 'dismiss' ],
|
|
27
|
+
methods: {
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
/**
|
|
30
|
+
* @param obj
|
|
31
|
+
* @param obj.text {string} - The text of the toast.
|
|
32
|
+
*/
|
|
33
|
+
open(obj){
|
|
34
|
+
this.toast = obj
|
|
35
|
+
this.isOpen = true
|
|
36
|
+
this.intervalId = window.setTimeout(() => this.close(), 3000)
|
|
37
|
+
},
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
close(){
|
|
40
|
+
this.isOpen = false
|
|
41
|
+
},
|
|
37
42
|
|
|
38
43
|
onMouseOver(){
|
|
39
44
|
if(this.intervalId){
|
|
40
45
|
window.clearTimeout(this.intervalId)
|
|
41
46
|
this.intervalId = null
|
|
42
47
|
}
|
|
43
|
-
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
onMouseOut(e){
|
|
51
|
+
this.intervalId = window.setTimeout(() => this.close(), 3000)
|
|
52
|
+
},
|
|
44
53
|
|
|
45
54
|
},
|
|
46
55
|
|
|
47
|
-
|
|
56
|
+
computed: {
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
if(
|
|
51
|
-
this.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}, parseInt(this.dismissAfter))
|
|
58
|
+
text(){
|
|
59
|
+
if(this.toast.text){
|
|
60
|
+
return this.toast.text
|
|
61
|
+
}
|
|
62
|
+
else if(this.toast.message){
|
|
63
|
+
return this.toast.message
|
|
56
64
|
}
|
|
57
65
|
}
|
|
58
66
|
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
data(){
|
|
70
|
+
return {
|
|
71
|
+
intervalId: null,
|
|
72
|
+
isOpen: false,
|
|
73
|
+
toast: {},
|
|
74
|
+
}
|
|
59
75
|
}
|
|
60
76
|
|
|
61
77
|
}
|
|
@@ -64,18 +80,18 @@ export default{
|
|
|
64
80
|
|
|
65
81
|
<style>
|
|
66
82
|
|
|
67
|
-
.
|
|
83
|
+
.YWxl{
|
|
68
84
|
@apply fixed top-0 left-0 right-0;
|
|
69
85
|
z-index: 61;
|
|
70
86
|
}
|
|
71
87
|
|
|
72
|
-
.
|
|
73
|
-
.
|
|
88
|
+
.YWxl-enter-active,
|
|
89
|
+
.YWxl-leave-active {
|
|
74
90
|
transition: all 300ms cubic-bezier(0.25, 1, 0.5, 1);
|
|
75
91
|
}
|
|
76
92
|
|
|
77
|
-
.
|
|
78
|
-
.
|
|
93
|
+
.YWxl-enter-from,
|
|
94
|
+
.YWxl-leave-to {
|
|
79
95
|
opacity: 0;
|
|
80
96
|
transform: translate3d(0, -10vh, 0);
|
|
81
97
|
}
|
|
@@ -85,7 +101,11 @@ export default{
|
|
|
85
101
|
<style module>
|
|
86
102
|
|
|
87
103
|
.toast{
|
|
88
|
-
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.item{
|
|
107
|
+
@apply flex p-3 gap-4;
|
|
108
|
+
@apply max-w-[90vw] md:max-w-[480px] bg-base-500 mx-auto rounded-xl border-[1px] border-text-100;
|
|
89
109
|
@apply min-h-[var(--h-cp)];
|
|
90
110
|
z-index: 61;
|
|
91
111
|
}
|
|
@@ -8,10 +8,8 @@
|
|
|
8
8
|
@moveup="moveUp(item)"
|
|
9
9
|
@movedown="moveDown(item)"
|
|
10
10
|
@change="$emit('change')"
|
|
11
|
-
@remove="confirm(
|
|
12
|
-
@add="(items) => $emit('add', items)"
|
|
13
|
-
@paste.stop.prevent="(e) => paste(e, item)"
|
|
14
|
-
@item-paste="(p1, p2, p3) => $emit('item-paste', p1, p2, p3)">
|
|
11
|
+
@remove="confirm({ title:$t('Remove this item?'), onConfirm: () => { modelValue.splice(index, 1);$emit('change') }})"
|
|
12
|
+
@add="(items) => $emit('add', items)">
|
|
15
13
|
<template #default="{ item }">
|
|
16
14
|
<slot :item="item"></slot>
|
|
17
15
|
</template>
|
|
@@ -23,14 +21,15 @@
|
|
|
23
21
|
<script>
|
|
24
22
|
|
|
25
23
|
import TreeViewItem from "./TreeViewItem.vue";
|
|
24
|
+
import {copyToClipboard, getClipboardData} from "../utils/helpers.mjs";
|
|
26
25
|
|
|
27
26
|
export default{
|
|
28
27
|
|
|
29
28
|
components: {TreeViewItem},
|
|
30
29
|
|
|
31
|
-
emits: [ 'add', 'change', '
|
|
30
|
+
emits: [ 'add', 'change', 'paste' ],
|
|
32
31
|
|
|
33
|
-
inject: [ 'confirm' ],
|
|
32
|
+
inject: [ 'confirm', 'toast' ],
|
|
34
33
|
|
|
35
34
|
props: {
|
|
36
35
|
|
|
@@ -42,17 +41,21 @@ export default{
|
|
|
42
41
|
|
|
43
42
|
methods: {
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
try{
|
|
50
|
-
const newItem = JSON.parse(pastedText)
|
|
51
|
-
this.$emit('item-paste', this.modelValue, subItem, newItem)
|
|
44
|
+
copy(){
|
|
45
|
+
if(this.selectedItem){
|
|
46
|
+
copyToClipboard(JSON.stringify(this.selectedItem))
|
|
47
|
+
.then(() => this.toast('Copied to clipboard'))
|
|
52
48
|
}
|
|
53
|
-
|
|
49
|
+
},
|
|
54
50
|
|
|
55
|
-
|
|
51
|
+
paste(){
|
|
52
|
+
getClipboardData().then(text => {
|
|
53
|
+
try{
|
|
54
|
+
const item = JSON.parse(text)
|
|
55
|
+
this.$emit('paste', item)
|
|
56
|
+
}
|
|
57
|
+
catch(e){}
|
|
58
|
+
})
|
|
56
59
|
},
|
|
57
60
|
|
|
58
61
|
moveDown(item){
|
|
@@ -73,8 +76,12 @@ export default{
|
|
|
73
76
|
|
|
74
77
|
add(){
|
|
75
78
|
this.$emit('add', this.modelValue)
|
|
76
|
-
}
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
},
|
|
77
82
|
|
|
83
|
+
mounted() {
|
|
84
|
+
window.addEventListener('keydown', this.onKeyUp)
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div @
|
|
3
|
-
@mouseover.stop="hoverMouseOver"
|
|
2
|
+
<div @mousemove.stop="hoverMouseOver"
|
|
4
3
|
@mouseout.stop="hoverMouseOut">
|
|
5
4
|
<div ref="item" :class="itemClass"
|
|
6
5
|
@mousedown="mouseDown">
|
|
@@ -22,11 +21,9 @@
|
|
|
22
21
|
:selected-item="selectedItem"
|
|
23
22
|
@moveup="moveUp(subItem)"
|
|
24
23
|
@movedown="moveDown(subItem)"
|
|
25
|
-
@remove="confirm(
|
|
24
|
+
@remove="confirm({ title:$t('Remove this item?'), onConfirm: () => { item.items.splice(index, 1);$emit('change') }})"
|
|
26
25
|
@add="(items) => $emit('add', items)"
|
|
27
|
-
@change="$emit('change')"
|
|
28
|
-
@paste.stop.prevent="(e) => paste(e, subItem)"
|
|
29
|
-
@item-paste="(p1, p2, p3) => $emit('item-paste', p1, p2, p3)">
|
|
26
|
+
@change="$emit('change')">
|
|
30
27
|
<template #default="{ item }">
|
|
31
28
|
<slot :item="item"></slot>
|
|
32
29
|
</template>
|
|
@@ -51,7 +48,7 @@ let guide1 = null
|
|
|
51
48
|
|
|
52
49
|
export default{
|
|
53
50
|
|
|
54
|
-
emits: [ 'add', 'change', 'moveup', 'movedown', 'remove'
|
|
51
|
+
emits: [ 'add', 'change', 'moveup', 'movedown', 'remove' ],
|
|
55
52
|
|
|
56
53
|
inject: [ 'confirm', 'toast' ],
|
|
57
54
|
|
|
@@ -70,24 +67,6 @@ export default{
|
|
|
70
67
|
|
|
71
68
|
methods: {
|
|
72
69
|
|
|
73
|
-
copy(){
|
|
74
|
-
copyToClipboard(JSON.stringify(this.item))
|
|
75
|
-
this.toast(this.item.type + ' copied')
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
paste(event, subItem){
|
|
79
|
-
const clipboardData = event.clipboardData || window.clipboardData;
|
|
80
|
-
const pastedText = clipboardData.getData('text');
|
|
81
|
-
|
|
82
|
-
try{
|
|
83
|
-
const newItem = JSON.parse(pastedText)
|
|
84
|
-
this.$emit('item-paste', this.item.items, subItem, newItem)
|
|
85
|
-
}
|
|
86
|
-
catch(e){
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
|
|
91
70
|
moveDown(item){
|
|
92
71
|
const idx = this.item.items.indexOf(item)
|
|
93
72
|
if(idx < this.item.items.length - 1){
|
|
@@ -142,31 +121,45 @@ export default{
|
|
|
142
121
|
window.removeEventListener('mousemove', mouseMove)
|
|
143
122
|
window.removeEventListener('mouseup', mouseUp)
|
|
144
123
|
|
|
145
|
-
if(guide1 && guide1.parentNode){
|
|
146
|
-
guide1.parentNode.removeChild(guide1)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
124
|
if(dragged && dragged.parent && dragged.targetParent){
|
|
150
125
|
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
/*if(e.clientY > dragged.startY){
|
|
155
|
-
targetIdx++
|
|
156
|
-
}*/
|
|
157
|
-
//console.log(e.clientY, dragged.startY, e.clientY > dragged.startY ? 'after' : 'before', targetIdx, startIdx)
|
|
158
|
-
|
|
159
|
-
if(targetIdx >= -1 && (targetIdx !== startIdx || dragged.parent !== dragged.targetParent)){
|
|
126
|
+
const startIdx = dragged.targetParent.indexOf(dragged.item)
|
|
127
|
+
const targetIdx = dragged.targetParent.indexOf(dragged.target)
|
|
128
|
+
const moveDirection = e.clientY < dragged.startY ? -1 : 1
|
|
160
129
|
|
|
130
|
+
let destIdx
|
|
131
|
+
if(moveDirection === -1){
|
|
161
132
|
if(dragged.parent === dragged.targetParent){
|
|
162
|
-
dragged.
|
|
133
|
+
destIdx = dragged.dragArea === -1 ? targetIdx : targetIdx + 1
|
|
163
134
|
}
|
|
164
135
|
else{
|
|
165
|
-
dragged.
|
|
136
|
+
destIdx = dragged.dragArea === -1 ? targetIdx : targetIdx + 1
|
|
166
137
|
}
|
|
167
|
-
|
|
168
|
-
this.$emit('change')
|
|
169
138
|
}
|
|
139
|
+
else{
|
|
140
|
+
if(dragged.parent === dragged.targetParent) {
|
|
141
|
+
destIdx = dragged.dragArea === -1 ? targetIdx - 1 : targetIdx
|
|
142
|
+
}
|
|
143
|
+
else{
|
|
144
|
+
destIdx = dragged.dragArea === -1 ? targetIdx : targetIdx + 1
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/*console.log('#1', {
|
|
149
|
+
startIdx,
|
|
150
|
+
targetIdx,
|
|
151
|
+
destIdx,
|
|
152
|
+
moveDirection,
|
|
153
|
+
dragArea: dragged.dragArea
|
|
154
|
+
})*/
|
|
155
|
+
|
|
156
|
+
dragged.targetParent.splice(destIdx, 0, dragged.parent.splice(startIdx, 1)[0])
|
|
157
|
+
|
|
158
|
+
this.$emit('change')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if(guide1 && guide1.parentNode){
|
|
162
|
+
guide1.parentNode.removeChild(guide1)
|
|
170
163
|
}
|
|
171
164
|
|
|
172
165
|
dragged = null
|
|
@@ -179,16 +172,30 @@ export default{
|
|
|
179
172
|
hoverMouseOver(e){
|
|
180
173
|
if(!dragged) return
|
|
181
174
|
|
|
175
|
+
if(this.item === dragged.item) return
|
|
176
|
+
|
|
182
177
|
if(!guide1){
|
|
183
178
|
guide1 = this.createGuide()
|
|
184
179
|
}
|
|
185
180
|
|
|
181
|
+
if(dragged.target !== this.item){
|
|
182
|
+
const rect = this.$refs.item.getBoundingClientRect()
|
|
183
|
+
dragged.centerY = rect.y + (rect.height / 2)
|
|
184
|
+
//console.log('#BS', dragged.centerY, this.item.name)
|
|
185
|
+
}
|
|
186
186
|
dragged.target = this.item
|
|
187
187
|
dragged.targetParent = this.parent
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
if(e.clientY < dragged.centerY){
|
|
190
|
+
this.$el.insertBefore(guide1, this.$el.firstElementChild)
|
|
191
|
+
dragged.dragArea = -1
|
|
192
|
+
}
|
|
193
|
+
else{
|
|
194
|
+
this.$el.insertBefore(guide1, null)
|
|
195
|
+
dragged.dragArea = 1
|
|
196
|
+
}
|
|
190
197
|
|
|
191
|
-
|
|
198
|
+
//console.log('centerY', dragged.dragArea, e.clientY, dragged.centerY)
|
|
192
199
|
},
|
|
193
200
|
|
|
194
201
|
hoverMouseOut(e){
|
|
@@ -222,7 +229,8 @@ export default{
|
|
|
222
229
|
|
|
223
230
|
data(){
|
|
224
231
|
return {
|
|
225
|
-
childCollapsed: false
|
|
232
|
+
childCollapsed: false,
|
|
233
|
+
hvm: null
|
|
226
234
|
}
|
|
227
235
|
}
|
|
228
236
|
|
package/src/utils/helpers.mjs
CHANGED
|
@@ -179,27 +179,49 @@ const _applyClass = function(props, defaultClass = {}){
|
|
|
179
179
|
|
|
180
180
|
const fallbackCopyTextToClipboard = function(obj){
|
|
181
181
|
return new Promise((resolve, reject) => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
try {
|
|
182
|
+
try{
|
|
183
|
+
var textArea = document.createElement("textarea");
|
|
184
|
+
textArea.value = obj;
|
|
185
|
+
textArea.style.left = "-100vw";
|
|
186
|
+
textArea.style.position = "fixed";
|
|
187
|
+
document.body.appendChild(textArea);
|
|
188
|
+
textArea.focus();
|
|
189
|
+
textArea.select();
|
|
190
|
+
|
|
192
191
|
document.execCommand('copy')
|
|
193
192
|
document.body.removeChild(textArea);
|
|
193
|
+
|
|
194
194
|
resolve()
|
|
195
|
-
}
|
|
196
|
-
|
|
195
|
+
}
|
|
196
|
+
catch(e){
|
|
197
|
+
reject(e)
|
|
197
198
|
}
|
|
198
199
|
})
|
|
199
200
|
}
|
|
200
201
|
|
|
201
|
-
const
|
|
202
|
+
const fallbackGetClipboardData = function(obj){
|
|
203
|
+
return new Promise((resolve, reject) => {
|
|
204
|
+
try{
|
|
205
|
+
var textArea = document.createElement("textarea");
|
|
206
|
+
textArea.style.left = "-100vw";
|
|
207
|
+
textArea.style.position = "fixed";
|
|
208
|
+
document.body.appendChild(textArea);
|
|
209
|
+
textArea.focus();
|
|
210
|
+
document.execCommand('paste');
|
|
211
|
+
|
|
212
|
+
window.setTimeout(() => {
|
|
213
|
+
const text = textArea.value;
|
|
214
|
+
document.body.removeChild(textArea);
|
|
215
|
+
resolve(text)
|
|
216
|
+
}, 100)
|
|
217
|
+
}
|
|
218
|
+
catch(e){
|
|
219
|
+
reject(e)
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
}
|
|
202
223
|
|
|
224
|
+
const copyToClipboard = function(obj){
|
|
203
225
|
if (!navigator.clipboard) {
|
|
204
226
|
return fallbackCopyTextToClipboard(obj);
|
|
205
227
|
}
|
|
@@ -213,6 +235,20 @@ const copyToClipboard = function(obj){
|
|
|
213
235
|
})
|
|
214
236
|
}
|
|
215
237
|
|
|
238
|
+
const getClipboardData = function(){
|
|
239
|
+
if (!navigator.clipboard) {
|
|
240
|
+
return fallbackGetClipboardData();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return new Promise((resolve, reject) => {
|
|
244
|
+
navigator.clipboard.readText().then((text) => {
|
|
245
|
+
resolve(text)
|
|
246
|
+
}, (err) => {
|
|
247
|
+
reject(err)
|
|
248
|
+
});
|
|
249
|
+
})
|
|
250
|
+
}
|
|
251
|
+
|
|
216
252
|
const getComponentUids = function(components, excepts = []){
|
|
217
253
|
|
|
218
254
|
const arr = []
|
|
@@ -249,8 +285,9 @@ export {
|
|
|
249
285
|
mediaPrefixes,
|
|
250
286
|
_applyClass,
|
|
251
287
|
copyToClipboard,
|
|
288
|
+
getClipboardData,
|
|
252
289
|
getComponentUids,
|
|
253
|
-
unPascalCase
|
|
290
|
+
unPascalCase,
|
|
254
291
|
}
|
|
255
292
|
|
|
256
293
|
function observeInit(){
|
|
@@ -1,58 +1,60 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="$style.comp">
|
|
3
3
|
|
|
4
|
-
<div class="flex flex-col gap-
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<div class="flex flex-col gap-1">
|
|
10
|
-
<label class="text-text-400">Mode</label>
|
|
11
|
-
<Dropdown v-model="item.props.mode" @change="item.props.items = { reviews:[] }">
|
|
12
|
-
<option value="">Static</option>
|
|
13
|
-
<option value="dynamic">Dynamic</option>
|
|
14
|
-
</Dropdown>
|
|
15
|
-
<Textbox v-if="item.props.mode === 'dynamic'"
|
|
16
|
-
placeholder="Var" v-model="item.props.src"
|
|
17
|
-
@blur="$emit('change')"
|
|
18
|
-
@keyup.enter="$emit('change')" />
|
|
19
|
-
</div>
|
|
4
|
+
<div v-if="viewType === ''" class="flex flex-col gap-4">
|
|
5
|
+
<div class="flex flex-col gap-1">
|
|
6
|
+
<label class="text-text-400">Title</label>
|
|
7
|
+
<Textbox v-model="item.props.title" maxlength="40" @keyup.enter="$emit('change')" placeholder="Title" />
|
|
8
|
+
</div>
|
|
20
9
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
10
|
+
<div class="flex flex-col gap-1">
|
|
11
|
+
<label class="text-text-400">Mode</label>
|
|
12
|
+
<Dropdown v-model="item.props.mode" @change="item.props.items = { reviews:[] }">
|
|
13
|
+
<option value="">Static</option>
|
|
14
|
+
<option value="dynamic">Dynamic</option>
|
|
15
|
+
</Dropdown>
|
|
16
|
+
<Textbox v-if="item.props.mode === 'dynamic'"
|
|
17
|
+
placeholder="Var" v-model="item.props.src"
|
|
18
|
+
@blur="$emit('change')"
|
|
19
|
+
@keyup.enter="$emit('change')" />
|
|
25
20
|
</div>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
|
|
22
|
+
<div v-if="item.props.mode !== 'dynamic'">
|
|
23
|
+
<div class="flex flex-row gap-2">
|
|
24
|
+
<label class="flex-1 text-text-400">Reviews</label>
|
|
25
|
+
<button type="button" class="text-primary" @click="$refs.reviewModal.open({ item:{} })">Add Review</button>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="mt-1">
|
|
28
|
+
<ListItem :items="items.reviews"
|
|
29
|
+
@reorder="(from, to) => { items.reviews.splice(to, 0, items.reviews.splice(from, 1)[0]); calcReview(); $emit('change') }">
|
|
30
|
+
<template v-slot="{ item, index }">
|
|
31
|
+
<div class="flex flex-row items-center gap-3 p-2">
|
|
32
|
+
<div data-reorder>
|
|
33
|
+
<svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496 288H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-128H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z"/></svg>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="flex-1 cursor-pointer" @click="$refs.reviewModal.open({ item, index })">
|
|
36
|
+
<p class="line-clamp-1">
|
|
36
37
|
<span class="w-[19px] aspect-square rounded-full bg-primary text-white inline-flex items-center justify-center">
|
|
37
38
|
{{ item.rate }}
|
|
38
39
|
</span>
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
{{ item.text }}
|
|
41
|
+
</p>
|
|
42
|
+
</div>
|
|
43
|
+
<button type="button" @click="confirm($t('Remove this item?'), '', () => { items.reviews.splice(index, 1); calcReview(); $emit('change') })">
|
|
44
|
+
<svg width="16" height="16" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
|
|
45
|
+
</button>
|
|
41
46
|
</div>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
</div>
|
|
46
|
-
</template>
|
|
47
|
-
</ListItem>
|
|
47
|
+
</template>
|
|
48
|
+
</ListItem>
|
|
49
|
+
</div>
|
|
48
50
|
</div>
|
|
49
|
-
</div>
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
<div class="flex flex-row gap-4 items-center">
|
|
53
|
+
<Checkbox v-model="item.props.enableGoogleReviewSD" @change="$emit('change')">
|
|
54
|
+
Enable google structured data
|
|
55
|
+
</Checkbox>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
56
58
|
|
|
57
59
|
|
|
58
60
|
<Modal ref="reviewModal" width="360" height="420">
|
|
@@ -160,8 +160,7 @@
|
|
|
160
160
|
v-model="layout.headers"
|
|
161
161
|
:selected-item="currentItem"
|
|
162
162
|
@add="openSelector"
|
|
163
|
-
@change="saveLayout"
|
|
164
|
-
@item-paste="onLayoutItemPaste">
|
|
163
|
+
@change="saveLayout">
|
|
165
164
|
<template #default="{ item }">
|
|
166
165
|
<component :is="`${(item ?? {}).type}Item`" :item="item"
|
|
167
166
|
@click="store.selectedComponent = [ item.uid ]"/>
|
|
@@ -178,8 +177,7 @@
|
|
|
178
177
|
v-model="layout.footers"
|
|
179
178
|
:selected-item="currentItem"
|
|
180
179
|
@add="openSelector"
|
|
181
|
-
@change="saveLayout"
|
|
182
|
-
@item-paste="onLayoutItemPaste">
|
|
180
|
+
@change="saveLayout">
|
|
183
181
|
<template #default="{ item }">
|
|
184
182
|
<component :is="`${(item ?? {}).type}Item`" :item="item"
|
|
185
183
|
@click="store.selectedComponent = [ item.uid ]"/>
|
|
@@ -196,14 +194,11 @@
|
|
|
196
194
|
v-model="page.components"
|
|
197
195
|
:selected-item="currentItem"
|
|
198
196
|
@add="openSelector"
|
|
199
|
-
@change="save"
|
|
200
|
-
@item-paste="onItemPaste">
|
|
201
|
-
|
|
197
|
+
@change="save">
|
|
202
198
|
<template #default="{ item }">
|
|
203
199
|
<component :is="`${(item ?? {}).type}Item`" :item="item"
|
|
204
200
|
@click="store.selectedComponent = [ item.uid ]"/>
|
|
205
201
|
</template>
|
|
206
|
-
|
|
207
202
|
</TreeView>
|
|
208
203
|
</div>
|
|
209
204
|
|
|
@@ -261,36 +256,41 @@
|
|
|
261
256
|
<div class="flex-1 flex flex-col bg-base-400">
|
|
262
257
|
|
|
263
258
|
<div class="p-3 sticky top-0 flex justify-center gap-4 bg-base-400 dark:bg-base-300 border-b-[1px] border-text-50">
|
|
264
|
-
<div class="flex-1 flex flex-row gap-
|
|
259
|
+
<div class="flex-1 flex flex-row gap-4 items-center">
|
|
265
260
|
<Dropdown v-model="store.zoomLevel" class="w-[75px]" @change="resize()">
|
|
266
|
-
<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
261
|
+
<optgroup label="Zoom Level">
|
|
262
|
+
<option value="fit">Fit</option>
|
|
263
|
+
<option value="125%">125%</option>
|
|
264
|
+
<option value="100%">100%</option>
|
|
265
|
+
<option value="75%">75%</option>
|
|
266
|
+
<option value="50%">50%</option>
|
|
267
|
+
</optgroup>
|
|
271
268
|
</Dropdown>
|
|
272
269
|
|
|
273
|
-
<
|
|
274
|
-
<
|
|
275
|
-
<
|
|
276
|
-
<
|
|
277
|
-
<
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
<
|
|
283
|
-
<
|
|
284
|
-
<
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
<
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
270
|
+
<div class="flex-1">
|
|
271
|
+
<Textbox :readonly="1" :value="iframeSrc" class="w-full">
|
|
272
|
+
<template #start>
|
|
273
|
+
<button @click="reloadIframe" class="p-3">
|
|
274
|
+
<svg width="14" height="14" viewBox="0 0 24 24" class="fill-text" xmlns="http://www.w3.org/2000/svg">
|
|
275
|
+
<path d="M3.75 12C3.75 7.44365 7.44365 3.75 12 3.75C14.7802 3.75 17.1982 5.12612 18.6816 7.24467L16.5022 7.23828C16.088 7.23707 15.7512 7.57187 15.75 7.98608C15.7488 8.4003 16.0836 8.73706 16.4978 8.73828L19.9491 8.74839C19.9817 8.75065 20.0147 8.75076 20.0477 8.74868L20.4978 8.75C20.6971 8.75058 20.8884 8.67182 21.0296 8.53111C21.1707 8.39039 21.25 8.19929 21.25 8L21.25 4C21.25 3.58579 20.9142 3.25 20.5 3.25C20.0858 3.25 19.75 3.58579 19.75 4L19.75 6.16237C17.9894 3.79113 15.2004 2.25 12 2.25C6.61522 2.25 2.25 6.61522 2.25 12C2.25 17.3848 6.61522 21.75 12 21.75C15.8354 21.75 19.0799 19.5367 20.6716 16.3338C20.856 15.9628 20.7047 15.5127 20.3338 15.3284C19.9628 15.144 19.5127 15.2953 19.3284 15.6662C17.9747 18.3902 15.2321 20.25 12 20.25C7.44365 20.25 3.75 16.5563 3.75 12Z"/>
|
|
276
|
+
</svg>
|
|
277
|
+
</button>
|
|
278
|
+
</template>
|
|
279
|
+
<template #end>
|
|
280
|
+
<div class="flex flex-row gap-4">
|
|
281
|
+
<CopyToClipboard :value="iframeSrc" @copied="toast($t('Copied'))">
|
|
282
|
+
<svg width="14" height="14" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM352 32.491a15.88 15.88 0 0 1 7.431 4.195l51.882 51.883A15.885 15.885 0 0 1 415.508 96H352V32.491zM288 464c0 8.822-7.178 16-16 16H48c-8.822 0-16-7.178-16-16V144c0-8.822 7.178-16 16-16h80v240c0 26.51 21.49 48 48 48h112v48zm128-96c0 8.822-7.178 16-16 16H176c-8.822 0-16-7.178-16-16V48c0-8.822 7.178-16 16-16h144v72c0 13.2 10.8 24 24 24h72v240z"/></svg>
|
|
283
|
+
</CopyToClipboard>
|
|
284
|
+
<a type="button" class="w-[21px]" :href="iframeSrc" target="_blank">
|
|
285
|
+
<svg width="12" height="12" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M497.6,0,334.4.17A14.4,14.4,0,0,0,320,14.57V47.88a14.4,14.4,0,0,0,14.69,14.4l73.63-2.72,2.06,2.06L131.52,340.49a12,12,0,0,0,0,17l23,23a12,12,0,0,0,17,0L450.38,101.62l2.06,2.06-2.72,73.63A14.4,14.4,0,0,0,464.12,192h33.31a14.4,14.4,0,0,0,14.4-14.4L512,14.4A14.4,14.4,0,0,0,497.6,0ZM432,288H416a16,16,0,0,0-16,16V458a6,6,0,0,1-6,6H54a6,6,0,0,1-6-6V118a6,6,0,0,1,6-6H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V304A16,16,0,0,0,432,288Z"/></svg>
|
|
286
|
+
</a>
|
|
287
|
+
</div>
|
|
288
|
+
</template>
|
|
289
|
+
</Textbox>
|
|
290
|
+
</div>
|
|
291
|
+
|
|
292
|
+
<div>
|
|
293
|
+
<Tabs v-model="store.previewViewType" variant="button" @change="resize" :items="viewTypes">
|
|
294
294
|
<template #tab="{ item }">
|
|
295
295
|
<div class="p-1 px-2" v-if="item.value === ''" v-tooltip="'Mobile'">
|
|
296
296
|
<svg width="14" height="14" class="fill-text pointer-events-none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M192 416c0 17.7-14.3 32-32 32s-32-14.3-32-32 14.3-32 32-32 32 14.3 32 32zM320 48v416c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48C0 21.5 21.5 0 48 0h224c26.5 0 48 21.5 48 48zm-32 0c0-8.8-7.2-16-16-16H48c-8.8 0-16 7.2-16 16v416c0 8.8 7.2 16 16 16h224c8.8 0 16-7.2 16-16V48z"/></svg>
|
|
@@ -304,7 +304,7 @@
|
|
|
304
304
|
</div>
|
|
305
305
|
</div>
|
|
306
306
|
|
|
307
|
-
<div class="flex-1 p-6 bg-base-300 dark:bg-base-400" :class="previewClass"
|
|
307
|
+
<div class="flex-1 p-6 bg-base-300 dark:bg-base-400" :class="previewClass" ref="preview">
|
|
308
308
|
<iframe :src="`${iframeSrc}?edit-mode=${page.uid}`" :width="iframeSize.width" :height="iframeSize.height"
|
|
309
309
|
class="mx-auto border-[2px] border-text-300" :style="iframeStyle" ref="iframe"></iframe>
|
|
310
310
|
</div>
|
|
@@ -314,19 +314,35 @@
|
|
|
314
314
|
<div v-if="currentItem" class="flex flex-col bg-base-400 dark:bg-base-300"
|
|
315
315
|
:style="section3Style">
|
|
316
316
|
|
|
317
|
-
<div class="
|
|
317
|
+
<div class="px-6 pt-6 pb-2 bg-base-300">
|
|
318
318
|
<strong>
|
|
319
319
|
{{ currentItem.type }}
|
|
320
320
|
</strong>
|
|
321
321
|
</div>
|
|
322
322
|
|
|
323
|
-
<div class="
|
|
323
|
+
<div class="px-4 bg-base-300 pt-2 relative">
|
|
324
|
+
<Tabs v-model="store.viewType" :items="viewTypes" variant="minimal">
|
|
325
|
+
<template #tab="{ item }">
|
|
326
|
+
<div v-if="item.value === ''" class="px-6 p-2 border-[1px] border-b-0 relative top-[1px] rounded-t-md"
|
|
327
|
+
:class="store.viewType === item.value ? 'bg-base-400 border-text-50' : 'border-transparent'">
|
|
328
|
+
Mobile
|
|
329
|
+
</div>
|
|
330
|
+
<div v-else-if="item.value === 'md:'" class="px-6 p-2 border-[1px] border-b-0 relative top-[1px] rounded-t-md"
|
|
331
|
+
:class="store.viewType === item.value ? 'bg-base-400 border-text-50' : 'border-transparent'">
|
|
332
|
+
Tablet
|
|
333
|
+
</div>
|
|
334
|
+
</template>
|
|
335
|
+
</Tabs>
|
|
336
|
+
</div>
|
|
337
|
+
|
|
338
|
+
<div class="flex-1 flex flex-row border-t-[1px] border-text-50">
|
|
324
339
|
|
|
325
340
|
<div :class="$style.resize3"
|
|
326
341
|
@mousedown="(e) => $util.dragResize(e, store.width[1], resize3)"></div>
|
|
327
342
|
|
|
328
343
|
<div class="flex-1 flex flex-col gap-6 overflow-y-auto p-6">
|
|
329
|
-
<div class="flex flex-col gap-6"
|
|
344
|
+
<div class="flex flex-col gap-6"
|
|
345
|
+
v-if="(store.selectedComponent ?? [])[1] !== 'style' && store.viewType === ''">
|
|
330
346
|
<div>
|
|
331
347
|
<label class="text-text-400">{{ $t('Enabled') }}</label>
|
|
332
348
|
<Switch v-model="currentItem.props.enabled" @change="onSave"/>
|
|
@@ -455,6 +471,7 @@
|
|
|
455
471
|
import throttle from "lodash/throttle";
|
|
456
472
|
import md5 from "md5";
|
|
457
473
|
import groupBy from "lodash/groupBy";
|
|
474
|
+
import {copyToClipboard, getClipboardData} from "../utils/helpers.mjs";
|
|
458
475
|
|
|
459
476
|
export default{
|
|
460
477
|
|
|
@@ -519,6 +536,32 @@ export default{
|
|
|
519
536
|
this.$refs.webPageComponentSelector.close()
|
|
520
537
|
},
|
|
521
538
|
|
|
539
|
+
copy(){
|
|
540
|
+
if(!this.currentItem) return
|
|
541
|
+
|
|
542
|
+
copyToClipboard(JSON.stringify(this.currentItem))
|
|
543
|
+
.then(() => this.toast('Copied to clipboard'))
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
paste(){
|
|
547
|
+
if(!this.currentItem) return
|
|
548
|
+
|
|
549
|
+
getClipboardData().then(text => {
|
|
550
|
+
try{
|
|
551
|
+
const item = JSON.parse(text)
|
|
552
|
+
this.setUid(item)
|
|
553
|
+
|
|
554
|
+
const comp = this.findItemByUid(this.currentItem.uid)
|
|
555
|
+
comp.items.splice(comp.items.indexOf(comp.item) + 1, 0, item)
|
|
556
|
+
this.store.selectedComponent = [ item.uid ]
|
|
557
|
+
comp.type === 'components' ? this.save() : this.saveLayout()
|
|
558
|
+
}
|
|
559
|
+
catch(e){
|
|
560
|
+
console.error(e)
|
|
561
|
+
}
|
|
562
|
+
})
|
|
563
|
+
},
|
|
564
|
+
|
|
522
565
|
async load(){
|
|
523
566
|
return this.socketEmit2('page.open', { uid:this.$route.params.uid })
|
|
524
567
|
.then(({ page, layouts, host }) => {
|
|
@@ -582,7 +625,7 @@ export default{
|
|
|
582
625
|
|
|
583
626
|
resize(){
|
|
584
627
|
|
|
585
|
-
const transformOrigin = this.
|
|
628
|
+
const transformOrigin = this.computedPreviewViewType === '' ? 'center top' : '0 0'
|
|
586
629
|
|
|
587
630
|
switch(this.store.zoomLevel){
|
|
588
631
|
|
|
@@ -592,7 +635,7 @@ export default{
|
|
|
592
635
|
const previewHeight = this.$refs.preview.clientHeight - 70
|
|
593
636
|
|
|
594
637
|
let scale = 1
|
|
595
|
-
if(this.
|
|
638
|
+
if(this.computedPreviewViewType === ''){
|
|
596
639
|
scale = (previewHeight / 844).toFixed(2)
|
|
597
640
|
}
|
|
598
641
|
else{
|
|
@@ -685,12 +728,9 @@ export default{
|
|
|
685
728
|
|
|
686
729
|
createComponentInstance(component){
|
|
687
730
|
|
|
688
|
-
if(!component.instance)
|
|
689
|
-
component.instance = {}
|
|
690
|
-
|
|
691
731
|
const compUid = '_' + component.uid.substring(0, 4) + ' '
|
|
692
732
|
|
|
693
|
-
|
|
733
|
+
const instance = {
|
|
694
734
|
type: component.type,
|
|
695
735
|
uid: component.uid,
|
|
696
736
|
|
|
@@ -711,27 +751,29 @@ export default{
|
|
|
711
751
|
})
|
|
712
752
|
.filter(_ => _)
|
|
713
753
|
.join(' ')
|
|
714
|
-
}
|
|
754
|
+
}
|
|
715
755
|
|
|
716
756
|
for(let key in component.props){
|
|
717
757
|
if(!this.compClasses.includes(key) && ![ 'enabled' ].includes(key)){
|
|
718
|
-
|
|
758
|
+
instance[key] = component.props[key]
|
|
719
759
|
}
|
|
720
760
|
}
|
|
721
761
|
|
|
722
762
|
if(Array.isArray(component.items)){
|
|
723
|
-
|
|
763
|
+
instance.items = component.items.map((_) => this.createComponentInstance(_))
|
|
724
764
|
}
|
|
725
765
|
|
|
726
766
|
if(component.props && Array.isArray(component.props.items)){
|
|
727
|
-
|
|
767
|
+
instance.items = component.props.items
|
|
728
768
|
}
|
|
729
769
|
|
|
730
|
-
return
|
|
770
|
+
return instance
|
|
731
771
|
},
|
|
732
772
|
|
|
733
773
|
save: throttle(function(reload = true){
|
|
734
|
-
this.page.
|
|
774
|
+
if(!this.page.instances || typeof this.page.instances !== 'object' || Array.isArray(this.page.instances))
|
|
775
|
+
this.page.instances = {}
|
|
776
|
+
this.page.instances.components = this.page.components.map((_) => this.createComponentInstance(_))
|
|
735
777
|
|
|
736
778
|
this.socketEmit2('page.save', this.page)
|
|
737
779
|
.then(() => {
|
|
@@ -747,8 +789,10 @@ export default{
|
|
|
747
789
|
}, 300),
|
|
748
790
|
|
|
749
791
|
saveLayout: throttle(function(reload = true){
|
|
750
|
-
this.layout.
|
|
751
|
-
|
|
792
|
+
if(!this.layout.instances || typeof this.layout.instances !== 'object' || Array.isArray(this.layout.instances))
|
|
793
|
+
this.layout.instances = {}
|
|
794
|
+
this.layout.instances.headers = (this.layout.headers ?? []).map((_) => this.createComponentInstance(_))
|
|
795
|
+
this.layout.instances.footers = (this.layout.footers ?? []).map((_) => this.createComponentInstance(_))
|
|
752
796
|
|
|
753
797
|
this.socketEmit2('layout.save', this.layout)
|
|
754
798
|
.then(() => {
|
|
@@ -863,29 +907,45 @@ export default{
|
|
|
863
907
|
}
|
|
864
908
|
},
|
|
865
909
|
|
|
866
|
-
onLayoutItemPaste(
|
|
867
|
-
|
|
868
|
-
},
|
|
910
|
+
onLayoutItemPaste(item){
|
|
911
|
+
//console.log('layout paste', item)
|
|
869
912
|
|
|
870
|
-
onItemPaste(items, currentItem, newItem, isLayout = false){
|
|
871
913
|
|
|
872
|
-
const setUid = (item) => {
|
|
873
|
-
item.uid = md5(newItem.type + Math.random())
|
|
874
914
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
}
|
|
915
|
+
},
|
|
916
|
+
|
|
917
|
+
onItemPaste(item, isLayout = false){
|
|
918
|
+
//console.log('page paste', item, this.store.selectedComponent)
|
|
919
|
+
return
|
|
881
920
|
|
|
882
|
-
setUid(newItem)
|
|
921
|
+
this.setUid(newItem)
|
|
883
922
|
items.splice(items.indexOf(currentItem) + 1, 0, newItem)
|
|
884
923
|
this.store.selectedComponent = [ newItem.uid ]
|
|
885
924
|
|
|
886
925
|
isLayout ? this.saveLayout() : this.save()
|
|
887
926
|
},
|
|
888
927
|
|
|
928
|
+
remove(item){
|
|
929
|
+
this.confirm(this.$t('Remove this item?'), {
|
|
930
|
+
onConfirm: () => {
|
|
931
|
+
const { items, type } = this.findItemByUid(item.uid)
|
|
932
|
+
items.splice(items.indexOf(item), 1)
|
|
933
|
+
type === 'components' ? this.save() : this.saveLayout()
|
|
934
|
+
this.store.selectedComponent = null
|
|
935
|
+
}
|
|
936
|
+
})
|
|
937
|
+
},
|
|
938
|
+
|
|
939
|
+
setUid(item){
|
|
940
|
+
item.uid = md5(Math.random())
|
|
941
|
+
|
|
942
|
+
if(Array.isArray(item.items)){
|
|
943
|
+
for(let subItem of item.items){
|
|
944
|
+
this.setUid(subItem)
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
|
|
889
949
|
findCompByUid(uid, components){
|
|
890
950
|
|
|
891
951
|
for(let i in components){
|
|
@@ -904,6 +964,47 @@ export default{
|
|
|
904
964
|
}
|
|
905
965
|
},
|
|
906
966
|
|
|
967
|
+
findItemByUid(uid, items){
|
|
968
|
+
|
|
969
|
+
if(!items){
|
|
970
|
+
for(let type of [ 'headers', 'footers' ]){
|
|
971
|
+
let item = this.findItemByUid(uid, (this.layout ?? {})[type] ?? [])
|
|
972
|
+
if(item){
|
|
973
|
+
return {
|
|
974
|
+
...item,
|
|
975
|
+
type
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
let item = this.findItemByUid(uid, (this.page ?? {}).components ?? [])
|
|
981
|
+
if(item){
|
|
982
|
+
return {
|
|
983
|
+
...item,
|
|
984
|
+
type: 'components'
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
else{
|
|
989
|
+
|
|
990
|
+
let item
|
|
991
|
+
for(let _item of items){
|
|
992
|
+
if(_item.uid === uid){
|
|
993
|
+
return {
|
|
994
|
+
item: _item,
|
|
995
|
+
items
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
else if(_item.items){
|
|
999
|
+
item = this.findItemByUid(uid, _item.items)
|
|
1000
|
+
if(item){
|
|
1001
|
+
return item
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
|
|
907
1008
|
getPage(){
|
|
908
1009
|
return this.page
|
|
909
1010
|
},
|
|
@@ -912,12 +1013,25 @@ export default{
|
|
|
912
1013
|
this.resize()
|
|
913
1014
|
}, 500, { leading:true }),
|
|
914
1015
|
|
|
1016
|
+
onKeyDown(e){
|
|
1017
|
+
if(e.keyCode === 67 && (e.metaKey || e.ctrlKey)){
|
|
1018
|
+
this.copy()
|
|
1019
|
+
}
|
|
1020
|
+
else if(e.keyCode === 86 && (e.metaKey || e.ctrlKey)){
|
|
1021
|
+
this.paste(e)
|
|
1022
|
+
}
|
|
1023
|
+
/*else if(e.keyCode === 8){
|
|
1024
|
+
if(this.currentItem){
|
|
1025
|
+
this.remove(this.currentItem)
|
|
1026
|
+
}
|
|
1027
|
+
}*/
|
|
1028
|
+
},
|
|
1029
|
+
|
|
915
1030
|
},
|
|
916
1031
|
|
|
917
1032
|
computed: {
|
|
918
1033
|
|
|
919
1034
|
currentItem(){
|
|
920
|
-
|
|
921
1035
|
let comp
|
|
922
1036
|
if(this.page && Array.isArray(this.store.selectedComponent)){
|
|
923
1037
|
|
|
@@ -954,14 +1068,19 @@ export default{
|
|
|
954
1068
|
break
|
|
955
1069
|
}
|
|
956
1070
|
}
|
|
957
|
-
|
|
958
1071
|
return comp
|
|
959
1072
|
},
|
|
960
1073
|
|
|
1074
|
+
computedPreviewViewType(){
|
|
1075
|
+
if(this.store.previewViewType === 'auto')
|
|
1076
|
+
return this.store.viewType
|
|
1077
|
+
return this.store.previewViewType
|
|
1078
|
+
},
|
|
1079
|
+
|
|
961
1080
|
iframeSize(){
|
|
962
1081
|
|
|
963
1082
|
let width, height
|
|
964
|
-
switch(this.
|
|
1083
|
+
switch(this.computedPreviewViewType){
|
|
965
1084
|
case '':
|
|
966
1085
|
width = 390
|
|
967
1086
|
height = 844
|
|
@@ -981,16 +1100,9 @@ export default{
|
|
|
981
1100
|
|
|
982
1101
|
previewClass(){
|
|
983
1102
|
return {
|
|
984
|
-
'overflow-
|
|
985
|
-
|
|
986
|
-
},
|
|
987
|
-
|
|
988
|
-
previewStyle(){
|
|
989
|
-
|
|
990
|
-
return {
|
|
991
|
-
'overflow-y': this.store.zoomLevel === 'fit' ? 'hidden' : 'auto'
|
|
1103
|
+
'overflow-auto': this.store.zoomLevel !== 'fit',
|
|
1104
|
+
'overflow-hidden': this.store.zoomLevel === 'fit',
|
|
992
1105
|
}
|
|
993
|
-
|
|
994
1106
|
},
|
|
995
1107
|
|
|
996
1108
|
layout(){
|
|
@@ -1041,7 +1153,7 @@ export default{
|
|
|
1041
1153
|
],
|
|
1042
1154
|
viewTypes: [
|
|
1043
1155
|
{ text:'Mobile', value:'' },
|
|
1044
|
-
{ text:'
|
|
1156
|
+
{ text:'Tablet', value:'md:' }
|
|
1045
1157
|
],
|
|
1046
1158
|
|
|
1047
1159
|
currentComponentItems: null,
|
|
@@ -1173,6 +1285,7 @@ export default{
|
|
|
1173
1285
|
|
|
1174
1286
|
window.addEventListener('message', this.onMessage)
|
|
1175
1287
|
window.addEventListener('resize', this.onResize)
|
|
1288
|
+
window.addEventListener('keydown', this.onKeyDown)
|
|
1176
1289
|
|
|
1177
1290
|
this.listen()
|
|
1178
1291
|
this.socket.onAny(this.onHooks)
|