@mixd-id/web-scaffold 0.1.230406108 → 0.1.230406110

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,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.230406108",
4
+ "version": "0.1.230406110",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -43,7 +43,6 @@
43
43
  "glob": "^8.0.3",
44
44
  "lodash": "^4.17.21",
45
45
  "md5": "^2.3.0",
46
- "monaco-editor": "^0.41.0",
47
46
  "nprogress": "^0.2.0",
48
47
  "pinia": "^2.0.14",
49
48
  "prismjs": "^1.28.0",
@@ -6,6 +6,8 @@
6
6
 
7
7
  <script>
8
8
 
9
+ import {copyToClipboard} from "../utils/helpers.mjs";
10
+
9
11
  export default{
10
12
 
11
13
  emits: [ 'copied', 'error' ],
@@ -19,41 +21,14 @@ export default{
19
21
 
20
22
  methods: {
21
23
 
22
- fallbackCopyTextToClipboard(text){
23
- var textArea = document.createElement("textarea");
24
- textArea.value = this.value;
25
- textArea.style.top = "0";
26
- textArea.style.left = "0";
27
- textArea.style.position = "fixed";
28
- document.body.appendChild(textArea);
29
- textArea.focus();
30
- textArea.select();
31
-
32
- try {
33
- document.execCommand('copy')
34
- this.$emit('copied')
35
- } catch (err) {
36
- this.$emit('error')
37
- }
38
-
39
- document.body.removeChild(textArea);
40
- },
41
-
42
24
  copyToClipboard(){
43
-
44
- if (!navigator.clipboard) {
45
- this.fallbackCopyTextToClipboard(this.value);
46
- return;
47
- }
48
- navigator.clipboard.writeText(this.value).then(() => {
49
- this.$emit('copied')
50
- }, (err) => {
51
- this.$emit('error')
52
- });
25
+ copyToClipboard(this.value)
26
+ .then(() => this.$emit('copied'))
27
+ .catch(() => this.$emit('error'))
53
28
  }
54
29
 
55
30
  }
56
31
 
57
32
  }
58
33
 
59
- </script>
34
+ </script>
@@ -9,7 +9,9 @@
9
9
  @movedown="moveDown(item)"
10
10
  @change="$emit('change')"
11
11
  @remove="confirm($t('Remove this item?'), { onConfirm: () => { modelValue.splice(index, 1);$emit('change') }})"
12
- @add="(items) => $emit('add', items)">
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)">
13
15
  <template #default="{ item }">
14
16
  <slot :item="item"></slot>
15
17
  </template>
@@ -26,7 +28,7 @@ export default{
26
28
 
27
29
  components: {TreeViewItem},
28
30
 
29
- emits: [ 'add', 'change' ],
31
+ emits: [ 'add', 'change', 'item-paste' ],
30
32
 
31
33
  inject: [ 'confirm' ],
32
34
 
@@ -40,6 +42,19 @@ export default{
40
42
 
41
43
  methods: {
42
44
 
45
+ paste(event, subItem){
46
+ const clipboardData = event.clipboardData || window.clipboardData;
47
+ const pastedText = clipboardData.getData('text');
48
+
49
+ try{
50
+ const newItem = JSON.parse(pastedText)
51
+ this.$emit('item-paste', this.modelValue, subItem, newItem)
52
+ }
53
+ catch(e){
54
+
55
+ }
56
+ },
57
+
43
58
  moveDown(item){
44
59
  const idx = this.modelValue.indexOf(item)
45
60
  if(idx < this.modelValue.length - 1){
@@ -1,27 +1,20 @@
1
1
  <template>
2
- <div>
2
+ <div @copy.stop.prevent="copy">
3
3
  <div ref="item" :class="itemClass"
4
- @mouseover="hoverMouseOver" @mouseout="hoverMouseOut">
5
- <div class="cursor-move" ref="drag" @mousedown="mouseDown">
6
- <svg width="14" height="14" class="fill-text-100" 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>
7
- </div>
8
- <div class="flex flex-col hidden">
9
- <button type="button" @click="$emit('moveup')">
10
- <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M32.032 352h255.93c28.425 0 42.767-34.488 22.627-54.627l-127.962-128c-12.496-12.496-32.758-12.497-45.255 0l-127.968 128C-10.695 317.472 3.55 352 32.032 352zM160 192l128 128H32l128-128z"/></svg>
11
- </button>
12
- <button type="button" @click="$emit('movedown')">
13
- <svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M287.968 160H32.038c-28.425 0-42.767 34.488-22.627 54.627l127.962 128c12.496 12.496 32.758 12.497 45.255 0l127.968-128C330.695 194.528 316.45 160 287.968 160zM160 320L32 192h256L160 320z"/></svg>
14
- </button>
15
- </div>
16
- <slot :item="item"></slot>
17
- <button type="button" class="py-2" @click="$emit('remove')">
18
- <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="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z"/></svg>
19
- </button>
4
+ @mouseover="hoverMouseOver"
5
+ @mouseout="hoverMouseOut"
6
+ @mousedown="mouseDown"
7
+ @mouseup="hoverMouseUp">
20
8
  <button type="button" class="py-2" v-if="Array.isArray((item ?? {}).items) && item.items.length > 0"
21
- @click="childCollapsed = !childCollapsed">
9
+ @click="childCollapsed = !childCollapsed">
22
10
  <svg v-if="!childCollapsed" width="16" height="16" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"/></svg>
23
11
  <svg v-else width="16" height="16" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><path d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"/></svg>
24
12
  </button>
13
+ <div v-else class="pl-1"></div>
14
+ <slot :item="item"></slot>
15
+ <button type="button" class="py-2" @click="$emit('remove')">
16
+ <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="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z"/></svg>
17
+ </button>
25
18
  </div>
26
19
  <div ref="container" v-if="item && Array.isArray(item.items) && !childCollapsed" class="ml-4">
27
20
  <TreeViewItem v-for="(subItem, index) in item.items"
@@ -32,7 +25,9 @@
32
25
  @movedown="moveDown(subItem)"
33
26
  @remove="confirm($t('Remove this item?'), { onConfirm: () => { item.items.splice(index, 1);$emit('change') }})"
34
27
  @add="(items) => $emit('add', items)"
35
- @change="$emit('change')">
28
+ @change="$emit('change')"
29
+ @paste.stop.prevent="(e) => paste(e, subItem)"
30
+ @item-paste="(p1, p2, p3) => $emit('item-paste', p1, p2, p3)">
36
31
  <template #default="{ item }">
37
32
  <slot :item="item"></slot>
38
33
  </template>
@@ -50,13 +45,15 @@
50
45
 
51
46
  <script>
52
47
 
48
+ import {copyToClipboard} from "../utils/helpers.mjs";
49
+
53
50
  let dragged = null
54
51
 
55
52
  export default{
56
53
 
57
- emits: [ 'add', 'change', 'moveup', 'movedown', 'remove' ],
54
+ emits: [ 'add', 'change', 'moveup', 'movedown', 'remove', 'item-paste' ],
58
55
 
59
- inject: [ 'confirm' ],
56
+ inject: [ 'confirm', 'toast' ],
60
57
 
61
58
  props: {
62
59
  item: Object,
@@ -73,6 +70,24 @@ export default{
73
70
 
74
71
  methods: {
75
72
 
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
+
76
91
  moveDown(item){
77
92
  const idx = this.item.items.indexOf(item)
78
93
  if(idx < this.item.items.length - 1){
@@ -94,12 +109,14 @@ export default{
94
109
  },
95
110
 
96
111
  mouseDown(e){
97
-
98
112
  e.preventDefault()
99
113
 
114
+ const rect = this.$el.getBoundingClientRect()
115
+ const startX = e.clientX
116
+
100
117
  const cloned = this.$el.cloneNode(true)
101
118
  cloned.style.position = 'absolute'
102
- cloned.style.left = (e.clientX - 10) + "px"
119
+ cloned.style.left = rect.x + "px"
103
120
  cloned.style.top = (e.clientY - 10) + "px"
104
121
  cloned.style.width = this.$el.clientWidth + "px"
105
122
  cloned.style.pointerEvents = 'none'
@@ -111,7 +128,8 @@ export default{
111
128
  }
112
129
 
113
130
  const mouseMove = (e) => {
114
- cloned.style.left = (e.clientX - 10) + "px"
131
+ const distanceX = e.clientX - startX
132
+ cloned.style.left = (rect.x + distanceX) + "px"
115
133
  cloned.style.top = (e.clientY - 10) + "px"
116
134
  }
117
135
 
@@ -170,7 +188,7 @@ export default{
170
188
  delete dragged.targetParent
171
189
  }
172
190
 
173
- }
191
+ },
174
192
 
175
193
  },
176
194
 
@@ -201,8 +219,8 @@ export default{
201
219
  <style module>
202
220
 
203
221
  .item{
204
- @apply bg-base-300 dark:bg-base-400 flex flex-row gap-2 px-3 items-center rounded-lg mb-1;
205
- @apply border-[1px] border-transparent;
222
+ @apply bg-base-300 dark:bg-base-400 flex flex-row gap-2 px-2 items-center rounded-lg mb-1;
223
+ @apply border-[1px] border-transparent cursor-pointer;
206
224
  }
207
225
  .item.active{
208
226
  @apply border-primary;
package/src/index.js CHANGED
@@ -321,7 +321,7 @@ export default{
321
321
  app.component('Grid', defineAsyncComponent(() => import("./components/Grid.vue")))
322
322
  app.component('Modal', defineAsyncComponent(() => import("./components/Modal.vue")))
323
323
  app.component('Modal2', defineAsyncComponent(() => import("./components/Modal2.vue")))
324
- app.component('MonacoEditor', defineAsyncComponent(() => import("./components/MonacoEditor.vue")))
324
+ //app.component('MonacoEditor', defineAsyncComponent(() => import("./components/MonacoEditor.vue")))
325
325
  app.component('OTPField', defineAsyncComponent(() => import("./components/OTPField.vue")))
326
326
  app.component('PageBuilder', defineAsyncComponent(() => import("./components/PageBuilder.vue")))
327
327
  app.component('Radio', defineAsyncComponent(() => import("./components/Radio.vue")))
@@ -177,6 +177,42 @@ const _applyClass = function(props, defaultClass = {}){
177
177
  return []
178
178
  }
179
179
 
180
+ const fallbackCopyTextToClipboard = function(obj){
181
+ return new Promise((resolve, reject) => {
182
+ var textArea = document.createElement("textarea");
183
+ textArea.value = obj;
184
+ textArea.style.top = "0";
185
+ textArea.style.left = "0";
186
+ textArea.style.position = "fixed";
187
+ document.body.appendChild(textArea);
188
+ textArea.focus();
189
+ textArea.select();
190
+
191
+ try {
192
+ document.execCommand('copy')
193
+ document.body.removeChild(textArea);
194
+ resolve()
195
+ } catch (err) {
196
+ reject(err)
197
+ }
198
+ })
199
+ }
200
+
201
+ const copyToClipboard = function(obj){
202
+
203
+ if (!navigator.clipboard) {
204
+ return fallbackCopyTextToClipboard(obj);
205
+ }
206
+
207
+ return new Promise((resolve, reject) => {
208
+ navigator.clipboard.writeText(obj).then(() => {
209
+ resolve()
210
+ }, (err) => {
211
+ reject(err)
212
+ });
213
+ })
214
+ }
215
+
180
216
  export {
181
217
  downsizeImage,
182
218
  uid,
@@ -187,7 +223,8 @@ export {
187
223
  getQueryString,
188
224
  accessNestedObject,
189
225
  mediaPrefixes,
190
- _applyClass
226
+ _applyClass,
227
+ copyToClipboard
191
228
  }
192
229
 
193
230
  function observeInit(){
@@ -144,7 +144,8 @@
144
144
  v-model="layout.headers"
145
145
  :selected-item="currentItem"
146
146
  @add="openSelector"
147
- @change="saveLayout">
147
+ @change="saveLayout"
148
+ @item-paste="onLayoutItemPaste">
148
149
  <template #default="{ item }">
149
150
  <component :is="`${(item ?? {}).type}Item`" :item="item"
150
151
  @click="store.selectedComponent = [ item.uid ]"/>
@@ -161,7 +162,8 @@
161
162
  v-model="layout.footers"
162
163
  :selected-item="currentItem"
163
164
  @add="openSelector"
164
- @change="saveLayout">
165
+ @change="saveLayout"
166
+ @item-paste="onLayoutItemPaste">
165
167
  <template #default="{ item }">
166
168
  <component :is="`${(item ?? {}).type}Item`" :item="item"
167
169
  @click="store.selectedComponent = [ item.uid ]"/>
@@ -178,7 +180,8 @@
178
180
  v-model="page.components"
179
181
  :selected-item="currentItem"
180
182
  @add="openSelector"
181
- @change="save">
183
+ @change="save"
184
+ @item-paste="onItemPaste">
182
185
 
183
186
  <template #default="{ item }">
184
187
  <component :is="`${(item ?? {}).type}Item`" :item="item"
@@ -253,7 +256,7 @@
253
256
  </template>
254
257
  <template #end>
255
258
  <div class="flex flex-row gap-4">
256
- <CopyToClipboard :value="iframeSrc" @copied="toast('Nomor hp berhasil disalin')">
259
+ <CopyToClipboard :value="iframeSrc" @copied="toast($t('Copied'))">
257
260
  <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>
258
261
  </CopyToClipboard>
259
262
  <a type="button" class="w-[21px]" :href="iframeSrc" target="_blank">
@@ -403,7 +406,7 @@
403
406
  </template>
404
407
  <template #default="{ context }">
405
408
  <div class="flex-1 p-5">
406
- <MonacoEditor ref="monacoEditor" v-model="context.code"/>
409
+ <Textarea v-model="context.code" rows="10" ></Textarea>
407
410
  </div>
408
411
  </template>
409
412
  </Modal>
@@ -467,7 +470,7 @@ export default{
467
470
  enabled: true
468
471
  })
469
472
 
470
- obj.uid = md5(obj.type + new Date().getTime())
473
+ obj.uid = md5(obj.type + Math.random())
471
474
 
472
475
  if([ 'headers', 'footers' ].includes(to)){
473
476
  this.layout[to].push(obj)
@@ -724,11 +727,11 @@ export default{
724
727
  }, 300),
725
728
 
726
729
  saveLdjson(context){
727
- const errors = this.$refs.monacoEditor.getErrors()
730
+ /*const errors = this.$refs.monacoEditor.getErrors()
728
731
  if(errors){
729
732
  this.alert('JSON is not valid', errors.map(_ => _.message).join("\n"))
730
733
  return
731
- }
734
+ }*/
732
735
 
733
736
  'index' in context ?
734
737
  this.page.ldjson[context.index] = context.code :
@@ -777,6 +780,29 @@ export default{
777
780
  this.$refs.iframe.contentWindow.postMessage({ uid, data }, '*')
778
781
  },
779
782
 
783
+ onLayoutItemPaste(items, currentItem, newItem){
784
+ this.onItemPaste(items, currentItem, newItem, true)
785
+ },
786
+
787
+ onItemPaste(items, currentItem, newItem, isLayout = false){
788
+
789
+ const setUid = (item) => {
790
+ item.uid = md5(newItem.type + Math.random())
791
+
792
+ if(Array.isArray(item.items)){
793
+ for(let subItem of item.items){
794
+ setUid(subItem)
795
+ }
796
+ }
797
+ }
798
+
799
+ setUid(newItem)
800
+ items.splice(items.indexOf(currentItem) + 1, 0, newItem)
801
+ this.store.selectedComponent = [ newItem.uid ]
802
+
803
+ isLayout ? this.saveLayout() : this.save()
804
+ },
805
+
780
806
  findCompByUid(uid, components){
781
807
 
782
808
  for(let i in components){