@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
@@ -1,157 +1,107 @@
1
1
  <template>
2
2
  <div :class="$style.comp">
3
3
 
4
- <div v-if="page"
5
- :class="$style.leftPane"
6
- :style="leftStyle"
7
- @click="printConfig">
4
+ <div :class="$style.leftPane"
5
+ @click="printConfig"
6
+ :style="leftStyle">
8
7
  <div :class="$style.leftBoundary" @mousedown="(e) => $util.dragResize(e, resize1)"></div>
9
8
 
10
- <div v-if="config.mode === 'layout'" class="flex-1 flex flex-col">
11
- <div class="border-b-[1px] border-text-50">
9
+ <div v-if="config.mode === 'layout'">
10
+ <div class="border-b-[1px] border-border-50">
12
11
  <div class="p-3 flex flex-row items-center gap-3">
13
12
  <button type="button" @click="delete config.mode">
14
- <svg class="fill-text" height="16" viewBox="0 0 448 512" width="16" xmlns="http://www.w3.org/2000/svg">
15
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
16
- <path
17
- d="M447.1 256C447.1 273.7 433.7 288 416 288H109.3l105.4 105.4c12.5 12.5 12.5 32.75 0 45.25C208.4 444.9 200.2 448 192 448s-16.38-3.125-22.62-9.375l-160-160c-12.5-12.5-12.5-32.75 0-45.25l160-160c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L109.3 224H416C433.7 224 447.1 238.3 447.1 256z"/>
18
- </svg>
13
+ <svg width="16" height="16" class="fill-text" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M447.1 256C447.1 273.7 433.7 288 416 288H109.3l105.4 105.4c12.5 12.5 12.5 32.75 0 45.25C208.4 444.9 200.2 448 192 448s-16.38-3.125-22.62-9.375l-160-160c-12.5-12.5-12.5-32.75 0-45.25l160-160c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L109.3 224H416C433.7 224 447.1 238.3 447.1 256z"/></svg>
19
14
  </button>
20
15
  <div class="flex-1 flex flex-col leading-3">
21
16
  <small>Layout</small>
22
- <Textbox v-model="layout.name" class="flex-1 border-transparent bg-transparent text-lg bg-red-100"
23
- item-class="p-0"/>
17
+ <Textbox v-model="layout.name" class="flex-1 border-transparent bg-transparent text-lg bg-red-100" item-class="p-0" />
24
18
  </div>
25
19
  <Button ref="saveBtn"
26
- :state="canSave ? 1 : -1"
27
20
  class="w-[56px]"
21
+ :state="canSave ? 1 : -1"
28
22
  @click="save()">
29
23
  Save
30
24
  </Button>
31
25
  </div>
32
26
  </div>
33
27
 
34
- <div class="flex-1 overflow-y-auto">
35
- <div class="p-5">
36
- <div class="flex flex-row items-center gap-2">
37
- <div class="flex-1">
38
- <label @click="log(config)">Headers</label>
39
- </div>
40
- <button class="text-primary" type="button"
41
- @click="$refs.componentSelector.open((component) => layout.headers.push(component))">
42
- Add Component
43
- </button>
28
+ <div class="p-5">
29
+ <div class="flex flex-row items-center gap-2">
30
+ <div class="flex-1">
31
+ <label>Headers</label>
44
32
  </div>
45
- <TreeView v-model="config.selectedUid"
46
- :config="componentsConfig"
47
- :items="layout.headers"
48
- class="mt-2">
49
- <template #item="{ item, parent }">
50
- <div class="flex-1 p-1 px-3 mb-1 overflow-hidden text-ellipsis cursor-pointer flex flex-row gap-2"
51
- @click="addToCopy(item, parent)">
52
- <div class="flex-1">
53
- <strong>{{ item.name }}</strong>
54
- </div>
55
- <button v-if="item.isContainer"
56
- type="button"
57
- @click="$refs.componentSelector.open(c => item.items.push(c))">
58
- <svg class="fill-text-300 hover:fill-primary-600" height="14" viewBox="0 0 448 512" width="14"
59
- xmlns="http://www.w3.org/2000/svg">
60
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
61
- <path
62
- d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/>
63
- </svg>
64
- </button>
65
- <button type="button" @click="parent.splice(parent.indexOf(item), 1)">
66
- <svg class="fill-text-300 hover:fill-red-600" height="14" viewBox="0 0 320 512" width="14"
67
- xmlns="http://www.w3.org/2000/svg">
68
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
69
- <path
70
- d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/>
71
- </svg>
72
- </button>
73
- </div>
74
- </template>
75
- </TreeView>
33
+ <button type="button" class="text-primary"
34
+ @click="$refs.componentSelector.open((component) => layout.headers.push(component))">
35
+ Add Component
36
+ </button>
76
37
  </div>
77
-
78
- <div class="p-5">
79
- <div class="flex flex-row items-center gap-2">
80
- <div class="flex-1">
81
- <label>Footers</label>
82
- </div>
83
- <button class="text-primary" type="button"
84
- @click="$refs.componentSelector.open((component) => layout.footers.push(component))">
85
- Add Component
86
- </button>
87
- </div>
88
- <TreeView v-model="config.selectedUid"
89
- :config="componentsConfig"
90
- :items="layout.footers"
91
- class="mt-2">
92
- <template #item="{ item, parent }">
93
- <div class="flex-1 p-1 px-3 mb-1 overflow-hidden text-ellipsis cursor-pointer flex flex-row gap-2"
94
- @click="addToCopy(item, parent)">
95
- <div class="flex-1">
96
- <strong>{{ item.name }}</strong>
97
- </div>
98
- <button v-if="item.isContainer"
99
- type="button"
100
- @click="$refs.componentSelector.open(c => item.items.push(c))">
101
- <svg class="fill-text-300 hover:fill-primary-600" height="14" viewBox="0 0 448 512" width="14"
102
- xmlns="http://www.w3.org/2000/svg">
103
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
104
- <path
105
- d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/>
106
- </svg>
107
- </button>
108
- <button type="button" @click="parent.splice(parent.indexOf(item), 1)">
109
- <svg class="fill-text-300 hover:fill-red-600" height="14" viewBox="0 0 320 512" width="14"
110
- xmlns="http://www.w3.org/2000/svg">
111
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
112
- <path
113
- d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/>
114
- </svg>
115
- </button>
38
+ <TreeView :items="layout.headers"
39
+ :config="componentsConfig"
40
+ v-model="config.selectedUid"
41
+ class="mt-2">
42
+ <template #item="{ item, parent }">
43
+ <div class="flex-1 p-1 px-3 mb-1 overflow-hidden text-ellipsis cursor-pointer flex flex-row gap-2">
44
+ <div class="flex-1">
45
+ <strong>{{ item.name }}</strong>
116
46
  </div>
117
- </template>
118
- </TreeView>
119
- </div>
120
-
121
- <div class="p-5">
122
- <div class="flex flex-row items-center gap-2">
123
- <div class="flex-1">
124
- <label>Style</label>
47
+ <button type="button"
48
+ v-if="item.isContainer"
49
+ @click="$refs.componentSelector.open(c => item.items.push(c))">
50
+ <svg width="14" height="14" class="fill-text-300 hover:fill-primary-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/></svg>
51
+ </button>
52
+ <button type="button" @click="parent.splice(parent.indexOf(item), 1)">
53
+ <svg width="14" height="14" class="fill-text-300 hover:fill-red-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg>
54
+ </button>
125
55
  </div>
126
- <button class="text-primary" type="button"
127
- @click="config.selectedUid = 'style'">
128
- Edit Style
129
- </button>
56
+ </template>
57
+ </TreeView>
58
+ </div>
59
+
60
+ <div class="p-5">
61
+ <div class="flex flex-row items-center gap-2">
62
+ <div class="flex-1">
63
+ <label>Footers</label>
130
64
  </div>
65
+ <button type="button" class="text-primary"
66
+ @click="$refs.componentSelector.open((component) => layout.footers.push(component))">
67
+ Add Component
68
+ </button>
131
69
  </div>
70
+ <TreeView :items="layout.footers"
71
+ :config="componentsConfig"
72
+ v-model="config.selectedUid"
73
+ class="mt-2">
74
+ <template #item="{ item, parent }">
75
+ <div class="flex-1 p-1 px-3 mb-1 overflow-hidden text-ellipsis cursor-pointer flex flex-row gap-2">
76
+ <div class="flex-1">
77
+ <strong>{{ item.name }}</strong>
78
+ </div>
79
+ <button type="button"
80
+ v-if="item.isContainer"
81
+ @click="$refs.componentSelector.open(c => item.items.push(c))">
82
+ <svg width="14" height="14" class="fill-text-300 hover:fill-primary-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/></svg>
83
+ </button>
84
+ <button type="button" @click="parent.splice(parent.indexOf(item), 1)">
85
+ <svg width="14" height="14" class="fill-text-300 hover:fill-red-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg>
86
+ </button>
87
+ </div>
88
+ </template>
89
+ </TreeView>
132
90
  </div>
91
+
133
92
  </div>
134
93
 
135
- <div v-else class="flex-1 flex flex-col">
136
- <div class="border-b-[1px] border-text-50">
137
- <div class="p-3 flex flex-row items-start gap-3">
138
- <button type="button" @click="$emit('close')">
139
- <svg class="fill-text hover:fill-red-600" height="16" viewBox="0 0 320 512" width="16"
140
- xmlns="http://www.w3.org/2000/svg">
141
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
142
- <path
143
- d="M312.1 375c9.369 9.369 9.369 24.57 0 33.94s-24.57 9.369-33.94 0L160 289.9l-119 119c-9.369 9.369-24.57 9.369-33.94 0s-9.369-24.57 0-33.94L126.1 256L7.027 136.1c-9.369-9.369-9.369-24.57 0-33.94s24.57-9.369 33.94 0L160 222.1l119-119c9.369-9.369 24.57-9.369 33.94 0s9.369 24.57 0 33.94L193.9 256L312.1 375z"/>
144
- </svg>
145
- </button>
146
- <div v-if="page" class="flex-1 flex flex-col leading-3">
94
+ <div v-else>
95
+ <div class="border-b-[1px] border-border-50">
96
+ <div class="p-3 flex flex-row items-center gap-3">
97
+ <div class="flex-1 flex flex-col leading-3">
147
98
  <small>Page</small>
148
- <Textbox v-model="page.name" class="flex-1 border-transparent bg-transparent text-lg bg-red-100"
149
- item-class="p-0"/>
99
+ <Textbox v-model="page.name" class="flex-1 border-transparent bg-transparent text-lg bg-red-100" item-class="p-0" />
150
100
  </div>
151
101
  <div>
152
102
  <Button ref="saveBtn"
153
- :state="canSave ? 1 : -1"
154
103
  class="w-[56px]"
104
+ :state="canSave ? 1 : -1"
155
105
  @click="save()">
156
106
  Save
157
107
  </Button>
@@ -159,166 +109,77 @@
159
109
  </div>
160
110
  </div>
161
111
 
162
- <div class="flex-1 overflow-y-auto">
112
+ <div class="p-5">
113
+ <div class="flex flex-row items-center gap-2">
114
+ <div class="flex-1">
115
+ <label>Layout</label>
116
+ </div>
117
+ <button type="button" class="text-primary" @click="config.mode = 'layout'">Edit Layout</button>
118
+ </div>
119
+ <Dropdown class="mt-1" v-model="page.layoutId">
120
+ <option v-for="layout in layouts"
121
+ :value="layout.id">
122
+ {{ layout.name }}
123
+ </option>
124
+ </Dropdown>
125
+ </div>
163
126
 
164
- <div class="p-5">
165
- <div class="flex flex-row items-center gap-2">
166
- <div class="flex-1">
167
- <label>Layout</label>
168
- </div>
169
- <button v-if="page.layoutId > 0"
170
- class="text-primary"
171
- type="button"
172
- @click="config.mode = 'layout'">
173
- Edit Layout
174
- </button>
127
+ <div class="p-5">
128
+ <div class="flex flex-row items-center gap-2">
129
+ <div class="flex-1">
130
+ <label>Components</label>
175
131
  </div>
176
- <button ref="layoutBtn"
177
- type="button"
178
- class="mt-1 flex flex-row w-full p-2 bg-text-50 border-[1px] border-text-200 rounded-lg"
179
- @click="$refs.layoutList.open($refs.layoutBtn)">
180
- <label>{{ layout ? layout.name : 'None' }}</label>
132
+ <button type="button" class="text-primary"
133
+ @click="$refs.componentSelector.open((component) => page.components.push(component))">
134
+ Add Component
181
135
  </button>
182
-
183
- <ContextMenu ref="layoutList" position="bottom-left" width="parent">
184
- <div class="flex flex-col min-w-[200px] divide-y divide-text-100 border-[1px] border-text-200 rounded-lg">
185
- <button type="button" class="p-2 text-left"
186
- @click="page.layoutId = null">
187
- None
188
- </button>
189
- <div v-for="layout in layouts"
190
- class="flex flex-row gap-2">
191
- <button type="button"
192
- class="flex-1 p-2 text-left"
193
- @click="page.layoutId = layout.id">
194
- {{ layout.name }}
195
- </button>
196
- <div v-if="layout.id !== page.layoutId" class="flex flex-row">
197
- <button type="button" class="p-2 text-primary"
198
- @click="duplicateLayout(layout)">
199
- <svg width="14" height="14" class="fill-primary" 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="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z"/></svg>
200
- </button>
201
- <button type="button" class="p-2 text-primary"
202
- @click.stop="confirm($t('Remove this layout?'), () => {})">
203
- <svg width="14" height="14" class="fill-text-300 hover:fill-red-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M312.1 375c9.369 9.369 9.369 24.57 0 33.94s-24.57 9.369-33.94 0L160 289.9l-119 119c-9.369 9.369-24.57 9.369-33.94 0s-9.369-24.57 0-33.94L126.1 256L7.027 136.1c-9.369-9.369-9.369-24.57 0-33.94s24.57-9.369 33.94 0L160 222.1l119-119c9.369-9.369 24.57-9.369 33.94 0s9.369 24.57 0 33.94L193.9 256L312.1 375z"/></svg>
204
- </button>
205
- </div>
136
+ </div>
137
+ <TreeView :items="page.components"
138
+ :config="componentsConfig"
139
+ v-model="config.selectedUid"
140
+ class="mt-2">
141
+ <template #item="{ item, parent }">
142
+ <div class="flex-1 p-1 px-3 mb-1 overflow-hidden text-ellipsis cursor-pointer flex flex-row gap-2">
143
+ <div class="flex-1">
144
+ <strong>{{ item.name }}</strong>
206
145
  </div>
207
146
  <button type="button"
208
- class="p-2 text-left text-primary"
209
- @click="">
210
- New Layout...
147
+ v-if="item.isContainer"
148
+ @click="$refs.componentSelector.open(c => item.items.push(c))">
149
+ <svg width="14" height="14" class="fill-text-300 hover:fill-primary-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/></svg>
150
+ </button>
151
+ <button type="button" @click="parent.splice(parent.indexOf(item), 1)">
152
+ <svg width="14" height="14" class="fill-text-300 hover:fill-red-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg>
211
153
  </button>
212
154
  </div>
213
- </ContextMenu>
214
- </div>
215
-
216
- <div class="p-5">
217
- <div class="flex flex-row items-center gap-2">
218
- <div class="flex-1">
219
- <label>Components</label>
220
- </div>
221
- <button class="text-primary" type="button"
222
- @click="$refs.componentSelector.open((component) => page.components.push(component))">
223
- Add Component
224
- </button>
225
- </div>
226
- <TreeView v-model="config.selectedUid"
227
- :config="componentsConfig"
228
- :items="page.components"
229
- class="mt-2">
230
- <template #item="{ item, parent }">
231
- <div class="flex-1 p-1 px-3 mb-1 overflow-hidden text-ellipsis cursor-pointer flex flex-row gap-2"
232
- @click="addToCopy(item, parent)">
233
- <div class="flex-1">
234
- <strong>{{ item.name }}</strong>
235
- </div>
236
- <button v-if="item.isContainer"
237
- type="button"
238
- @click="$refs.componentSelector.open(c => item.items.push(c))">
239
- <svg class="fill-text-300 hover:fill-primary-600" height="14" viewBox="0 0 448 512" width="14"
240
- xmlns="http://www.w3.org/2000/svg">
241
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
242
- <path
243
- d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/>
244
- </svg>
245
- </button>
246
- <button type="button" @click="parent.splice(parent.indexOf(item), 1)">
247
- <svg class="fill-text-300 hover:fill-red-600" height="14" viewBox="0 0 320 512" width="14"
248
- xmlns="http://www.w3.org/2000/svg">
249
- <!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) -->
250
- <path
251
- d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/>
252
- </svg>
253
- </button>
254
- </div>
255
- </template>
256
- </TreeView>
257
- </div>
258
-
259
- <div class="p-5">
260
- <div class="flex flex-row items-center gap-2">
261
- <div class="flex-1">
262
- <label>Data</label>
263
- </div>
264
- <button class="text-primary" type="button"
265
- @click="$refs.webPageDataEdit.create()">
266
- Add Data
267
- </button>
268
- </div>
269
- <TreeView v-model="config.selectedUid"
270
- :config="componentsConfig"
271
- :items="page.data"
272
- class="mt-2">
273
- <template #item="{ item, parent }">
274
- <div class="flex-1 flex flex-row items-center gap-3 px-2">
275
- <div class="flex-1 p-2">
276
- {{ item.key }}
277
- </div>
278
- <button type="button" @click="page.data.splice(index, 1)">
279
- <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>
280
- </button>
281
- </div>
282
- </template>
283
- </TreeView>
284
- </div>
285
-
155
+ </template>
156
+ </TreeView>
286
157
  </div>
287
158
  </div>
288
159
 
289
160
  <WebPageComponentSelector ref="componentSelector"
290
- @select="(item) => config.selectedUid = item.uid"/>
291
-
292
- <WebPageDataEdit ref="webPageDataEdit" @apply="applyData" />
293
-
161
+ @select="(item) => config.selectedUid = item.uid" />
294
162
  </div>
295
163
 
296
164
  <div :class="$style.centerPane">
297
165
 
298
- <div class="flex flex-row gap-2 items-start p-3">
299
- <div class="flex flex-col gap-2">
300
- <div class="flex flex-row gap-2">
301
- <select v-model="config.zoomLevel" :class="$style.zoomLevel" @change="resize()">
302
- <optgroup label="Zoom Level">
303
- <option value="fit">Fit</option>
304
- <option value="125%">125%</option>
305
- <option value="100%">100%</option>
306
- <option value="75%">75%</option>
307
- <option value="50%">50%</option>
308
- </optgroup>
309
- </select>
310
- <select v-model="config.previewMode" :class="$style.zoomLevel" class="w-[70px]" @change="resize()">
311
- <option value="design">Design</option>
312
- <option value="preview">Preview</option>
313
- </select>
314
- </div>
315
- <Checkbox v-model="config.autoSelect" item-class="items-center">
316
- <small>Auto Select</small>
317
- </Checkbox>
318
- </div>
166
+ <div class="flex flex-row gap-2 items-center p-3">
167
+ <select v-model="config.zoomLevel" :class="$style.zoomLevel" @change="resize()">
168
+ <optgroup label="Zoom Level">
169
+ <option value="fit">Fit</option>
170
+ <option value="125%">125%</option>
171
+ <option value="100%">100%</option>
172
+ <option value="75%">75%</option>
173
+ <option value="50%">50%</option>
174
+ </optgroup>
175
+ </select>
176
+ <select v-model="config.previewMode" class="w-[70px]" :class="$style.zoomLevel" @change="resize()">
177
+ <option value="design">Design</option>
178
+ <option value="preview">Preview</option>
179
+ </select>
319
180
  <div class="flex-1"></div>
320
- <select v-model="config.viewType"
321
- :class="$style.zoomLevel"
181
+ <select class="p-1 text-sm cursor-pointer bg-text-50 outline-none"
182
+ v-model="config.viewType"
322
183
  @change="resize">
323
184
  <option v-for="_type in viewTypes" :value="_type.value">{{ _type.text }}</option>
324
185
  </select>
@@ -326,13 +187,13 @@
326
187
 
327
188
  <div ref="preview" :class="`${$style.preview}${config.zoomLevel !== 'fit' ? '' : ' ' + $style.fit}`">
328
189
 
329
- <iframe ref="iframe"
330
- :height="iframeSize.height"
331
- :src="iframeSrc"
332
- :style="iframeStyle"
190
+ <iframe :src="iframeSrc"
333
191
  :width="iframeSize.width"
192
+ :height="iframeSize.height"
334
193
  class="mx-auto border-[2px] border-text-300"
335
- @load="updateIframe"></iframe>
194
+ :style="iframeStyle"
195
+ @load="updateIframe"
196
+ ref="iframe"></iframe>
336
197
 
337
198
  </div>
338
199
 
@@ -341,21 +202,16 @@
341
202
  <div :class="$style.rightPane" :style="rightStyle">
342
203
  <div :class="$style.rightBoundary" @mousedown="(e) => $util.dragResize(e, resize2)"></div>
343
204
 
344
- <div class="p-5" @click="log(selectedComponent)">
345
-
346
- <StyleSetting v-if="config.selectedUid === 'style'"
347
- :config="config"
348
- :index="viewTypeIndex"
349
- :value="layout"
350
- :view-type="config.viewType"/>
351
-
205
+ <div class="p-5">
352
206
  <component :is="`${selectedComponent?.type}Setting`"
353
- v-else
354
207
  :config="config"
355
- :index="viewTypeIndex"
356
208
  :value="selectedComponent"
357
- :view-type="config.viewType"/>
209
+ :index="viewTypeIndex"
210
+ :view-type="config.viewType" />
358
211
 
212
+ <pre class="text-xs whitespace-pre">
213
+ {{ selectedComponent }}
214
+ </pre>
359
215
  </div>
360
216
  </div>
361
217
 
@@ -367,47 +223,56 @@
367
223
  import {defineAsyncComponent} from "vue";
368
224
  import TreeView from "./WebPageBuilder4/TreeView.vue";
369
225
  import throttle from "lodash/throttle";
370
- import md5 from "md5";
226
+ /*import ButtonSetting from "./WebPageBuilder4/ButtonSetting.vue";
227
+ import FlexSetting from "./WebPageBuilder4/FlexSetting.vue";
228
+ import ImageSetting from "./WebPageBuilder4/ImageSetting.vue";
229
+ import PaddingSetting from "./WebPageBuilder4/PaddingSetting.vue";
230
+ import WebPageComponentSelector from "./WebPageBuilder4/WebPageComponentSelector.vue";*/
371
231
 
372
- export default {
232
+ export default{
373
233
 
374
234
  components: {
375
235
  ButtonSetting: defineAsyncComponent(() => import('./WebPageBuilder4/ButtonSetting.vue')),
376
236
  CarouselSetting: defineAsyncComponent(() => import('./WebPageBuilder4/CarouselSetting.vue')),
377
- DataSetting: defineAsyncComponent(() => import('./WebPageBuilder4/DataSetting.vue')),
378
237
  FlexSetting: defineAsyncComponent(() => import('./WebPageBuilder4/FlexSetting.vue')),
379
238
  GridSetting: defineAsyncComponent(() => import('./WebPageBuilder4/GridSetting.vue')),
380
239
  ImageSetting: defineAsyncComponent(() => import('./WebPageBuilder4/ImageSetting.vue')),
381
- LinkSetting: defineAsyncComponent(() => import('./WebPageBuilder4/LinkSetting.vue')),
382
240
  MarginSetting: defineAsyncComponent(() => import('./WebPageBuilder4/MarginSetting.vue')),
383
- MobileMenuSetting: defineAsyncComponent(() => import('./WebPageBuilder4/MobileMenuSetting.vue')),
384
241
  PaddingSetting: defineAsyncComponent(() => import('./WebPageBuilder4/PaddingSetting.vue')),
385
242
  TextSetting: defineAsyncComponent(() => import('./WebPageBuilder4/TextSetting.vue')),
386
- StyleSetting: defineAsyncComponent(() => import('./WebPageBuilder4/StyleSetting.vue')),
387
- SvgSetting: defineAsyncComponent(() => import('./WebPageBuilder4/SvgSetting.vue')),
388
243
  TreeView,
389
- WebPageDataEdit: defineAsyncComponent(() => import('./WebPageBuilder4/WebPageDataEdit.vue')),
390
244
  WebPageComponentSelector: defineAsyncComponent(() => import('./WebPageBuilder4/WebPageComponentSelector.vue')),
391
245
  },
392
246
 
247
+ emits: [ 'save' ],
248
+
249
+ props:{
250
+ page: {
251
+ type: Object,
252
+ default: {}
253
+ },
254
+ config: Object,
255
+ layouts: Array,
256
+ },
257
+
393
258
  computed: {
394
259
 
395
- canSave() {
396
- if (this.config.mode === 'layout')
260
+ canSave(){
261
+ if(this.config.mode === 'layout')
397
262
  return JSON.stringify(this.layout) !== this.initialLayout
398
263
  return JSON.stringify(this.page) !== this.initialPage
399
264
  },
400
265
 
401
- componentsConfig() {
402
- if (!this.config.components)
266
+ componentsConfig(){
267
+ if(!this.config.components)
403
268
  this.config.components = {}
404
269
  return this.config.components
405
270
  },
406
271
 
407
- iframeSize() {
272
+ iframeSize(){
408
273
 
409
274
  let width, height
410
- switch (this.config.viewType) {
275
+ switch(this.config.viewType){
411
276
  case '':
412
277
  width = 390
413
278
  height = 844
@@ -418,7 +283,7 @@ export default {
418
283
  height = 768
419
284
  break
420
285
 
421
- case 'lg:':
286
+ case 'xl:':
422
287
  width = 1365
423
288
  height = 768
424
289
  break
@@ -435,16 +300,12 @@ export default {
435
300
  }
436
301
  },
437
302
 
438
- iframeSrc() {
439
- return `/?edit-mode=${this.config.previewMode}`
303
+ layout(){
304
+ return (this.layouts ?? []).find(_ => _.id === this.page?.layoutId)
440
305
  },
441
306
 
442
- layout() {
443
- return (this.layouts ?? []).find(_ => _.id === parseInt(this.page?.layoutId))
444
- },
445
-
446
- leftBar() {
447
- if (!this.config.leftBar) {
307
+ leftBar(){
308
+ if(!this.config.leftBar){
448
309
  this.config.leftBar = {
449
310
  width: 360
450
311
  }
@@ -453,27 +314,27 @@ export default {
453
314
  return this.config.leftBar
454
315
  },
455
316
 
456
- leftStyle() {
317
+ leftStyle(){
457
318
  return {
458
319
  width: this.leftBar.width + 'px'
459
320
  }
460
321
  },
461
322
 
462
- previewStyle() {
323
+ previewStyle(){
463
324
  return {
464
325
  'overflow-auto !important': this.config.zoomLevel !== 'fit',
465
326
  'overflow-hidden !important': this.config.zoomLevel === 'fit',
466
327
  }
467
328
  },
468
329
 
469
- rightStyle() {
330
+ rightStyle(){
470
331
  return {
471
332
  width: this.rightBar.width + 'px'
472
333
  }
473
334
  },
474
335
 
475
- rightBar() {
476
- if (!this.config.rightBar) {
336
+ rightBar(){
337
+ if(!this.config.rightBar){
477
338
  this.config.rightBar = {
478
339
  width: 360
479
340
  }
@@ -482,40 +343,39 @@ export default {
482
343
  return this.config.rightBar
483
344
  },
484
345
 
485
- selectedComponent() {
486
- if (!this.config.selectedUid) return
487
- if (!this.page) return
346
+ selectedComponent(){
347
+ if(!this.config.selectedUid) return
348
+ if(!this.page) return
488
349
 
489
350
  const findComponents = (items, uid) => {
490
- for (let item of items) {
491
- if (item.uid === uid)
351
+ for(let item of items){
352
+ if(item.uid === uid)
492
353
  return item
493
354
 
494
- if (item.items) {
355
+ if(item.items){
495
356
  const component = findComponents(item.items, uid)
496
- if (component)
357
+ if(component)
497
358
  return component
498
359
  }
499
360
  }
500
361
  }
501
362
 
502
- if (this.config.mode === 'layout') {
363
+ if(this.config.mode === 'layout'){
503
364
  return findComponents(this.layout.headers ?? [], this.config.selectedUid) ??
504
365
  findComponents(this.layout.footers ?? [], this.config.selectedUid)
505
366
  }
506
- else {
507
- return findComponents(this.page.components, this.config.selectedUid) ??
508
- findComponents(this.page.data ?? [], this.config.selectedUid)
367
+ else{
368
+ return findComponents(this.page.components, this.config.selectedUid)
509
369
  }
510
370
  },
511
371
 
512
- viewTypeIndex() {
372
+ viewTypeIndex(){
513
373
  return this.viewTypes.findIndex(v => v.value === this.config.viewType)
514
374
  }
515
375
 
516
376
  },
517
377
 
518
- data() {
378
+ data(){
519
379
  return {
520
380
  compClasses: [
521
381
  'aspectRatio', 'position', 'left', 'top', 'right', 'bottom',
@@ -553,91 +413,34 @@ export default {
553
413
  ],
554
414
  initialPage: null,
555
415
  initialLayout: null,
556
- iframeStyle: {},
557
416
  viewTypes: [
558
- {text: 'Mobile', value: ''},
559
- {text: 'Tablet', value: 'md:'},
560
- {text: 'Desktop', value: 'lg:'},
561
- {text: 'TV', value: '2xl:'},
417
+ { text:'Mobile', value:'' },
418
+ { text:'Tablet', value:'md:' },
419
+ { text:'Desktop', value:'xl:' },
420
+ { text:'TV', value:'2xl:' },
562
421
  ],
563
- copyItem: {}
422
+ iframeSrc: '/?edit-mode=1',
423
+ iframeStyle: {}
564
424
  }
565
425
  },
566
426
 
567
- emits: ['close', 'save'],
568
-
569
- inject: [ 'confirm', 'toast' ],
570
-
571
427
  methods: {
572
428
 
573
- applyData(obj, idx){
574
- if(!Array.isArray(this.page.data))
575
- this.page.data = []
576
-
577
- idx >= 0 ?
578
- Object.assign(this.page.data[idx], obj) :
579
- this.page.data.push(obj)
580
-
581
- this.config.selectedUid = obj.uid
582
- },
583
-
584
- applyPage(obj) {
585
- const {page, layout} = obj
586
-
587
- Object.assign(this.page, page)
588
- this.initialPage = JSON.stringify(this.page)
589
-
590
- if(layout){
591
- Object.assign(this.layout, layout)
429
+ applyPage(page){
430
+ if(page.type === 1){
431
+ Object.assign(this.layout, page)
592
432
  this.initialLayout = JSON.stringify(this.layout)
593
433
  }
434
+ else{
435
+ Object.assign(this.page, page)
436
+ this.initialPage = JSON.stringify(this.page)
437
+ }
594
438
  },
595
439
 
596
- addToCopy(item, parent) {
597
- Object.assign(this.copyItem, {
598
- item,
599
- parent
600
- })
601
- },
602
-
603
- copy() {
604
- if (!this.copyItem) return
605
- this.copyItem.copied = JSON.stringify(this.copyItem.item)
606
- this.toast('Component copied')
607
- },
608
-
609
- duplicateLayout(layout){
610
- const newLayout = JSON.parse(JSON.stringify(layout))
611
- newLayout.id = -1
612
- newLayout.name += ' copy'
613
- delete newLayout.uid
614
- this.layouts.push(newLayout)
615
- this.page.layoutId = newLayout.id
616
-
617
- this.config.mode = 'layout'
618
- },
619
-
620
- getPage(){
621
- return this.page
622
- },
623
-
624
- paste() {
625
- if (!this.copyItem || !this.copyItem.copied) return
626
-
627
- const newItem = JSON.parse(this.copyItem.copied)
628
- this.setUid(newItem)
629
- newItem.name += ' copy'
630
-
631
- this.config.components[newItem.uid] = { childCollapsed:true }
632
-
633
- const itemIndex = this.copyItem.parent.indexOf(this.copyItem.item)
634
- this.copyItem.parent.splice(itemIndex + 1, 0, newItem)
635
- },
636
-
637
- createComponentInstance(component) {
440
+ createComponentInstance(component){
638
441
 
639
- if (!component.uid) return
640
- if (!component.props.enabled) return
442
+ if(!component.uid) return
443
+ if(!component.props.enabled) return
641
444
 
642
445
  const compUid = '_' + component.uid.substring(0, 4) + ' '
643
446
 
@@ -664,153 +467,99 @@ export default {
664
467
  .join(' ')
665
468
  }
666
469
 
667
- for (let key in component.props) {
668
- if (!this.compClasses.includes(key) &&
470
+ for(let key in component.props){
471
+ if(!this.compClasses.includes(key) &&
669
472
  !this.containerClasses.includes(key) &&
670
473
  !this.itemClasses.includes(key) &&
671
- !['enabled'].includes(key)) {
474
+ ![ 'enabled' ].includes(key)){
672
475
  instance[key] = component.props[key]
673
476
  }
674
477
  }
675
478
 
676
- const whitelistProps = ['containerVariant']
479
+ const whitelistProps = [ 'containerVariant' ]
677
480
  whitelistProps.forEach((key) => {
678
- if (component.props[key]) {
481
+ if(component.props[key]){
679
482
  instance[key] = component.props[key]
680
483
  }
681
484
  })
682
485
 
683
- if (Array.isArray(component.items)) {
684
- instance.items = component.items.map((_) => this.createComponentInstance(_)).filter(_ => _)
486
+ if(Array.isArray(component.items)){
487
+ instance.items = component.items.map((_) => this.createComponentInstance(_)).filter(_=>_)
685
488
  }
686
489
 
687
- if (component.props && Array.isArray(component.props.items)) {
490
+ if(component.props && Array.isArray(component.props.items)){
688
491
  instance.items = component.props.items
689
492
  }
690
493
 
691
494
  return instance
692
495
  },
693
496
 
694
- createInstance() {
695
-
696
- const headers = (this.layout?.headers ?? []).map((_) => this.createComponentInstance(_)).filter(_ => _)
697
- const footers = (this.layout?.footers ?? []).map((_) => this.createComponentInstance(_)).filter(_ => _)
698
- const components = (this.page.components ?? []).map((_) => this.createComponentInstance(_)).filter(_ => _)
699
-
700
- return {
701
- headers,
702
- footers,
703
- components,
704
- style: this.layout?.style,
705
- data: this.page.data
706
- //stylesheet,
707
- //data: this.page.data,
708
- //editMode: this.store.previewMode
709
- }
710
- },
711
-
712
- findComponentByUid(uid, items) {
497
+ findComponentByUid(uid, items){
713
498
  let component
714
499
 
715
- for (let item of items) {
716
- if (item.uid === uid) {
500
+ for(let item of items){
501
+ if(item.uid === uid){
717
502
  component = item
718
503
  break
719
- } else if (Array.isArray(item.items)) {
504
+ }
505
+ else if(Array.isArray(item.items)){
720
506
  component = this.findComponentByUid(uid, item.items)
721
- if (component) break
507
+ if(component) break
722
508
  }
723
509
  }
724
510
 
725
511
  return component
726
512
  },
727
513
 
728
- getComponentIdWithType() {
729
-
730
- const getComponentsWithMethods = (items, methods) => {
731
-
732
- if (Array.isArray(items)) {
733
- for (let item of items) {
734
-
735
- if (Array.isArray(item.methods)) {
736
- for (let method of item.methods) {
737
- if (!methods[method]) methods[method] = []
738
- methods[method].push(item)
739
- }
740
- } else if (item.isContainer) {
741
- const childMethods = getComponentsWithMethods(item.items, methods)
742
- for (let method in childMethods) {
743
- if (!methods[method]) methods[method] = []
744
- methods[method].push(...childMethods[method])
745
- }
746
- }
747
-
748
- }
749
- }
750
- }
751
-
752
- const methods = {}
753
- getComponentsWithMethods(this.page.components, methods)
754
- getComponentsWithMethods(this.layout?.headers, methods)
755
- getComponentsWithMethods(this.layout?.footers, methods)
756
- return methods
757
- },
758
-
759
- onKeyDown(e) {
514
+ onKeyDown(e){
760
515
 
761
- if (e.altKey) {
762
- if ([49, 50, 51, 52].includes(e.keyCode)) {
763
- if (e.keyCode === 49) {
516
+ if(e.altKey){
517
+ if([ 49, 50, 51, 52 ].includes(e.keyCode)){
518
+ if(e.keyCode === 49){
764
519
  this.config.viewType = ''
765
- } else if (e.keyCode === 50) {
520
+ }
521
+ else if(e.keyCode === 50){
766
522
  this.config.viewType = 'md:'
767
- } else if (e.keyCode === 51) {
768
- this.config.viewType = 'lg:'
769
- } else if (e.keyCode === 52) {
523
+ }
524
+ else if(e.keyCode === 51){
525
+ this.config.viewType = 'xl:'
526
+ }
527
+ else if(e.keyCode === 52){
770
528
  this.config.viewType = '2xl:'
771
529
  }
772
530
  this.resize()
773
- } else if (e.keyCode === 65) {
774
- this.config.autoSelect = !this.config.autoSelect
775
531
  }
776
- } else if ((e.ctrlKey || e.metaKey) && e.keyCode === 83) {
532
+ }
533
+ else if((e.ctrlKey || e.metaKey) && e.keyCode === 83){
777
534
  e.preventDefault()
778
535
  this.save()
779
- } else if ((e.ctrlKey || e.metaKey)) {
780
- if (e.keyCode === 67) {
781
- this.copy()
782
- } else if (e.keyCode === 86) {
783
- this.paste()
784
- }
785
536
  }
786
537
 
787
538
  },
788
539
 
789
- onIframeMessage(event) {
790
- const {uid, type, value} = event.data ?? {}
540
+ onIframeMessage(event){
541
+ const { uid, type, value } = event.data ?? {}
791
542
 
792
- switch (type) {
543
+ switch(type) {
793
544
 
794
545
  case 'mounted':
795
546
  this.updateIframe()
796
547
  break
797
548
 
798
549
  case 'component-click':
799
- if (!this.config.autoSelect) {
800
- return
801
- }
802
550
 
803
551
  let component
804
- if (this.config.mode === 'layout') {
552
+ if(this.config.mode === 'layout'){
805
553
  component = this.findComponentByUid(uid, this.layout.headers)
806
- if (!component)
554
+ if(!component)
807
555
  component = this.findComponentByUid(uid, this.layout.footers)
808
- } else {
556
+ }
557
+ else{
809
558
  component = this.findComponentByUid(uid, this.page.components)
810
559
  }
811
560
 
812
- if (!component) {
813
- if (this.config.mode === 'layout')
561
+ if(!component){
562
+ if(this.config.mode === 'layout')
814
563
  delete this.config.mode
815
564
  else
816
565
  this.config.mode = 'layout'
@@ -823,17 +572,17 @@ export default {
823
572
  }
824
573
  },
825
574
 
826
- printConfig(e) {
827
- if (e.altKey) {
575
+ printConfig(e){
576
+ if(e.altKey){
828
577
  console.log(this.config)
829
578
  }
830
579
  },
831
580
 
832
- resize() {
581
+ resize(){
833
582
 
834
583
  const transformOrigin = this.config.viewType === '' ? 'center top' : '0 0'
835
584
 
836
- switch (this.config.zoomLevel) {
585
+ switch(this.config.zoomLevel){
837
586
 
838
587
  case '125%':
839
588
  this.iframeStyle = {
@@ -880,18 +629,18 @@ export default {
880
629
  break
881
630
 
882
631
  default:
883
- if (this.$refs.preview) {
632
+ if(this.$refs.preview){
884
633
  const previewWidth = this.$refs.preview.clientWidth - 50
885
634
  const previewHeight = this.$refs.preview.clientHeight - 70
886
635
 
887
636
  let scale = 1
888
- switch (this.config.viewType) {
637
+ switch(this.config.viewType){
889
638
 
890
639
  case 'md:':
891
640
  scale = (previewWidth / 1024).toFixed(2)
892
641
  break
893
642
 
894
- case 'lg:':
643
+ case 'xl:':
895
644
  scale = (previewWidth / 1365).toFixed(2)
896
645
  break
897
646
 
@@ -917,65 +666,53 @@ export default {
917
666
  }
918
667
  },
919
668
 
920
- resize1(w) {
669
+ resize1(w){
921
670
  const nextWidth = this.leftBar.width + w
922
- if (nextWidth >= 240 && nextWidth <= 480) {
671
+ if(nextWidth >= 240 && nextWidth <= 480){
923
672
  this.leftBar.width += w
924
673
  }
925
674
  },
926
675
 
927
- resize2(w) {
676
+ resize2(w){
928
677
  const nextWidth = this.rightBar.width - w
929
- if (nextWidth >= 240 && nextWidth <= 480) {
678
+ if(nextWidth >= 240 && nextWidth <= 480){
930
679
  this.rightBar.width -= w
931
680
  }
932
681
  },
933
682
 
934
- resetState() {
683
+ resetState(){
935
684
  this.$refs.saveBtn.resetState()
936
685
  },
937
686
 
938
- save() {
939
- if (!this.canSave) return
940
-
941
- this.$emit('save', {
942
-
943
- layout: this.layout ? {
944
- ...this.layout,
945
- id: this.layout.id === -1 ? null : this.layout.id
946
- } : undefined,
947
-
948
- page: {
949
- ...this.page,
950
- layoutId: this.page.layoutId ? parseInt(this.page.layoutId) : null,
951
- instance: this.createInstance()
952
- }
687
+ save(){
688
+ if(!this.canSave) return
953
689
 
954
- })
690
+ this.$emit('save',
691
+ this.config.mode === 'layout' ? this.layout : this.page
692
+ )
955
693
  },
956
694
 
957
- setState(state) {
695
+ setState(state){
958
696
  this.$refs.saveBtn.setState(state)
959
697
  },
960
698
 
961
- setUid(item){
962
- item.uid = md5(JSON.stringify(item) + new Date().getTime())
963
- if (Array.isArray(item.methods))
964
- item.props.id = item.uid
965
-
966
- if(Array.isArray(item.items)){
967
- for(let subItem of item.items){
968
- this.setUid(subItem)
969
- }
970
- }
971
- },
699
+ updateIframe: throttle(function(){
700
+ if(!this.$refs.iframe) return
972
701
 
973
- updateIframe: throttle(function () {
974
- if (!this.$refs.iframe) return
702
+ const headers = (this.layout?.headers ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
703
+ const footers = (this.layout?.footers ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
704
+ const components = (this.page.components ?? []).map((_) => this.createComponentInstance(_)).filter(_=>_)
975
705
 
976
706
  this.$refs.iframe.contentWindow.postMessage({
977
- action: 'update',
978
- page: JSON.stringify(this.createInstance())
707
+ action:'update',
708
+ page: JSON.stringify({
709
+ headers,
710
+ footers,
711
+ components,
712
+ //stylesheet,
713
+ //data: this.page.data,
714
+ //editMode: this.store.previewMode
715
+ })
979
716
  }, '*')
980
717
  }, 300, {
981
718
  leading: false,
@@ -984,14 +721,13 @@ export default {
984
721
 
985
722
  },
986
723
 
987
- mounted() {
988
- Object.assign(this.config, {
989
- autoSelect: this.config?.autoSelect ?? true,
990
- previewMode: this.config?.previewMode ?? 'design',
991
- viewType: this.config?.viewType ?? this.viewTypes[0].value,
992
- zoomLevel: this.config?.zoomLevel ?? 'fit',
993
- })
724
+ provide(){
725
+ return {
726
+ viewTypes: this.viewTypes
727
+ }
728
+ },
994
729
 
730
+ mounted() {
995
731
  window.addEventListener('message', this.onIframeMessage)
996
732
  window.addEventListener('keydown', this.onKeyDown)
997
733
 
@@ -1000,36 +736,18 @@ export default {
1000
736
  this.resize()
1001
737
  },
1002
738
 
1003
- props: {
1004
- config: Object,
1005
- layouts: Array,
1006
- page: {
1007
- type: Object,
1008
- default: {}
1009
- },
1010
- store: Object
1011
- },
1012
-
1013
- provide() {
1014
- return {
1015
- getComponentIdWithType: this.getComponentIdWithType,
1016
- getPage: this.getPage,
1017
- viewTypes: this.viewTypes
1018
- }
1019
- },
1020
-
1021
739
  watch: {
1022
740
 
1023
- layout: {
741
+ page: {
1024
742
  deep: true,
1025
- handler() {
743
+ handler(){
1026
744
  this.updateIframe()
1027
745
  }
1028
746
  },
1029
747
 
1030
- page: {
748
+ layout: {
1031
749
  deep: true,
1032
- handler() {
750
+ handler(){
1033
751
  this.updateIframe()
1034
752
  }
1035
753
  },
@@ -1042,43 +760,39 @@ export default {
1042
760
 
1043
761
  <style module>
1044
762
 
1045
- .comp {
763
+ .comp{
1046
764
  @apply flex-1 flex flex-row;
1047
765
  }
1048
766
 
1049
- .leftPane {
767
+ .leftPane{
1050
768
  @apply relative overflow-y-auto;
1051
- @apply flex flex-col;
1052
769
  }
1053
-
1054
- .leftBoundary {
1055
- @apply absolute top-0 right-0 bottom-0 w-[3px] border-r-[1px] border-text-50 cursor-e-resize;
770
+ .leftBoundary{
771
+ @apply absolute top-0 right-0 bottom-0 w-[3px] border-r-[1px] border-border-50 cursor-e-resize;
1056
772
  }
1057
773
 
1058
- .centerPane {
774
+ .centerPane{
1059
775
  @apply flex-1 flex flex-col;
1060
776
  }
1061
777
 
1062
- .preview {
778
+ .preview{
1063
779
  @apply flex-1 relative overflow-y-auto;
1064
780
  }
1065
-
1066
- .preview.fit {
781
+ .preview.fit{
1067
782
  @apply flex-1 relative overflow-hidden;
1068
783
  }
1069
784
 
1070
- .rightPane {
785
+ .rightPane{
1071
786
  @apply relative overflow-y-auto;
1072
787
 
1073
788
  }
1074
-
1075
- .rightBoundary {
1076
- @apply absolute top-0 left-0 bottom-0 w-[3px] border-l-[1px] border-text-50 cursor-w-resize;
789
+ .rightBoundary{
790
+ @apply absolute top-0 left-0 bottom-0 w-[3px] border-l-[1px] border-border-50 cursor-w-resize;
1077
791
  }
1078
792
 
1079
- .zoomLevel {
1080
- @apply appearance-none bg-base-400 text-center outline-none h-[24px] rounded-md px-2;
1081
- @apply border-[1px] border-text-100;
793
+ .zoomLevel{
794
+ @apply appearance-none bg-base-400 text-center outline-none h-[24px] rounded-md;
795
+ @apply border-[1px] border-border-100;
1082
796
  }
1083
797
 
1084
798
  </style>