@mixd-id/web-scaffold 0.1.230406186 → 0.1.230406187

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.230406186",
4
+ "version": "0.1.230406187",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <div :class="$style.comp">
3
3
  <article ref="article" :class="$style.article"
4
- v-html="htmlText"
5
- :contenteditable="editMode"
4
+ v-html="computedHtml"
5
+ :contenteditable="editMode === 1"
6
6
  @input="onInput"
7
7
  @click="onClick"
8
8
  @paste="onPaste"></article>
@@ -13,6 +13,7 @@
13
13
 
14
14
  import { componentMixin } from '../mixin/component';
15
15
  import {getSelection, restoreSelection, saveSelection} from "../utils/selection";
16
+ import {applyDatasourceReplacer} from "../utils/helpers.mjs";
16
17
 
17
18
  export default{
18
19
 
@@ -214,7 +215,7 @@ export default{
214
215
  },
215
216
 
216
217
  mounted() {
217
- if('edit-mode' in this.$route.query){
218
+ if(this.editMode){
218
219
  window.addEventListener('message', (e) => {
219
220
 
220
221
  const { data, source } = e
@@ -325,7 +326,23 @@ export default{
325
326
 
326
327
  })
327
328
  }
328
- }
329
+ },
330
+
331
+ computed: {
332
+
333
+ computedHtml(){
334
+ if(this.editMode && this.editMode === 1)
335
+ return this.htmlText
336
+ return applyDatasourceReplacer(this.htmlText, this.pageData)
337
+ },
338
+
339
+ },
340
+
341
+ data(){
342
+ return {
343
+ data: {},
344
+ }
345
+ }
329
346
 
330
347
  }
331
348
 
@@ -204,7 +204,7 @@ export default{
204
204
  stroke-opacity: 50%;
205
205
  }
206
206
  .button-outline .svgHg{
207
- fill: rgb(var(--primary));
207
+ fill: rgb(var(--primary-500));
208
208
  fill-opacity: 100%;
209
209
  }
210
210
 
@@ -3,9 +3,8 @@
3
3
 
4
4
  <div ref="inner" :class="computedContainerClass">
5
5
  <div v-for="item in items" :class="computedItemClass">
6
- <component :is="item.type"
7
- :="item"
8
- edit-selectable="false" />
6
+ <slot v-if="$slots['default']" :item="item"></slot>
7
+ <component v-else :is="item.type" :="item" />
9
8
  </div>
10
9
  </div>
11
10
 
@@ -156,6 +155,13 @@ export default{
156
155
  this.$el.firstElementChild.style.transform = `translate3d(${left}px, 0, 0)`
157
156
  },
158
157
 
158
+ setIndex(index){
159
+ if(index >= 0 && index < this.items.length){
160
+ this.index = index
161
+ this.setPosition()
162
+ }
163
+ },
164
+
159
165
  next(setPosition, useBack){
160
166
 
161
167
  let index = this.index + 1
@@ -327,7 +333,7 @@ export default{
327
333
  @apply w-2 h-2 rounded-full bg-gray-100;
328
334
  }
329
335
  .legend .legendItemActive>*{
330
- @apply bg-primary;
336
+ @apply bg-primary-500;
331
337
  }
332
338
 
333
339
  @media screen(md){
@@ -1,31 +1,31 @@
1
1
  <template>
2
2
  <div :class="$style.comp">
3
3
 
4
- <slot v-if="display >= 4 && $slots.day" name="day" :day="day"></slot>
5
- <div ref="day" v-else-if="display >= 4" :class="$style.lap">
4
+ <slot v-if="computedDisplay >= 4 && $slots.day" name="day" :day="day"></slot>
5
+ <div ref="day" v-else-if="computedDisplay >= 4" :class="$style.lap">
6
6
  <div></div>
7
7
  <div></div>
8
8
  </div>
9
- <div v-if="display >= 4" class="mr-2" :style="labelStyle">hari</div>
9
+ <div v-if="computedDisplay >= 4" class="mr-2" :style="labelStyle">hari</div>
10
10
 
11
- <slot v-if="display >= 3 && $slots.hour" name="hour" :hour="hour"></slot>
12
- <div ref="hour" v-else-if="display >= 3" :class="$style.lap">
11
+ <slot v-if="computedDisplay >= 3 && $slots.hour" name="hour" :hour="hour"></slot>
12
+ <div ref="hour" v-else-if="computedDisplay >= 3" :class="$style.lap">
13
13
  <div></div>
14
14
  <div></div>
15
15
  </div>
16
16
 
17
17
  <div :style="labelStyle">:</div>
18
18
 
19
- <slot v-if="display >= 2 && $slots.minute" name="minute" :minute="minute"></slot>
20
- <div ref="minute" v-else-if="display >= 2" :class="$style.lap">
19
+ <slot v-if="computedDisplay >= 2 && $slots.minute" name="minute" :minute="minute"></slot>
20
+ <div ref="minute" v-else-if="computedDisplay >= 2" :class="$style.lap">
21
21
  <div></div>
22
22
  <div></div>
23
23
  </div>
24
24
 
25
25
  <div :style="labelStyle">:</div>
26
26
 
27
- <slot v-if="display >= 1 && $slots.second" name="second" :second="second"></slot>
28
- <div ref="second" v-else-if="display >= 1" :class="$style.lap">
27
+ <slot v-if="computedDisplay >= 1 && $slots.second" name="second" :second="second"></slot>
28
+ <div ref="second" v-else-if="computedDisplay >= 1" :class="$style.lap">
29
29
  <div></div>
30
30
  <div></div>
31
31
  </div>
@@ -35,16 +35,24 @@
35
35
 
36
36
  <script>
37
37
 
38
+ import {componentMixin} from "../mixin/component";
39
+ import throttle from "lodash/throttle";
40
+
38
41
  export default{
39
42
 
43
+ mixins: [ componentMixin ],
44
+
40
45
  props: {
41
46
 
42
- display: {
47
+ mode: {
43
48
  type: [ String, Number ], // default: 3
44
49
  default: 3
45
50
  },
46
51
 
47
- value: [ String, Number ], // value in second,
52
+ value: {
53
+ type: [ String, Number ], // value in second,
54
+ required: true
55
+ },
48
56
 
49
57
  labelStyle: Object
50
58
 
@@ -66,7 +74,11 @@ export default{
66
74
 
67
75
  second(){
68
76
  return (this.timer % 60).toString().padStart(2, '0')
69
- }
77
+ },
78
+
79
+ computedDisplay(){
80
+ return parseInt(this.mode)
81
+ }
70
82
 
71
83
  },
72
84
 
@@ -83,10 +95,6 @@ export default{
83
95
 
84
96
  mounted() {
85
97
  this.start()
86
- if(this.$refs.second) this.$refs.second.addEventListener('transitionend', this.onSecondEnd)
87
- if(this.$refs.minute) this.$refs.minute.addEventListener('transitionend', this.onMinuteEnd)
88
- if(this.$refs.hour) this.$refs.hour.addEventListener('transitionend', this.onHourEnd)
89
- if(this.$refs.day) this.$refs.day.addEventListener('transitionend', this.onDayEnd)
90
98
  },
91
99
 
92
100
  methods: {
@@ -115,13 +123,13 @@ export default{
115
123
  this.state[2] = 0
116
124
  },
117
125
 
118
- onSecondEnd: function (e){
126
+ onSecondEnd: function (){
119
127
  if(this.state[3] !== 1) return
120
- this.$refs.second.insertBefore(this.$refs.second.childNodes[1], this.$refs.second.childNodes[0])
121
- this.$refs.second.classList.remove(this.$style.tick)
122
- this.$refs.second.childNodes[0].innerHTML = ''
128
+ this.$refs.second.insertBefore(this.$refs.second.childNodes[1], this.$refs.second.childNodes[0])
129
+ this.$refs.second.classList.remove(this.$style.tick)
130
+ this.$refs.second.childNodes[0].innerHTML = ''
123
131
  this.state[3] = 0
124
- },
132
+ },
125
133
 
126
134
  setInitial(){
127
135
  if(this.$refs.day) this.$refs.day.lastElementChild.innerHTML = Math.floor(this.timer / 86400).toString().padStart(2, '0')
@@ -132,7 +140,25 @@ export default{
132
140
 
133
141
  start(){
134
142
 
135
- this.timer = this.value
143
+ let timer
144
+ if(typeof this.value === 'string') {
145
+ const d = new Date(this.value + ' 00:00:00')
146
+ if(d.getFullYear() !== 1970){
147
+ timer = Math.floor((d.getTime() - new Date().getTime()) / 1000)
148
+ }
149
+ }
150
+ else{
151
+ timer = this.value
152
+ }
153
+
154
+ if(timer < 1) return
155
+
156
+ this.timer = timer
157
+
158
+ if(this.$refs.second) this.$refs.second.addEventListener('transitionend', this.onSecondEnd)
159
+ if(this.$refs.minute) this.$refs.minute.addEventListener('transitionend', this.onMinuteEnd)
160
+ if(this.$refs.hour) this.$refs.hour.addEventListener('transitionend', this.onHourEnd)
161
+ if(this.$refs.day) this.$refs.day.addEventListener('transitionend', this.onDayEnd)
136
162
 
137
163
  this.setInitial()
138
164
 
@@ -151,7 +177,11 @@ export default{
151
177
  watch: {
152
178
 
153
179
  value(){
154
- this.start()
180
+ this.$nextTick(() => this.start())
181
+ },
182
+
183
+ mode(){
184
+ this.$nextTick(() => this.start())
155
185
  },
156
186
 
157
187
  day(to, from){
@@ -198,7 +228,7 @@ export default{
198
228
  }
199
229
 
200
230
  .lap{
201
- @apply relative overflow-hidden bg-gray-200 min-w-[1.8rem] rounded-lg text-center;
231
+ @apply relative overflow-hidden bg-gray-200 min-w-[1.8rem] px-1 rounded-lg text-center;
202
232
  }
203
233
  .lap>*{
204
234
  @apply whitespace-nowrap font-bold;
@@ -57,17 +57,17 @@
57
57
  <div class="flex items-center">
58
58
  <h4 class="flex-1">{{ contextMenuTitle }}</h4>
59
59
  <button type="button" @click.stop="contextMenuPrevMonth()" class="p-2">
60
- <svg width="24" height="24" class="fill-text" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
60
+ <svg width="21" height="21" class="fill-text" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
61
61
  <path d="M10.5303 17.9697C10.8232 18.2626 10.8232 18.7374 10.5303 19.0303C10.2374 19.3232 9.76253 19.3232 9.46964 19.0303L3.67675 13.2374C2.99333 12.554 2.99333 11.446 3.67675 10.7626L9.46964 4.96967C9.76253 4.67678 10.2374 4.67678 10.5303 4.96967C10.8232 5.26256 10.8232 5.73744 10.5303 6.03033L5.31063 11.25H20C20.4142 11.25 20.75 11.5858 20.75 12C20.75 12.4142 20.4142 12.75 20 12.75H5.31063L10.5303 17.9697Z"/>
62
62
  </svg>
63
63
  </button>
64
64
  <button type="button" @click.stop="contextMenuNextMonth()" class="p-2">
65
- <svg width="24" height="24" class="fill-text" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
65
+ <svg width="21" height="21" class="fill-text" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
66
66
  <path d="M13.4697 17.9697C13.1768 18.2626 13.1768 18.7374 13.4697 19.0303C13.7626 19.3232 14.2374 19.3232 14.5303 19.0303L20.3232 13.2374C21.0066 12.554 21.0066 11.446 20.3232 10.7626L14.5303 4.96967C14.2374 4.67678 13.7626 4.67678 13.4697 4.96967C13.1768 5.26256 13.1768 5.73744 13.4697 6.03033L18.6893 11.25H4C3.58579 11.25 3.25 11.5858 3.25 12C3.25 12.4142 3.58579 12.75 4 12.75H18.6893L13.4697 17.9697Z"/>
67
67
  </svg>
68
68
  </button>
69
69
  </div>
70
- <div class="grid grid-cols-7 gap-2">
70
+ <div class="grid grid-cols-7 gap-2 mt-2">
71
71
  <div v-for="i in 7">{{ getDayOfWeekLabel(i) }}</div>
72
72
  <button type="button" :class="buttonStyle(d.value)"
73
73
  v-for="d in contextMenuDates" @click="setValue(d.value)">
@@ -1,10 +1,12 @@
1
1
  <template>
2
- <p :class="$style.comp" v-html="html"></p>
2
+ <p :class="$style.comp" v-html="computedHtml"></p>
3
3
  </template>
4
4
 
5
5
  <script>
6
6
 
7
7
  import {componentMixin} from "../mixin/component";
8
+ import {applyDatasourceReplacer} from "../utils/helpers.mjs";
9
+
8
10
 
9
11
  export default{
10
12
 
@@ -12,6 +14,18 @@ export default{
12
14
 
13
15
  props: {
14
16
  html: String
17
+ },
18
+
19
+ computed: {
20
+
21
+ computedHtml(){
22
+ return applyDatasourceReplacer(this.html, this.pageData)
23
+ }
24
+
25
+ },
26
+
27
+ methods: {
28
+
15
29
  }
16
30
 
17
31
  }
@@ -5,6 +5,7 @@
5
5
  <svg width="14" height="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>
6
6
  </div>
7
7
  </div>
8
+ <input type="radio" class="hidden" :checked="cChecked"/>
8
9
  <slot></slot>
9
10
  </div>
10
11
  </template>
@@ -280,7 +280,7 @@ export default{
280
280
 
281
281
  .slider>div:nth-child(3),
282
282
  .slider>div:nth-child(4){
283
- @apply absolute w-[2.3rem] h-[2.3rem] rounded-full bg-white shadow-sm border-[1px] border-text-200;
283
+ @apply absolute w-[2.5rem] h-[2.5rem] rounded-full bg-white shadow-sm border-[1px] border-text-200;
284
284
  @apply flex;
285
285
  top: 50%;
286
286
  transform: translate3d(0, -50%, 0);
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ <Countdown value="2023-11-15 00:00:00" />
5
+
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+
11
+ export default{
12
+
13
+ }
14
+
15
+ </script>
16
+
17
+ <style module>
18
+
19
+ .comp{
20
+
21
+ }
22
+
23
+ </style>
@@ -0,0 +1,27 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <Image class="w-full aspect-square bg-primary-100" />
4
+ <strong>Title</strong>
5
+ <p>sit amet bear claw sesame snaps bonbon </p>
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+
11
+ import {componentMixin} from "../mixin/component";
12
+
13
+ export default{
14
+
15
+ mixins: [ componentMixin ],
16
+
17
+ }
18
+
19
+ </script>
20
+
21
+ <style module>
22
+
23
+ .comp{
24
+ @apply flex flex-col gap-1 min-w-0 w-[6/12];
25
+ }
26
+
27
+ </style>
package/src/index.js CHANGED
@@ -417,6 +417,8 @@ export default{
417
417
  app.component('SplitPane', defineAsyncComponent(() => import("./components/SplitPane.vue")))
418
418
  app.component('Table', defineAsyncComponent(() => import("./components/Table.vue")))
419
419
  app.component('TabView', defineAsyncComponent(() => import("./components/TabView.vue")))
420
+ app.component('Test', defineAsyncComponent(() => import("./components/Test.vue")))
421
+ app.component('Thumbnail', defineAsyncComponent(() => import("./components/Thumbnail.vue")))
420
422
  app.component('Testimonial', defineAsyncComponent(() => import("./components/Testimonial.vue")))
421
423
  app.component('TextBlock', defineAsyncComponent(() => import("./components/TextBlock.vue")))
422
424
  app.component('TextEditor', defineAsyncComponent(() => import("./components/TextEditor.vue")))
@@ -427,6 +429,7 @@ export default{
427
429
  app.component('BoxSetting', defineAsyncComponent(() => import("./widgets/BoxSetting.vue")))
428
430
  app.component('ButtonSetting', defineAsyncComponent(() => import("./widgets/ButtonSetting.vue")))
429
431
  app.component('CarouselSetting', defineAsyncComponent(() => import("./widgets/CarouselSetting.vue")))
432
+ app.component('CountdownSetting', defineAsyncComponent(() => import("./widgets/CountdownSetting.vue")))
430
433
  app.component('ComponentSetting', defineAsyncComponent(() => import("./widgets/ComponentSetting.vue")))
431
434
  app.component('ContactForm', defineAsyncComponent(() => import("./widgets/ContactForm.vue")))
432
435
  app.component('ContactFormSetting', defineAsyncComponent(() => import("./widgets/ContactFormSetting.vue")))
@@ -455,6 +458,7 @@ export default{
455
458
  app.component('ShareSetting', defineAsyncComponent(() => import("./widgets/ShareSetting.vue")))
456
459
  app.component('StyleSetting', defineAsyncComponent(() => import("./widgets/StyleSetting.vue")))
457
460
  app.component('TableSetting', defineAsyncComponent(() => import("./widgets/TableSetting.vue")))
461
+ app.component('ThumbnailSetting', defineAsyncComponent(() => import("./widgets/ThumbnailSetting.vue")))
458
462
  app.component('TestimonialSetting', defineAsyncComponent(() => import("./widgets/TestimonialSetting.vue")))
459
463
  app.component('TextBlockSetting', defineAsyncComponent(() => import("./widgets/TextBlockSetting.vue")))
460
464
  app.component('WebPageBuilder', defineAsyncComponent(() => import("./widgets/WebPageBuilder.vue")))
@@ -462,5 +466,6 @@ export default{
462
466
  app.component('WebDatasourceSelector', defineAsyncComponent(() => import("./widgets/WebDatasourceSelector.vue")))
463
467
  app.component('WebPageSelector', defineAsyncComponent(() => import("./widgets/WebPageSelector.vue")))
464
468
  app.component('WebLayoutSelector', defineAsyncComponent(() => import("./widgets/WebLayoutSelector.vue")))
469
+ app.component('WebTemplateCreator', defineAsyncComponent(() => import("./widgets/WebTemplateCreator.vue")))
465
470
  }
466
471
  }
@@ -6,6 +6,8 @@ let guide, guide2
6
6
 
7
7
  export const componentMixin = {
8
8
 
9
+ inject: [ 'getPage' ],
10
+
9
11
  props: {
10
12
  enabled: Boolean,
11
13
  name: String,
@@ -85,6 +87,14 @@ export const componentMixin = {
85
87
  ]
86
88
  },
87
89
 
90
+ pageData(){
91
+ return (this.page ?? {}).data
92
+ },
93
+
94
+ editMode(){
95
+ return (this.page ?? {}).editMode
96
+ }
97
+
88
98
  },
89
99
 
90
100
  methods: {
@@ -95,6 +105,8 @@ export const componentMixin = {
95
105
  },
96
106
 
97
107
  componentClick(e){
108
+ if(this.editMode !== 1) return
109
+
98
110
  e.stopPropagation()
99
111
  e.preventDefault()
100
112
 
@@ -102,6 +114,8 @@ export const componentMixin = {
102
114
  },
103
115
 
104
116
  componentMouseOver(e){
117
+ if(this.editMode !== 1) return
118
+
105
119
  e.stopPropagation()
106
120
  e.preventDefault()
107
121
 
@@ -111,8 +125,14 @@ export const componentMixin = {
111
125
  this.$el.appendChild(this.getGuide())
112
126
  },
113
127
 
114
- componentMouseOut(e){
128
+ componentMouseOut(){
129
+ if(this.editMode !== 1) return
115
130
  this.$el.style.position = this.lastStyle.position
131
+
132
+ const guide = this.getGuide()
133
+ if(guide.parentNode){
134
+ guide.parentNode.removeChild(guide)
135
+ }
116
136
  },
117
137
 
118
138
  getGuide(){
@@ -138,21 +158,25 @@ export const componentMixin = {
138
158
  select(){
139
159
  if(!this.$el || this.$el.nodeType !== 1) return
140
160
 
141
- this.$el.appendChild(this.getGuide2())
161
+ //this.$el.appendChild(this.getGuide2())
142
162
  },
143
163
 
144
164
  },
145
165
 
146
166
  data(){
147
167
  return {
148
- editMode: false,
149
- lastStyle: {}
168
+ lastStyle: {},
169
+ store: null,
170
+ page: null,
150
171
  }
151
172
  },
152
173
 
153
174
  mounted(){
154
- if('edit-mode' in this.$route.query){
155
- this.editMode = true
175
+ if(this.getPage){
176
+ this.page = this.getPage()
177
+ }
178
+
179
+ if(this.editMode){
156
180
  this.editModeClick = inject('editModeClick', () => {})
157
181
  this.editRegisterComponent = inject('editRegisterComponent', () => {})
158
182
 
@@ -392,6 +392,84 @@ const removeStyleFromTag = (html) => {
392
392
  });
393
393
  }
394
394
 
395
+ const datasourceGet = async ({ Models }) => {
396
+
397
+ const models = []
398
+ for(let key in Models){
399
+
400
+ const columns = []
401
+ const attributes = Models[key].getAttributes()
402
+ for(let key in attributes){
403
+
404
+ let type
405
+ const fieldType = attributes[key].type.toString()
406
+
407
+ if(fieldType.startsWith('VARCHAR')){
408
+ type = 'string'
409
+ }
410
+ else if(fieldType.startsWith('INTEGER') || fieldType.startsWith('TINYINT')){
411
+ type = 'number'
412
+ }
413
+ else if(fieldType.startsWith('DATETIME')){
414
+ type = 'date'
415
+ }
416
+
417
+ if(type){
418
+ columns.push({
419
+ name: attributes[key].fieldName,
420
+ type,
421
+ })
422
+ }
423
+ }
424
+
425
+ models.push({
426
+ name: key,
427
+ columns
428
+ })
429
+ }
430
+
431
+ return {
432
+ models
433
+ }
434
+
435
+ }
436
+
437
+ const datasourceLoad = async ({ datasource, Models }) => {
438
+
439
+ const obj = {}
440
+
441
+ if(Array.isArray(datasource)){
442
+ for(let _datasource of datasource){
443
+
444
+ const Model = Models[_datasource.model]
445
+
446
+ const where = {}
447
+ if(Array.isArray(_datasource.filters)){
448
+ for(let filter of _datasource.filters){
449
+
450
+ switch(filter.operator){
451
+
452
+ case '=':
453
+ where[filter.key] = filter.value
454
+ break
455
+
456
+ }
457
+ }
458
+ }
459
+
460
+ const rows = await Model.findAll({
461
+ where,
462
+ limit: 20
463
+ })
464
+
465
+ obj[_datasource.key] = rows.length === 1 ? rows[0].toJSON() :
466
+ (rows.length === 0 ? {} : rows.map(_ => _.toJSON()))
467
+ }
468
+ }
469
+
470
+ return obj
471
+ }
472
+
395
473
 
396
474
  module.exports = {
397
475
  ceil,
@@ -417,4 +495,6 @@ module.exports = {
417
495
  createComponentInstance,
418
496
  deepObjectContainsObject,
419
497
  removeStyleFromTag,
498
+ datasourceGet,
499
+ datasourceLoad,
420
500
  }
@@ -341,6 +341,19 @@ function rgbToHex(r, g, b) {
341
341
  return "#" + hexR + hexG + hexB;
342
342
  }
343
343
 
344
+ function applyDatasourceReplacer(value, datasource){
345
+ if(typeof value !== 'string') return value
346
+
347
+ let matches = value.match(/\{\{([^}]+)\}\}/g);
348
+ (matches ?? []).forEach(matchKey => {
349
+ matchKey = matchKey.slice(2, -2)
350
+ const matchValue = accessNestedObject(datasource, matchKey) ?? ''
351
+ value = value.replace(`{{${matchKey}}}`, matchValue, 'gi')
352
+ });
353
+
354
+ return value
355
+ }
356
+
344
357
  export {
345
358
  downsizeImage,
346
359
  hexToRgb,
@@ -361,7 +374,8 @@ export {
361
374
  sleep,
362
375
  removeStyleFromTag,
363
376
  createFormData,
364
- unslugAndCapitalize
377
+ unslugAndCapitalize,
378
+ applyDatasourceReplacer
365
379
  }
366
380
 
367
381
  function observeInit(){
package/src/utils/web.js CHANGED
@@ -1,11 +1,13 @@
1
1
  const { accessNestedObject } = require("./helpers");
2
2
 
3
3
  const applyDatasourceReplacer = (value, datasource) => {
4
- let matches = value.match(/\{([^}]+)\}/g);
4
+ console.log('applyDatasourceReplacer', value, datasource)
5
+
6
+ let matches = value.match(/\{\{([^}]+)\}\}/g);
5
7
  (matches ?? []).forEach(matchKey => {
6
8
  matchKey = matchKey.slice(1, -1)
7
9
  const matchValue = accessNestedObject(datasource, matchKey) ?? ''
8
- value = value.replace(`{${matchKey}}`, matchValue, 'gi')
10
+ value = value.replace(`{{${matchKey}}}`, matchValue, 'gi')
9
11
  });
10
12
 
11
13
  return value
@@ -61,10 +61,6 @@
61
61
  </div>
62
62
  </div>
63
63
 
64
- <div>
65
- <Article v-model="item.props.text" />
66
- </div>
67
-
68
64
  <div class="flex flex-row gap-4">
69
65
  <label class="flex-1 text-text-400">Color</label>
70
66
  <ColorPicker v-for="(_viewType, index) in viewTypes"