@mixd-id/web-scaffold 0.2.240705 → 0.2.250801009

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.
Files changed (220) hide show
  1. package/docs/components/Dashboard.md +56 -0
  2. package/log.txt +7 -0
  3. package/package.json +27 -19
  4. package/src/components/404.vue +61 -0
  5. package/src/components/AccountIcon.vue +19 -0
  6. package/src/components/Ahref.vue +1 -1
  7. package/src/components/Alert.vue +4 -13
  8. package/src/components/ArrayList.vue +49 -0
  9. package/src/components/Article.vue +24 -30
  10. package/src/components/Button.vue +79 -167
  11. package/src/components/Card.vue +235 -0
  12. package/src/components/Carousel.vue +61 -60
  13. package/src/components/Cart.vue +192 -0
  14. package/src/components/CartIcon.vue +89 -0
  15. package/src/components/ChartBar.vue +2 -3
  16. package/src/components/Checkbox.vue +20 -11
  17. package/src/components/Checkout.vue +373 -0
  18. package/src/components/CheckoutDelivery.vue +267 -0
  19. package/src/components/CodeEditor.vue +5 -16
  20. package/src/components/CollapsiblePanel.vue +70 -0
  21. package/src/components/ColorPicker.vue +8 -3
  22. package/src/components/ColorPicker2.vue +41 -19
  23. package/src/components/ColorPicker3.vue +100 -0
  24. package/src/components/Confirm.vue +9 -7
  25. package/src/components/ContextMenu.vue +122 -206
  26. package/src/components/ContextMenuItem.vue +53 -0
  27. package/src/components/Dashboard.vue +243 -0
  28. package/src/components/Dashboard2.vue +118 -0
  29. package/src/components/DashboardComponentSelector.vue +96 -0
  30. package/src/components/DashboardConfigs.vue +202 -0
  31. package/src/components/Datepicker.vue +102 -41
  32. package/src/components/DayTimeRange.vue +3 -2
  33. package/src/components/Dropdown.vue +7 -4
  34. package/src/components/Flex.vue +14 -40
  35. package/src/components/GHeatMaps.vue +2 -2
  36. package/src/components/Grid.vue +6 -6
  37. package/src/components/HTMLEditor.vue +27 -14
  38. package/src/components/Image.vue +62 -108
  39. package/src/components/ImagePreview.vue +14 -4
  40. package/src/components/ImageUploader.vue +114 -0
  41. package/src/components/ImportModal.vue +3 -3
  42. package/src/components/Link.vue +62 -6
  43. package/src/components/List.vue +524 -402
  44. package/src/components/ListContextMenu.vue +88 -0
  45. package/src/components/ListItem.vue +5 -3
  46. package/src/components/ListPage1.vue +14 -15
  47. package/src/components/ListView.vue +5 -6
  48. package/src/components/ListViewSettings.vue +2 -2
  49. package/src/components/LogViewerItem.vue +1 -1
  50. package/src/components/MarkdownEdit.vue +128 -0
  51. package/src/components/MarkdownPreview.vue +102 -0
  52. package/src/components/MenuItem1.vue +36 -0
  53. package/src/components/Modal.vue +95 -43
  54. package/src/components/MultiDropdown.vue +124 -0
  55. package/src/components/MultilineText.vue +1 -4
  56. package/src/components/OTPField.vue +11 -17
  57. package/src/components/ObjectTree.vue +1 -1
  58. package/src/components/PageBuilder.vue +3 -3
  59. package/src/components/Paragraph.vue +1 -2
  60. package/src/components/PresetSelectorFilterItem.vue +107 -95
  61. package/src/components/Radio.vue +1 -1
  62. package/src/components/SearchModal.vue +153 -0
  63. package/src/components/Slider.vue +1 -1
  64. package/src/components/Svg.vue +1 -1
  65. package/src/components/SvgEditor.vue +173 -0
  66. package/src/components/Switch.vue +4 -5
  67. package/src/components/Table.vue +2 -2
  68. package/src/components/TableView.vue +2 -3
  69. package/src/components/TableViewHead.vue +2 -2
  70. package/src/components/Tabs.vue +1 -1
  71. package/src/components/Testimonial.vue +2 -2
  72. package/src/components/Text.vue +7 -22
  73. package/src/components/TextEditor.vue +3 -3
  74. package/src/components/TextWithTag.vue +61 -30
  75. package/src/components/Textarea.vue +11 -16
  76. package/src/components/Textbox.vue +9 -19
  77. package/src/components/Timepicker.vue +25 -15
  78. package/src/components/Toast.vue +5 -3
  79. package/src/components/TreeMenu.vue +122 -0
  80. package/src/components/TreeView.vue +15 -10
  81. package/src/components/TreeView2.vue +38 -0
  82. package/src/components/TreeViewItem.vue +58 -29
  83. package/src/components/TreeViewItem2.vue +55 -0
  84. package/src/components/Uploader.vue +45 -0
  85. package/src/components/Video.vue +119 -0
  86. package/src/components/VirtualGrid.vue +24 -7
  87. package/src/components/VirtualTable.vue +363 -128
  88. package/src/configs/dashboard/data-table.js +9 -0
  89. package/src/configs/web-page-builder.js +118 -0
  90. package/src/directives/intersect.js +26 -0
  91. package/src/hooks/device.js +14 -0
  92. package/src/index.js +62 -107
  93. package/src/mixin/component.js +147 -67
  94. package/src/themes/default/index.js +83 -155
  95. package/src/utils/dashboard.js +22 -962
  96. package/src/utils/helpers.cjs +635 -0
  97. package/src/utils/helpers.js +91 -60
  98. package/src/utils/helpers.mjs +245 -12
  99. package/src/utils/importer.js +22 -3
  100. package/src/utils/list.mjs +1509 -0
  101. package/src/utils/preset-selector.cjs +1455 -0
  102. package/src/utils/preset-selector.js +489 -95
  103. package/src/utils/preset-selector.mjs +59 -20
  104. package/src/utils/queue.js +63 -0
  105. package/src/utils/web.mjs +120 -0
  106. package/src/utils/wss.js +37 -29
  107. package/src/utils/wss.mjs +24 -19
  108. package/src/widgets/AhrefSetting.vue +16 -13
  109. package/src/widgets/ArticleSetting.vue +15 -27
  110. package/src/widgets/BackgroundColorSetting.vue +153 -0
  111. package/src/widgets/BorderColorSetting.vue +57 -0
  112. package/src/widgets/BotEditor/BotEditorActions.vue +3 -2
  113. package/src/widgets/BotEditor/BotEditorSettings.vue +21 -0
  114. package/src/widgets/BotEditor.vue +35 -15
  115. package/src/widgets/ButtonSetting.vue +12 -13
  116. package/src/widgets/CarouselSetting.vue +33 -45
  117. package/src/widgets/CartSetting.vue +46 -0
  118. package/src/widgets/CheckoutSetting.vue +46 -0
  119. package/src/widgets/CollapsiblePanelSetting.vue +46 -0
  120. package/src/widgets/ColumnSelector.vue +29 -5
  121. package/src/widgets/ComponentSetting.vue +1 -1
  122. package/src/widgets/ComponentSetting2.vue +112 -234
  123. package/src/widgets/ComponentSetting3.vue +1 -1
  124. package/src/widgets/ContactForm.vue +3 -3
  125. package/src/widgets/ContactFormSetting.vue +41 -30
  126. package/src/widgets/Dashboard/BarChart.vue +47 -11
  127. package/src/widgets/Dashboard/BarChartSetting.vue +1 -1
  128. package/src/widgets/Dashboard/DataTable.vue +125 -0
  129. package/src/widgets/Dashboard/DataTableSetting.vue +243 -0
  130. package/src/widgets/Dashboard/DatasourceSelector.vue +1 -1
  131. package/src/widgets/Dashboard/Doughnut.vue +49 -7
  132. package/src/widgets/Dashboard/DoughnutSetting.vue +2 -2
  133. package/src/widgets/Dashboard/Metric.vue +78 -19
  134. package/src/widgets/Dashboard/MetricSetting.vue +81 -28
  135. package/src/widgets/Dashboard/Pie.vue +55 -6
  136. package/src/widgets/Dashboard/PieSetting.vue +1 -1
  137. package/src/widgets/Dashboard/PolarArea.vue +49 -7
  138. package/src/widgets/Dashboard/PolarAreaSetting.vue +1 -1
  139. package/src/widgets/Dashboard/SharingModal.vue +4 -5
  140. package/src/widgets/Dashboard/ViewSelector.vue +2 -2
  141. package/src/widgets/Dashboard/VirtualTableSetting.vue +121 -184
  142. package/src/widgets/{Dashboard.vue → Dashboard0.vue} +426 -343
  143. package/src/widgets/EmbeddedVideoSetting.vue +7 -5
  144. package/src/widgets/FAQ.vue +16 -3
  145. package/src/widgets/FAQSetting.vue +53 -47
  146. package/src/widgets/FeatureList.vue +3 -0
  147. package/src/widgets/FeatureListSetting.vue +112 -102
  148. package/src/widgets/FlexSetting.vue +83 -106
  149. package/src/widgets/GridSetting.vue +71 -196
  150. package/src/widgets/Header2.vue +34 -71
  151. package/src/widgets/Header2Setting.vue +95 -179
  152. package/src/widgets/HeaderSetting.vue +16 -18
  153. package/src/widgets/IconListSetting.vue +69 -65
  154. package/src/widgets/ImageSetting.vue +33 -60
  155. package/src/widgets/LinkSetting.vue +60 -37
  156. package/src/widgets/LinkSettingModal.vue +173 -0
  157. package/src/widgets/LogViewer.vue +1 -1
  158. package/src/widgets/MarginSetting.vue +2 -2
  159. package/src/widgets/MenuEditor.vue +1 -1
  160. package/src/widgets/MenuItem1Setting.vue +78 -0
  161. package/src/widgets/ModalSetting.vue +42 -44
  162. package/src/widgets/MultiValueSetting.vue +2 -2
  163. package/src/widgets/MultiValueSetting2.vue +78 -45
  164. package/src/widgets/OGSettingModal.vue +103 -0
  165. package/src/widgets/PaddingSetting.vue +2 -2
  166. package/src/widgets/ParagraphSetting.vue +16 -13
  167. package/src/widgets/PositionSetting.vue +209 -0
  168. package/src/widgets/PresetBar.vue +359 -210
  169. package/src/widgets/PresetBarPivot.vue +31 -19
  170. package/src/widgets/PresetSelector.vue +29 -17
  171. package/src/widgets/SearchModalSetting.vue +70 -0
  172. package/src/widgets/Share.vue +1 -2
  173. package/src/widgets/ShareSetting.vue +67 -60
  174. package/src/widgets/StyleSetting.vue +227 -116
  175. package/src/widgets/TestimonialSetting.vue +97 -88
  176. package/src/widgets/TextBlockSetting.vue +16 -13
  177. package/src/widgets/UserActionBuilder/UserActionConsole.vue +30 -10
  178. package/src/widgets/UserActionBuilder/UserActionOutput.vue +2 -2
  179. package/src/widgets/UserActionBuilder/UserActionOutputReply.vue +64 -87
  180. package/src/widgets/UserActionBuilder/UserActionProps.vue +3 -3
  181. package/src/widgets/UserActionBuilder.vue +4 -16
  182. package/src/widgets/WebComponentSelector.vue +15 -11
  183. package/src/widgets/WebLayoutSelector.vue +41 -270
  184. package/src/widgets/WebPageBuilder.vue +693 -704
  185. package/src/widgets/WebPageBuilder2.vue +7 -7
  186. package/src/widgets/WebPageBuilder4/ButtonSetting.vue +0 -8
  187. package/src/widgets/WebPageBuilder4/CarouselSetting.vue +63 -7
  188. package/src/widgets/WebPageBuilder4/FlexAlignSetting.vue +3 -3
  189. package/src/widgets/WebPageBuilder4/FlexSetting.vue +1 -10
  190. package/src/widgets/WebPageBuilder4/MultiValueSetting.vue +2 -2
  191. package/src/widgets/WebPageBuilder4/PropertySetting.vue +0 -7
  192. package/src/widgets/WebPageBuilder4/WebPageComponentSelector.vue +1 -7
  193. package/src/widgets/WebPageBuilder4.vue +289 -575
  194. package/src/widgets/WebPageSelector.vue +1 -1
  195. package/src/widgets/YoutubeVideoSetting.vue +16 -13
  196. package/tailwind.config.js +3 -35
  197. package/docs/schema/user-action.json +0 -266
  198. package/src/App.vue +0 -25
  199. package/src/components/SearchButton.vue +0 -57
  200. package/src/entry-client.js +0 -27
  201. package/src/entry-server.js +0 -73
  202. package/src/events/event.js +0 -2
  203. package/src/main.js +0 -29
  204. package/src/mixin/website.js +0 -121
  205. package/src/router.js +0 -57
  206. package/src/widgets/MobileMenu.vue +0 -182
  207. package/src/widgets/WebPageBuilder4/ActionSetting.vue +0 -158
  208. package/src/widgets/WebPageBuilder4/ColorSetting.vue +0 -63
  209. package/src/widgets/WebPageBuilder4/DataSetting.vue +0 -92
  210. package/src/widgets/WebPageBuilder4/FontSizeSetting.vue +0 -76
  211. package/src/widgets/WebPageBuilder4/LinkSetting.vue +0 -68
  212. package/src/widgets/WebPageBuilder4/MobileMenuSetting.vue +0 -106
  213. package/src/widgets/WebPageBuilder4/Setting.vue +0 -73
  214. package/src/widgets/WebPageBuilder4/StyleSetting.vue +0 -77
  215. package/src/widgets/WebPageBuilder4/SvgSetting.vue +0 -207
  216. package/src/widgets/WebPageBuilder4/TextTransformSetting.vue +0 -70
  217. package/src/widgets/WebPageBuilder4/WebPageDataEdit.vue +0 -121
  218. package/test.json +0 -22
  219. /package/src/widgets/{Header1.vue → Header0.vue} +0 -0
  220. /package/src/widgets/{Header1Setting.vue → Header0Setting.vue} +0 -0
@@ -5,7 +5,11 @@
5
5
  @mousedown="onMouseDown"
6
6
  :style="computedStyle">
7
7
 
8
- <slot v-if="status === 0" name="empty" :instance="this"></slot>
8
+ <slot v-if="status === 0" name="empty" :instance="this">
9
+ <div :class="$style.loading">
10
+ <svg width="50%" height="50%" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M447.1 32h-384C28.64 32-.0091 60.65-.0091 96v320c0 35.35 28.65 64 63.1 64h384c35.35 0 64-28.65 64-64V96C511.1 60.65 483.3 32 447.1 32zM111.1 96c26.51 0 48 21.49 48 48S138.5 192 111.1 192s-48-21.49-48-48S85.48 96 111.1 96zM446.1 407.6C443.3 412.8 437.9 416 432 416H82.01c-6.021 0-11.53-3.379-14.26-8.75c-2.73-5.367-2.215-11.81 1.334-16.68l70-96C142.1 290.4 146.9 288 152 288s9.916 2.441 12.93 6.574l32.46 44.51l93.3-139.1C293.7 194.7 298.7 192 304 192s10.35 2.672 13.31 7.125l128 192C448.6 396 448.9 402.3 446.1 407.6z"/></svg>
11
+ </div>
12
+ </slot>
9
13
 
10
14
  <slot v-else-if="status === 1" name="loading">
11
15
  <div :class="$style.loading + (spinnerType === 'shimmer' ? ' ' + $style.shimmer : '')">
@@ -14,9 +18,13 @@
14
18
  </slot>
15
19
 
16
20
  <div v-else-if="status === 2 && actualSrc.indexOf('<svg') >= 0" v-html="actualSrc"></div>
17
- <img v-else-if="status === 2" :class="computedItemClass" :src="actualSrc" ref="img" :alt="alt" />
21
+ <img v-else-if="status === 2" :class="computedItemClass" :src="actualSrc" ref="img" :alt="alt" @error="status = 3" />
18
22
 
19
- <slot v-else-if="status === 3" name="error" :instance="this"></slot>
23
+ <slot v-else-if="status === 3" name="error" :instance="this">
24
+ <div :class="$style.loading">
25
+ <svg width="50%" height="50%" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M630.8 469.1l-55.95-43.85C575.3 422.2 575.1 419.2 575.1 416l.0034-320c0-35.35-28.65-64-64-64H127.1C113.6 32 100.4 36.98 89.78 45.06L38.81 5.113C28.34-3.058 13.31-1.246 5.109 9.192C-3.063 19.63-1.235 34.72 9.187 42.89L601.2 506.9C605.6 510.3 610.8 512 615.1 512c7.125 0 14.17-3.156 18.91-9.188C643.1 492.4 641.2 477.3 630.8 469.1zM223.1 149.6l-64.29-50.39C164.2 97.15 169.9 96 175.1 96c26.51 0 48 21.49 48 48C223.1 145.9 223.4 147.7 223.1 149.6zM331.2 234.3l23.45-35.18C357.7 194.7 362.7 192 368 192s10.35 2.672 13.31 7.125l103.9 155.9L331.2 234.3zM145.1 416c-6.021 0-11.53-3.379-14.26-8.75c-2.73-5.367-2.215-11.81 1.334-16.68l70-96C206.1 290.4 210.9 288 216 288s9.916 2.441 12.93 6.574l32.46 44.51l16.43-24.65L63.99 146.8L63.99 416c0 35.35 28.65 64 64 64h361.1l-81.66-64H145.1z"/></svg>
26
+ </div>
27
+ </slot>
20
28
 
21
29
  <input v-if="Boolean(editable)" class="hidden" type="file" accept="image/*" ref="file" @change="onChange"/>
22
30
 
@@ -41,7 +49,7 @@ export default{
41
49
 
42
50
  mixins: [ componentMixin ],
43
51
 
44
- emits: [ 'change' ],
52
+ emits: [ 'click', 'change' ],
45
53
 
46
54
  props:{
47
55
 
@@ -150,116 +158,63 @@ export default{
150
158
  },
151
159
 
152
160
  async loadSrc(){
161
+ if(!this.isVisible) return
153
162
 
154
- if(!this.isVisible){
155
- return
156
- }
163
+ const setSrc = (src) => {
164
+ let reader
157
165
 
158
- if(typeof this.src === 'string') {
166
+ if(typeof src === 'string') {
167
+ if(src.indexOf('://') < 0 && src.substring(0, 1) !== '/' &&
168
+ src.indexOf('<svg') < 0 && src.indexOf(';base64') < 0){
169
+ src = ((import.meta.env.VITE_IMAGE_HOST ?? '') + '/' + src)
170
+ }
159
171
 
160
- if (this.src.startsWith('data:image')) {
161
- this.actualSrc = this.src
162
- this.status = 2
163
- }
164
- else if(this.src.indexOf('<svg') >= 0){
165
- this.actualSrc = this.src
172
+ this.actualSrc = src
166
173
  this.status = 2
167
174
  }
168
- else{
169
- const src = {}
170
-
171
- if(typeof this.src === 'string'){
172
- this.src.split(',').forEach((text) => {
173
- let [ prefix, ...args ] = text.split(':')
174
-
175
- if(args.length > 0 && args[0].substring(0, 2) !== '//'){
176
- src[prefix.trim()] = args.join(':').trim()
177
- }
178
- else{
179
- src['all'] = text
180
- }
181
- })
182
- }
183
-
184
- let imgSrc
185
- for(const b in screens){
186
- if(document.documentElement.clientWidth > b && screens[b] in src){
187
- imgSrc = src[screens[b]]
188
- }
189
- }
190
-
191
- if(imgSrc !== this.actualSrc){
192
- var img = new Image()
193
- img.addEventListener('load', () => {
194
- if(img.getAttribute('data-src') !== this.src) return
195
- this.status = 2
196
- this.actualSrc = img.src
197
- })
198
- img.addEventListener('error', (err) => {
199
- if(img.getAttribute('data-src') !== this.src) return
200
- this.status = 3
201
- this.actualSrc = this.defaultSrc
202
- })
203
- img.src = imgSrc
204
- img.setAttribute('data-src', this.src)
205
- this.status = 1
206
- }
207
- }
208
- }
209
- else if(Array.isArray(this.src)){
210
-
211
- const src = {}
212
- src['all'] = this.src[0]
213
- if(this.src[1]){
214
- src['md'] = this.src[1]
215
- }
216
-
217
- let imgSrc
218
- for(const b in screens){
219
- if(document.documentElement.clientWidth > b && screens[b] in src){
220
- imgSrc = src[screens[b]]
221
- }
222
- }
223
-
224
- if(imgSrc !== this.actualSrc){
225
- var img = new Image()
226
- img.addEventListener('load', () => {
227
- this.status = 2
228
- this.actualSrc = img.src
229
- })
230
- img.addEventListener('error', (err) => {
231
- this.status = 3
232
- this.actualSrc = this.defaultSrc
233
- })
234
- img.src = imgSrc
235
- this.status = 1
236
- }
237
- }
238
- else if(this.src instanceof File){
239
- var reader = new FileReader();
240
175
 
241
- reader.addEventListener('load', () => {
242
- this.status = 2
243
- this.actualSrc = reader.result
244
- }, false)
176
+ else if(src instanceof File){
177
+ reader = new FileReader();
245
178
 
246
- reader.addEventListener('error', () => {
247
- this.status = 3
248
- this.actualSrc = this.defaultSrc
249
- })
179
+ reader.addEventListener('load', () => {
180
+ this.status = 2
181
+ this.actualSrc = reader.result
182
+ }, false)
250
183
 
251
- reader.readAsDataURL(this.src)
252
- this.status = 1
253
- }
184
+ reader.addEventListener('error', () => {
185
+ this.status = 3
186
+ this.actualSrc = this.defaultSrc
187
+ })
188
+
189
+ reader.readAsDataURL(src)
190
+ this.status = 1
191
+ }
192
+ }
193
+
194
+ if(Array.isArray(this.src)){
195
+ let imgSrc
196
+ for(let i = this.$device.mediaIndex ; i >= 0 ; i--){
197
+ if(this.src[i]){
198
+ imgSrc = this.src[i]
199
+ break
200
+ }
201
+ }
202
+ setSrc(imgSrc)
203
+ }
204
+ else if(this.src){
205
+ setSrc(this.src)
206
+ }
254
207
  else{
255
208
  this.status = 0
256
209
  }
257
210
  },
258
211
 
259
- onClick(){
212
+ onClick(e){
260
213
  if(!this.moved && this.target){
261
214
  this.$router.push(this.target)
262
215
  }
216
+
217
+ this.$emit('click', e, this)
263
218
  },
264
219
 
265
220
  onMouseDown(){
@@ -274,9 +229,12 @@ export default{
274
229
 
275
230
  watch:{
276
231
 
277
- src(to, from){
278
- this.loadSrc()
279
- },
232
+ src: {
233
+ handler(){
234
+ this.loadSrc()
235
+ },
236
+ deep: true
237
+ },
280
238
 
281
239
  }
282
240
  }
@@ -286,15 +244,11 @@ export default{
286
244
  <style module>
287
245
 
288
246
  .comp{
289
- @apply relative overflow-hidden;
247
+ @apply relative flex items-center justify-center overflow-hidden;
290
248
  }
291
249
 
292
250
  .img{
293
- @apply w-full h-full;
294
- }
295
-
296
- .editArea{
297
- @apply absolute top-0 left-0 right-0 bottom-0;
251
+ @apply w-full h-full object-contain;
298
252
  }
299
253
 
300
254
  .loading{
@@ -303,7 +257,7 @@ export default{
303
257
  }
304
258
 
305
259
  .shimmer{
306
- @apply bg-text-200 animate-pulse;
260
+ @apply bg-text-300 animate-pulse;
307
261
  }
308
262
 
309
263
  </style>
@@ -3,7 +3,7 @@
3
3
  <div class="flex-1 flex flex-col gap-3">
4
4
  <div class="flex flex-row gap-4 justify-end items-center p-3 pr-6">
5
5
  <slot name="moreButtons"></slot>
6
- <a v-if="download" :href="imageUrl" target="_blank" download>
6
+ <a v-if="canDownload" :href="imageUrl" target="_blank" download>
7
7
  <svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" class="fill-text" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M480 352h-133.5l-45.25 45.25C289.2 409.3 273.1 416 256 416s-33.16-6.656-45.25-18.75L165.5 352H32c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h448c17.67 0 32-14.33 32-32v-96C512 366.3 497.7 352 480 352zM432 456c-13.2 0-24-10.8-24-24c0-13.2 10.8-24 24-24s24 10.8 24 24C456 445.2 445.2 456 432 456zM233.4 374.6C239.6 380.9 247.8 384 256 384s16.38-3.125 22.62-9.375l128-128c12.49-12.5 12.49-32.75 0-45.25c-12.5-12.5-32.76-12.5-45.25 0L288 274.8V32c0-17.67-14.33-32-32-32C238.3 0 224 14.33 224 32v242.8L150.6 201.4c-12.49-12.5-32.75-12.5-45.25 0c-12.49 12.5-12.49 32.75 0 45.25L233.4 374.6z"/></svg>
8
8
  </a>
9
9
  <button @click="close">
@@ -24,7 +24,7 @@ export default{
24
24
  props: {
25
25
 
26
26
  download: {
27
- type: Boolean,
27
+ type: [ Boolean, String ],
28
28
  default: false
29
29
  },
30
30
 
@@ -32,8 +32,17 @@ export default{
32
32
 
33
33
  },
34
34
 
35
+ computed: {
36
+
37
+ canDownload(){
38
+ return this.download || this.downloadable
39
+ }
40
+
41
+ },
42
+
35
43
  data(){
36
44
  return {
45
+ downloadable: false,
37
46
  isOpen: false,
38
47
  imageUrl: null
39
48
  }
@@ -41,9 +50,10 @@ export default{
41
50
 
42
51
  methods: {
43
52
 
44
- open(imageUrl){
53
+ open(imageUrl, opt = {}){
45
54
  this.imageUrl = imageUrl
46
55
  this.isOpen = true
56
+ this.downloadable = opt.download || this.downloadable
47
57
  window.addEventListener('keyup', this.onKeyUp)
48
58
  },
49
59
 
@@ -75,7 +85,7 @@ export default{
75
85
 
76
86
  .previewModal{
77
87
  @apply !w-screen !h-screen !bg-base-300 !rounded-none top-0;
78
- z-index: 21 !important;
88
+ z-index: 121 !important;
79
89
  max-width: unset !important;
80
90
  max-height: unset !important;
81
91
  }
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <button ref="btn"
3
+ type="button"
4
+ class="text-primary text-sm"
5
+ @click="$refs.contextMenu.open($refs.btn)">
6
+ <slot>Upload</slot>
7
+ </button>
8
+
9
+ <input type="file" class="hidden" ref="file" accept="image/*" @change="onFileUpload" />
10
+
11
+ <ContextMenu ref="contextMenu" position="bottom-right">
12
+ <div class="flex flex-col min-w-[200px]">
13
+
14
+ <button class="menu-item w-full p-3 text-left flex flex-row"
15
+ @click="$refs.file.click()">
16
+ Upload Image File...
17
+ </button>
18
+
19
+ <button class="menu-item w-full p-3 text-left flex flex-row"
20
+ @click="$refs.modal.open()">
21
+ SVG Text
22
+ </button>
23
+ </div>
24
+ </ContextMenu>
25
+
26
+ <Modal ref="modal" width="480" height="480">
27
+ <template v-slot:head>
28
+ <div class="relative p-5">
29
+ <h3>Add SVG Text</h3>
30
+ <div class="absolute top-0 right-0 p-2">
31
+ <button type="button" class="p-2" @click="$refs.modal.close()">
32
+ <svg width="24" height="24" viewBox="0 0 24 24" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg">
33
+ <path d="M6.53034 5.46965C6.23745 5.17676 5.76257 5.17676 5.46968 5.46965C5.17679 5.76255 5.17679 6.23742 5.46968 6.53031L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0606L17.4697 18.5303C17.7626 18.8232 18.2375 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53032C18.8232 6.23743 18.8232 5.76256 18.5303 5.46966C18.2374 5.17677 17.7626 5.17677 17.4697 5.46966L12 10.9393L6.53034 5.46965Z"/>
34
+ </svg>
35
+ </button>
36
+ </div>
37
+ </div>
38
+ </template>
39
+ <template v-slot:foot="{ context }">
40
+ <div class="p-5">
41
+ <Button class="w-[90px]"
42
+ :state="`${context.value}`.length > 0 ? 1 : -1"
43
+ @click="addSvg(context)">
44
+ Add
45
+ </Button>
46
+ </div>
47
+ </template>
48
+
49
+ <template #default="{ context }">
50
+ <div class="flex-1 p-5 flex flex-col gap-3">
51
+
52
+ <div>
53
+ <SvgEditor v-model="context.value" class="" />
54
+ </div>
55
+
56
+ </div>
57
+ </template>
58
+ </Modal>
59
+ </template>
60
+
61
+ <script setup>
62
+
63
+ import {useTemplateRef} from "vue";
64
+ import ContextMenu from "./ContextMenu.vue";
65
+ import SvgEditor from "./SvgEditor.vue";
66
+
67
+ const { uploadFn } = defineProps({
68
+ uploadFn: Function
69
+ })
70
+
71
+ const file = useTemplateRef('file')
72
+ const modal = useTemplateRef('modal')
73
+ const emits = defineEmits([ 'change' ])
74
+
75
+ function onFileUpload(e){
76
+ if(typeof uploadFn === 'function'){
77
+ uploadFn(e.target.files[0])
78
+ .then(res => {
79
+ emits('change', res.name)
80
+ file.value.value = null
81
+ })
82
+ .catch(e => {
83
+ console.error(e)
84
+ })
85
+ }
86
+ else{
87
+ emits('change', e.target.files[0])
88
+ file.value.value = null
89
+ }
90
+ }
91
+
92
+ function addSvg(obj){
93
+ emits('change', obj.value)
94
+ modal.value.close()
95
+ }
96
+
97
+ function edit(value){
98
+ if(`${value}`.indexOf('<svg') >= 0){
99
+ modal.value.open({ value })
100
+ }
101
+ }
102
+
103
+ defineExpose({
104
+ edit
105
+ })
106
+
107
+ </script>
108
+
109
+ <style module>
110
+
111
+ .comp {
112
+ }
113
+
114
+ </style>
@@ -26,7 +26,7 @@
26
26
  </template>
27
27
 
28
28
  <div class="flex-1 p-5 flex flex-col items-center justify-center" v-if="step === 1">
29
- <button type="button" @click="$refs.uploader.click()" class="rounded-3xl w-[160px] bg-base-300 px-6 aspect-square flex items-center justify-center text-center border-dashed border-[3px] border-text-100">
29
+ <button type="button" @click="$refs.uploader.click()" class="rounded-3xl w-[160px] bg-base-300 px-6 aspect-square flex items-center justify-center text-center border-dashed border-[3px] border-border-100">
30
30
  <div class="text-xl" v-if="!isLoading">
31
31
  Click to <br />
32
32
  <span class="text-primary text-lg">Upload</span>
@@ -174,7 +174,7 @@ export default{
174
174
 
175
175
  this.isLoading = true
176
176
  axios({
177
- url: import.meta.env.VITE_API_HOST + this.urlAnalyse,
177
+ url: this.urlAnalyse,
178
178
  method: 'POST',
179
179
  data
180
180
  })
@@ -224,7 +224,7 @@ export default{
224
224
 
225
225
  this.isLoading = true
226
226
  axios({
227
- url: import.meta.env.VITE_API_HOST + this.urlImport,
227
+ url: this.urlImport,
228
228
  method: 'POST',
229
229
  data: this.importData
230
230
  })
@@ -1,29 +1,85 @@
1
1
  <template>
2
- <router-link :to="target">
2
+ <router-link v-if="mode === 'route' && (items ?? []).length <= 0" :to="route">
3
3
  {{ text }}
4
4
  </router-link>
5
+ <router-link v-else-if="mode === 'route' && (items ?? []).length > 0" :to="route">
6
+ <component v-for="(item, idx) in items"
7
+ :is="item.type"
8
+ :key="idx"
9
+ :="item" />
10
+ </router-link>
11
+
12
+ <a v-else-if="mode === 'link' && (items ?? []).length <= 0" :href="link.href" :target="link.target">
13
+ {{ text }}
14
+ </a>
15
+ <a v-else-if="mode === 'link' && (items ?? []).length > 0" :href="link.href" :target="link.target">
16
+ <component v-for="(item, idx) in items"
17
+ :is="item.type"
18
+ :key="idx"
19
+ :="item" />
20
+ </a>
21
+
22
+ <a v-else-if="mode === 'download' && (items ?? []).length <= 0"
23
+ :download="download.originalName ?? download.name"
24
+ :href="download.url">
25
+ {{ text }}
26
+ </a>
27
+ <a v-else-if="mode === 'download' && (items ?? []).length > 0"
28
+ :download="download.originalName ?? download.name"
29
+ :href="download.url">
30
+ <component v-for="(item, idx) in items"
31
+ :is="item.type"
32
+ :key="idx"
33
+ :="item" />
34
+ </a>
35
+
5
36
  </template>
6
37
 
7
38
  <script>
8
39
 
9
- import { componentMixin } from "../mixin/component";
40
+ import {componentMixin} from "../mixin/component";
41
+ import {applyDatasourceReplacer} from "../utils/helpers";
10
42
 
11
43
  export default{
12
44
 
13
45
  mixins: [ componentMixin ],
14
46
 
15
47
  props: {
48
+ text: String,
49
+ items: Array,
16
50
 
17
- target: String,
18
-
19
- text: String
20
-
51
+ mode: String,
52
+ route: Object,
53
+ link: Object,
54
+ download: Object,
21
55
  },
22
56
 
23
57
  computed: {
24
58
 
59
+ isExternalLink(){
60
+ return (this.href ?? '').indexOf('://') > -1;
61
+ },
62
+
63
+ to(){
64
+ const obj = {}
65
+
66
+ if(this.route.hash)
67
+ obj.hash = '#' + (this.editMode === 1 ? this.route.hash :
68
+ applyDatasourceReplacer(this.route.hash, this.data))
25
69
 
70
+ if(this.route.path)
71
+ obj.path = this.editMode === 1 ? this.route.path :
72
+ applyDatasourceReplacer(this.route.path, this.data)
73
+
74
+ return obj
75
+ }
76
+
77
+ },
26
78
 
79
+ provide(){
80
+ return {
81
+ parentData: this.data
82
+ }
27
83
  }
28
84
 
29
85
  }