@mixd-id/web-scaffold 0.2.240706 → 0.2.250801010
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/docs/components/Dashboard.md +56 -0
- package/log.txt +7 -0
- package/package.json +27 -19
- package/src/components/404.vue +61 -0
- package/src/components/AccountIcon.vue +19 -0
- package/src/components/Ahref.vue +1 -1
- package/src/components/Alert.vue +4 -13
- package/src/components/ArrayList.vue +49 -0
- package/src/components/Article.vue +24 -30
- package/src/components/Button.vue +83 -169
- package/src/components/Card.vue +257 -0
- package/src/components/Carousel.vue +61 -60
- package/src/components/Cart.vue +192 -0
- package/src/components/CartIcon.vue +89 -0
- package/src/components/ChartBar.vue +2 -3
- package/src/components/Checkbox.vue +20 -11
- package/src/components/Checkout.vue +373 -0
- package/src/components/CheckoutDelivery.vue +267 -0
- package/src/components/CodeEditor.vue +5 -16
- package/src/components/CollapsiblePanel.vue +70 -0
- package/src/components/ColorPicker.vue +12 -5
- package/src/components/ColorPicker2.vue +41 -19
- package/src/components/ColorPicker3.vue +100 -0
- package/src/components/Confirm.vue +9 -7
- package/src/components/ContextMenu.vue +122 -206
- package/src/components/ContextMenuItem.vue +53 -0
- package/src/components/Dashboard.vue +243 -0
- package/src/components/Dashboard2.vue +118 -0
- package/src/components/DashboardComponentSelector.vue +96 -0
- package/src/components/DashboardConfigs.vue +202 -0
- package/src/components/Datepicker.vue +102 -41
- package/src/components/DayTimeRange.vue +3 -2
- package/src/components/Dropdown.vue +7 -4
- package/src/components/Flex.vue +14 -40
- package/src/components/GHeatMaps.vue +2 -2
- package/src/components/Grid.vue +6 -6
- package/src/components/HTMLEditor.vue +27 -14
- package/src/components/Image.vue +62 -108
- package/src/components/ImagePreview.vue +14 -4
- package/src/components/ImageUploader.vue +114 -0
- package/src/components/ImportModal.vue +3 -3
- package/src/components/Link.vue +62 -6
- package/src/components/List.vue +528 -403
- package/src/components/ListContextMenu.vue +88 -0
- package/src/components/ListItem.vue +6 -4
- package/src/components/ListPage1.vue +14 -15
- package/src/components/ListView.vue +5 -6
- package/src/components/ListViewSettings.vue +2 -2
- package/src/components/LogViewerItem.vue +1 -1
- package/src/components/MarkdownEdit.vue +128 -0
- package/src/components/MarkdownPreview.vue +102 -0
- package/src/components/MenuItem1.vue +36 -0
- package/src/components/Modal.vue +95 -43
- package/src/components/MultiDropdown.vue +124 -0
- package/src/components/MultilineText.vue +1 -4
- package/src/components/OTPField.vue +40 -26
- package/src/components/ObjectTree.vue +1 -1
- package/src/components/PageBuilder.vue +3 -3
- package/src/components/Paragraph.vue +1 -2
- package/src/components/PresetSelectorFilterItem.vue +107 -95
- package/src/components/Radio.vue +1 -1
- package/src/components/SearchModal.vue +153 -0
- package/src/components/Slider.vue +1 -1
- package/src/components/Svg.vue +1 -1
- package/src/components/SvgEditor.vue +173 -0
- package/src/components/Switch.vue +4 -5
- package/src/components/Table.vue +2 -2
- package/src/components/TableView.vue +2 -3
- package/src/components/TableViewHead.vue +2 -2
- package/src/components/Tabs.vue +1 -1
- package/src/components/Testimonial.vue +2 -2
- package/src/components/Text.vue +7 -22
- package/src/components/TextEditor.vue +3 -3
- package/src/components/TextWithTag.vue +61 -30
- package/src/components/Textarea.vue +16 -22
- package/src/components/Textbox.vue +9 -19
- package/src/components/Timepicker.vue +25 -15
- package/src/components/Toast.vue +5 -3
- package/src/components/TreeMenu.vue +122 -0
- package/src/components/TreeView.vue +15 -10
- package/src/components/TreeView2.vue +38 -0
- package/src/components/TreeViewItem.vue +58 -29
- package/src/components/TreeViewItem2.vue +55 -0
- package/src/components/Uploader.vue +45 -0
- package/src/components/Video.vue +119 -0
- package/src/components/VirtualGrid.vue +24 -7
- package/src/components/VirtualTable.vue +363 -128
- package/src/configs/dashboard/data-table.js +9 -0
- package/src/configs/web-page-builder.js +118 -0
- package/src/directives/intersect.js +26 -0
- package/src/hooks/device.js +14 -0
- package/src/index.js +62 -107
- package/src/mixin/component.js +151 -67
- package/src/themes/default/index.js +118 -159
- package/src/utils/dashboard.js +22 -962
- package/src/utils/helpers.cjs +635 -0
- package/src/utils/helpers.js +91 -60
- package/src/utils/helpers.mjs +245 -12
- package/src/utils/importer.js +22 -3
- package/src/utils/list.mjs +1509 -0
- package/src/utils/preset-selector.cjs +1455 -0
- package/src/utils/preset-selector.js +489 -95
- package/src/utils/preset-selector.mjs +59 -20
- package/src/utils/queue.js +63 -0
- package/src/utils/web.mjs +120 -0
- package/src/utils/wss.js +38 -36
- package/src/utils/wss.mjs +24 -19
- package/src/widgets/AhrefSetting.vue +16 -13
- package/src/widgets/ArticleSetting.vue +15 -27
- package/src/widgets/BackgroundColorSetting.vue +153 -0
- package/src/widgets/BorderColorSetting.vue +57 -0
- package/src/widgets/BotEditor/BotEditorActions.vue +3 -2
- package/src/widgets/BotEditor/BotEditorSettings.vue +21 -0
- package/src/widgets/BotEditor.vue +35 -15
- package/src/widgets/ButtonSetting.vue +12 -13
- package/src/widgets/CarouselSetting.vue +33 -45
- package/src/widgets/CartSetting.vue +46 -0
- package/src/widgets/CheckoutSetting.vue +46 -0
- package/src/widgets/CollapsiblePanelSetting.vue +46 -0
- package/src/widgets/ColumnSelector.vue +29 -5
- package/src/widgets/ComponentSetting.vue +1 -1
- package/src/widgets/ComponentSetting2.vue +145 -236
- package/src/widgets/ComponentSetting3.vue +1 -1
- package/src/widgets/ContactForm.vue +3 -3
- package/src/widgets/ContactFormSetting.vue +41 -30
- package/src/widgets/Dashboard/BarChart.vue +47 -11
- package/src/widgets/Dashboard/BarChartSetting.vue +1 -1
- package/src/widgets/Dashboard/DataTable.vue +125 -0
- package/src/widgets/Dashboard/DataTableSetting.vue +243 -0
- package/src/widgets/Dashboard/DatasourceSelector.vue +1 -1
- package/src/widgets/Dashboard/Doughnut.vue +49 -7
- package/src/widgets/Dashboard/DoughnutSetting.vue +2 -2
- package/src/widgets/Dashboard/Metric.vue +78 -19
- package/src/widgets/Dashboard/MetricSetting.vue +81 -28
- package/src/widgets/Dashboard/Pie.vue +55 -6
- package/src/widgets/Dashboard/PieSetting.vue +1 -1
- package/src/widgets/Dashboard/PolarArea.vue +49 -7
- package/src/widgets/Dashboard/PolarAreaSetting.vue +1 -1
- package/src/widgets/Dashboard/SharingModal.vue +4 -5
- package/src/widgets/Dashboard/ViewSelector.vue +2 -2
- package/src/widgets/Dashboard/VirtualTableSetting.vue +121 -184
- package/src/widgets/{Dashboard.vue → Dashboard0.vue} +426 -343
- package/src/widgets/EmbeddedVideoSetting.vue +7 -5
- package/src/widgets/FAQ.vue +16 -3
- package/src/widgets/FAQSetting.vue +53 -47
- package/src/widgets/FeatureList.vue +3 -0
- package/src/widgets/FeatureListSetting.vue +112 -102
- package/src/widgets/FlexSetting.vue +83 -106
- package/src/widgets/GridSetting.vue +71 -196
- package/src/widgets/Header2.vue +34 -71
- package/src/widgets/Header2Setting.vue +95 -179
- package/src/widgets/HeaderSetting.vue +16 -18
- package/src/widgets/IconListSetting.vue +69 -65
- package/src/widgets/ImageSetting.vue +33 -60
- package/src/widgets/LinkSetting.vue +60 -37
- package/src/widgets/LinkSettingModal.vue +173 -0
- package/src/widgets/LogViewer.vue +1 -1
- package/src/widgets/MarginSetting.vue +2 -2
- package/src/widgets/MenuEditor.vue +1 -1
- package/src/widgets/MenuItem1Setting.vue +78 -0
- package/src/widgets/ModalSetting.vue +42 -44
- package/src/widgets/MultiValueSetting.vue +2 -2
- package/src/widgets/MultiValueSetting2.vue +78 -45
- package/src/widgets/OGSettingModal.vue +103 -0
- package/src/widgets/PaddingSetting.vue +2 -2
- package/src/widgets/ParagraphSetting.vue +16 -13
- package/src/widgets/PositionSetting.vue +209 -0
- package/src/widgets/PresetBar.vue +359 -210
- package/src/widgets/PresetBarPivot.vue +31 -19
- package/src/widgets/PresetSelector.vue +29 -17
- package/src/widgets/SearchModalSetting.vue +70 -0
- package/src/widgets/Share.vue +1 -2
- package/src/widgets/ShareSetting.vue +67 -60
- package/src/widgets/StyleSetting.vue +365 -150
- package/src/widgets/TestimonialSetting.vue +97 -88
- package/src/widgets/TextBlockSetting.vue +16 -13
- package/src/widgets/UserActionBuilder/UserActionConsole.vue +30 -10
- package/src/widgets/UserActionBuilder/UserActionOutput.vue +2 -2
- package/src/widgets/UserActionBuilder/UserActionOutputReply.vue +64 -87
- package/src/widgets/UserActionBuilder/UserActionProps.vue +3 -3
- package/src/widgets/UserActionBuilder.vue +4 -16
- package/src/widgets/WebComponentSelector.vue +15 -11
- package/src/widgets/WebLayoutSelector.vue +41 -270
- package/src/widgets/WebPageBuilder.vue +1019 -707
- package/src/widgets/WebPageBuilder2.vue +7 -7
- package/src/widgets/WebPageBuilder4/ButtonSetting.vue +0 -8
- package/src/widgets/WebPageBuilder4/CarouselSetting.vue +63 -7
- package/src/widgets/WebPageBuilder4/FlexAlignSetting.vue +3 -3
- package/src/widgets/WebPageBuilder4/FlexSetting.vue +1 -10
- package/src/widgets/WebPageBuilder4/MultiValueSetting.vue +2 -2
- package/src/widgets/WebPageBuilder4/PropertySetting.vue +0 -7
- package/src/widgets/WebPageBuilder4/WebPageComponentSelector.vue +1 -7
- package/src/widgets/WebPageBuilder4.vue +289 -575
- package/src/widgets/WebPageSelector.vue +1 -1
- package/src/widgets/YoutubeVideoSetting.vue +16 -13
- package/tailwind.config.js +3 -35
- package/docs/schema/user-action.json +0 -266
- package/src/App.vue +0 -25
- package/src/components/SearchButton.vue +0 -57
- package/src/entry-client.js +0 -27
- package/src/entry-server.js +0 -73
- package/src/events/event.js +0 -2
- package/src/main.js +0 -29
- package/src/mixin/website.js +0 -121
- package/src/router.js +0 -57
- package/src/widgets/MobileMenu.vue +0 -182
- package/src/widgets/WebPageBuilder4/ActionSetting.vue +0 -158
- package/src/widgets/WebPageBuilder4/ColorSetting.vue +0 -63
- package/src/widgets/WebPageBuilder4/DataSetting.vue +0 -92
- package/src/widgets/WebPageBuilder4/FontSizeSetting.vue +0 -76
- package/src/widgets/WebPageBuilder4/LinkSetting.vue +0 -68
- package/src/widgets/WebPageBuilder4/MobileMenuSetting.vue +0 -106
- package/src/widgets/WebPageBuilder4/Setting.vue +0 -73
- package/src/widgets/WebPageBuilder4/StyleSetting.vue +0 -77
- package/src/widgets/WebPageBuilder4/SvgSetting.vue +0 -207
- package/src/widgets/WebPageBuilder4/TextTransformSetting.vue +0 -70
- package/src/widgets/WebPageBuilder4/WebPageDataEdit.vue +0 -121
- package/test.json +0 -22
- /package/src/widgets/{Header1.vue → Header0.vue} +0 -0
- /package/src/widgets/{Header1Setting.vue → Header0Setting.vue} +0 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="$style.comp">
|
|
3
|
+
|
|
4
|
+
<div v-if="config.params.openSidebar" :style="leftStyle" class="relative flex flex-col bg-base-300 border-l-[1px] border-border-50">
|
|
5
|
+
<DashboardConfigs :config="config" class="flex-1" />
|
|
6
|
+
|
|
7
|
+
<div :class="$style.resize1" @mousedown="(e) => $util.dragResize(e, resize1)"></div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="flex-1 flex flex-col gap-4 py-4">
|
|
11
|
+
|
|
12
|
+
<div class="px-8 flex flex-row gap-8 items-center">
|
|
13
|
+
<button type="button" class="p-3" @click="config.params.openSidebar = !config.params.openSidebar">
|
|
14
|
+
<svg width="16" height="16" class="hover:fill-primary" :class="config.params.openSidebar ? 'fill-primary' : 'fill-text'" 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="M448 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h384c35.35 0 64-28.65 64-64V96C512 60.65 483.3 32 448 32zM136 336h-48C74.75 336 64 325.3 64 312C64 298.7 74.75 288 88 288h48C149.3 288 160 298.7 160 312C160 325.3 149.3 336 136 336zM136 240h-48C74.75 240 64 229.3 64 216C64 202.7 74.75 192 88 192h48C149.3 192 160 202.7 160 216C160 229.3 149.3 240 136 240zM136 144h-48C74.75 144 64 133.3 64 120C64 106.7 74.75 96 88 96h48C149.3 96 160 106.7 160 120C160 133.3 149.3 144 136 144zM464 416c0 8.822-7.176 16-16 16H224v-352h224c8.824 0 16 7.178 16 16V416z"/></svg>
|
|
15
|
+
</button>
|
|
16
|
+
<button type="button" class="flex flex-row gap-2 items-center">
|
|
17
|
+
<h5>{{ preset?.name }}</h5>
|
|
18
|
+
<svg width="14" height="14" 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="M432.6 209.3l-191.1 183.1C235.1 397.8 229.1 400 224 400s-11.97-2.219-16.59-6.688L15.41 209.3C5.814 200.2 5.502 184.1 14.69 175.4c9.125-9.625 24.38-9.938 33.91-.7187L224 342.8l175.4-168c9.5-9.219 24.78-8.906 33.91 .7187C442.5 184.1 442.2 200.2 432.6 209.3z"/></svg>
|
|
19
|
+
<button type="button" class="p-3" @click="load">
|
|
20
|
+
<svg width="14" height="14" class="fill-text hover: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="M468.9 32.11c13.87 0 27.18 10.77 27.18 27.04v145.9c0 10.59-8.584 19.17-19.17 19.17h-145.7c-16.28 0-27.06-13.32-27.06-27.2c0-6.634 2.461-13.4 7.96-18.9l45.12-45.14c-28.22-23.14-63.85-36.64-101.3-36.64c-88.09 0-159.8 71.69-159.8 159.8S167.8 415.9 255.9 415.9c73.14 0 89.44-38.31 115.1-38.31c18.48 0 31.97 15.04 31.97 31.96c0 35.04-81.59 70.41-147 70.41c-123.4 0-223.9-100.5-223.9-223.9S132.6 32.44 256 32.44c54.6 0 106.2 20.39 146.4 55.26l47.6-47.63C455.5 34.57 462.3 32.11 468.9 32.11z"/></svg>
|
|
21
|
+
</button>
|
|
22
|
+
</button>
|
|
23
|
+
<div class="flex-1"></div>
|
|
24
|
+
|
|
25
|
+
<button type="button" class="p-3" @click="config.params.openRightbar = !config.params.openRightbar">
|
|
26
|
+
<svg width="16" height="16" class="fill-text hover:fill-primary" :class="config.params.openRightbar ? 'fill-primary' : 'fill-text'" 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="M324.4 103.1L384 128l24.88 59.63C410.2 190.3 413 192 416 192s5.75-1.75 7.125-4.375L448 128l59.63-24.88C510.3 101.8 512 99 512 96s-1.75-5.75-4.375-7.125L448 64l-24.88-59.62C421.8 1.75 419 0 416 0s-5.75 1.75-7.125 4.375L384 64l-59.63 24.88C321.8 90.25 320 93 320 96S321.8 101.8 324.4 103.1zM507.6 408.9L448 384l-24.88-59.63C421.8 321.8 419 320 416 320s-5.75 1.75-7.125 4.375L384 384l-59.63 24.88C321.8 410.2 320 413 320 416s1.75 5.75 4.375 7.125L384 448l24.88 59.63C410.2 510.2 413 512 416 512s5.75-1.75 7.125-4.375L448 448l59.63-24.88C510.3 421.8 512 419 512 416S510.3 410.2 507.6 408.9zM384 255.6c0-6-3.375-11.62-8.875-14.38l-112.5-56.31L206.3 72.19c-5.375-10.88-23.13-10.88-28.5 0L121.4 184.9L8.875 241.2C3.375 244 0 249.6 0 255.6c0 6.125 3.375 11.62 8.875 14.38l112.5 56.37l56.38 112.7C180.4 444.4 185.1 447.9 192 447.9c5.999 0 11.62-3.512 14.25-8.887l56.38-112.7l112.5-56.37C380.6 267.2 384 261.8 384 255.6z"/></svg>
|
|
27
|
+
</button>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="flex-1 overflow-y-auto px-8">
|
|
31
|
+
<component :is="component.type"
|
|
32
|
+
v-for="component in components"
|
|
33
|
+
:="component" />
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div v-if="config.params.openRightbar" class="w-[320px] bg-base-300 flex flex-col">
|
|
39
|
+
|
|
40
|
+
<div class="flex-1"></div>
|
|
41
|
+
|
|
42
|
+
<div class="p-3">
|
|
43
|
+
<Textarea placeholder="Ask anything...">
|
|
44
|
+
<template #end>
|
|
45
|
+
<div class="p-1">
|
|
46
|
+
<button class="p-2">
|
|
47
|
+
<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="M511.1 255.1c0 12.8-7.625 24.38-19.41 29.41L44.6 477.4c-4.062 1.75-8.344 2.594-12.59 2.594c-8.625 0-17.09-3.5-23.28-10.05c-9.219-9.766-11.34-24.25-5.344-36.27l73.66-147.3l242.1-30.37L77.03 225.6l-73.66-147.3C-2.623 66.3-.4982 51.81 8.72 42.05c9.25-9.766 23.56-12.75 35.87-7.453L492.6 226.6C504.4 231.6 511.1 243.2 511.1 255.1z"/></svg>
|
|
48
|
+
</button>
|
|
49
|
+
</div>
|
|
50
|
+
</template>
|
|
51
|
+
</Textarea>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
</div>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<script setup>
|
|
60
|
+
|
|
61
|
+
import {computed, inject, onMounted, ref, watch} from "vue";
|
|
62
|
+
import DashboardConfigs from "./DashboardConfigs.vue";
|
|
63
|
+
|
|
64
|
+
const { controller, presetKey } = defineProps({
|
|
65
|
+
|
|
66
|
+
controller: {
|
|
67
|
+
type: String,
|
|
68
|
+
required: true
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
presetKey: { type: String },
|
|
72
|
+
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const alert = inject('alert')
|
|
76
|
+
const loadConfig = inject('loadConfig')
|
|
77
|
+
const saveConfig = inject('saveConfig')
|
|
78
|
+
const useSocket = inject('useSocket')
|
|
79
|
+
const socket = useSocket()
|
|
80
|
+
|
|
81
|
+
const config = ref(Object.assign({
|
|
82
|
+
params: {},
|
|
83
|
+
presets: []
|
|
84
|
+
}, presetKey ? await loadConfig(presetKey, {}) : {}))
|
|
85
|
+
|
|
86
|
+
const data = ref({})
|
|
87
|
+
|
|
88
|
+
const leftStyle = computed(() => {
|
|
89
|
+
if(!config.value.params.leftWidth)
|
|
90
|
+
config.value.params.leftWidth = 300
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
width: `${config.value.params.leftWidth}px`
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
function load(){
|
|
98
|
+
if(!preset.value) return
|
|
99
|
+
|
|
100
|
+
socket.send(`${controller}.load`, preset.value.datasource)
|
|
101
|
+
.then(res => Object.assign(data.value, res))
|
|
102
|
+
.catch(err => alert(err))
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function resize1(w){
|
|
106
|
+
if(config.value.params.leftWidth + w >= 100 && config.value.params.leftWidth + w <= 600){
|
|
107
|
+
config.value.params.leftWidth += w
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const preset = computed(() => {
|
|
112
|
+
return (config.value.presets ?? []).find(_ => _.uid === config.value.params.presetUid)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const selectedPreset = computed(() => {
|
|
116
|
+
return (config.value.presets ?? []).find(_ => _.uid === config.value.params.selectedUid)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const compClasses = [
|
|
120
|
+
'aspectRatio', 'position', 'left', 'top', 'right', 'bottom',
|
|
121
|
+
|
|
122
|
+
'bdSize', 'bdColor', 'bdRadius', 'bdStyle',
|
|
123
|
+
'divideSize', 'divideColor', 'divideStyle',
|
|
124
|
+
'outlineWidth', 'outlineColor', 'outlineStyle',
|
|
125
|
+
'bgColors', 'bgSize', 'bgPosition', 'bgRepeat',
|
|
126
|
+
'textAlign', 'verticalAlign',
|
|
127
|
+
'gap',
|
|
128
|
+
'padding', 'margin',
|
|
129
|
+
'direction', 'columns', 'rows', 'display', 'wrap',
|
|
130
|
+
'width', 'minWidth', 'maxWidth',
|
|
131
|
+
'height', 'minHeight', 'maxHeight',
|
|
132
|
+
'fontFamily', 'fontSize', 'fontWeight', 'textColor', 'lineHeight', 'overflow',
|
|
133
|
+
'textTransform', 'whitespace', 'textOverflow', 'textDecoration',
|
|
134
|
+
'boxShadow', 'opacity',
|
|
135
|
+
'colSpan', 'rowSpan',
|
|
136
|
+
'flex', 'flexAlign', 'flexJustify', 'flexBasis', 'flexColumns', 'flexWrap',
|
|
137
|
+
'flexDirection',
|
|
138
|
+
'zIndex',
|
|
139
|
+
|
|
140
|
+
'autoFlow', 'alignItems', 'justifyContent',
|
|
141
|
+
'letterSpacing', 'lineClamp',
|
|
142
|
+
|
|
143
|
+
'animate',
|
|
144
|
+
|
|
145
|
+
'blur', 'grayscale',
|
|
146
|
+
]
|
|
147
|
+
const containerClasses = [
|
|
148
|
+
'containerVariant', 'containerGridColumn', 'containerGap'
|
|
149
|
+
]
|
|
150
|
+
const itemClasses = [
|
|
151
|
+
'itemMinWidth', 'itemRatio', 'itemVariant'
|
|
152
|
+
]
|
|
153
|
+
|
|
154
|
+
const components = computed(() => {
|
|
155
|
+
if(!selectedPreset.value) return
|
|
156
|
+
|
|
157
|
+
const getComponent = (component) => {
|
|
158
|
+
if (!component.uid) return
|
|
159
|
+
if (!component.props.enabled) return
|
|
160
|
+
|
|
161
|
+
const compUid = '_' + component.uid.substring(0, 4) + ' '
|
|
162
|
+
|
|
163
|
+
const instance = {
|
|
164
|
+
type: component.type,
|
|
165
|
+
uid: component.uid,
|
|
166
|
+
|
|
167
|
+
class: compUid + compClasses.map(key => {
|
|
168
|
+
return Array.isArray(component.props[key]) ? component.props[key].join(' ') : ''
|
|
169
|
+
})
|
|
170
|
+
.filter(_ => _)
|
|
171
|
+
.join(' '),
|
|
172
|
+
|
|
173
|
+
containerClass: containerClasses.map(key => {
|
|
174
|
+
return Array.isArray(component.props[key]) ? component.props[key].join(' ') : ''
|
|
175
|
+
})
|
|
176
|
+
.filter(_ => _)
|
|
177
|
+
.join(' '),
|
|
178
|
+
|
|
179
|
+
itemClass: itemClasses.map(key => {
|
|
180
|
+
return Array.isArray(component.props[key]) ? component.props[key].join(' ') : ''
|
|
181
|
+
})
|
|
182
|
+
.filter(_ => _)
|
|
183
|
+
.join(' ')
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
for (let key in component.props) {
|
|
187
|
+
if (!compClasses.includes(key) &&
|
|
188
|
+
!containerClasses.includes(key) &&
|
|
189
|
+
!itemClasses.includes(key) &&
|
|
190
|
+
!['enabled'].includes(key)) {
|
|
191
|
+
instance[key] = component.props[key]
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const whitelistProps = [
|
|
196
|
+
'column', 'datasourceUid', 'rows', 'columns'
|
|
197
|
+
]
|
|
198
|
+
whitelistProps.forEach((key) => {
|
|
199
|
+
if (component.props[key]) {
|
|
200
|
+
instance[key] = component.props[key]
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
if(data.value[component.uid]){
|
|
205
|
+
instance.items = data.value[component.uid].items
|
|
206
|
+
}
|
|
207
|
+
else if(Array.isArray(component.items)) {
|
|
208
|
+
instance.items = component.items.map((_) => getComponent(_)).filter(_ => _)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return instance
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return selectedPreset.value.views.map(view => {
|
|
215
|
+
return getComponent(view)
|
|
216
|
+
})
|
|
217
|
+
.filter(_ => _)
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
if(presetKey){
|
|
221
|
+
console.log('Watch config changes')
|
|
222
|
+
watch(() => config, _ => saveConfig(presetKey, config.value), {
|
|
223
|
+
deep: true
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
onMounted(() => {
|
|
228
|
+
load()
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
</script>
|
|
232
|
+
|
|
233
|
+
<style module>
|
|
234
|
+
|
|
235
|
+
.comp {
|
|
236
|
+
@apply flex flex-row;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.resize1{
|
|
240
|
+
@apply w-[3px] cursor-ew-resize absolute top-0 right-0 bottom-0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
</style>
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="$style.comp">
|
|
3
|
+
|
|
4
|
+
<div class="w-[480px] border-r-[1px] border-border-50">
|
|
5
|
+
<MetricSetting :value="preset.views[0]"/>
|
|
6
|
+
|
|
7
|
+
<pre class="text-xs break-all">
|
|
8
|
+
{{ preset.views[0] }}
|
|
9
|
+
</pre>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="flex-1 p-8">
|
|
13
|
+
|
|
14
|
+
<component v-for="view in preset.views"
|
|
15
|
+
:is="view.type"
|
|
16
|
+
:="view.props" />
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
|
|
25
|
+
import {defineAsyncComponent} from "vue";
|
|
26
|
+
|
|
27
|
+
export default{
|
|
28
|
+
|
|
29
|
+
components: {
|
|
30
|
+
MetricSetting: defineAsyncComponent(() => import('../widgets/Dashboard/MetricSetting.vue')),
|
|
31
|
+
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
props: {
|
|
35
|
+
|
|
36
|
+
controller: String,
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
computed: {
|
|
42
|
+
|
|
43
|
+
preset(){
|
|
44
|
+
return this.config.presets[this.config.presetIdx]
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
data(){
|
|
51
|
+
return {
|
|
52
|
+
|
|
53
|
+
config: {
|
|
54
|
+
presets: [
|
|
55
|
+
{
|
|
56
|
+
name: "Sample 1",
|
|
57
|
+
datasource: [
|
|
58
|
+
{
|
|
59
|
+
uid: "1",
|
|
60
|
+
name: "AffiliateShareReport",
|
|
61
|
+
filters: [],
|
|
62
|
+
sorts: []
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
views: [
|
|
66
|
+
{
|
|
67
|
+
type: "Metric",
|
|
68
|
+
props: {
|
|
69
|
+
datasourceUid: "1",
|
|
70
|
+
columns: [
|
|
71
|
+
{
|
|
72
|
+
key: "id",
|
|
73
|
+
modifier: "count"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: "id",
|
|
77
|
+
modifier: "sum"
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
presetIdx: 0
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
metric1: {
|
|
89
|
+
props: {}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
methods: {
|
|
95
|
+
|
|
96
|
+
getController(){
|
|
97
|
+
return this.controller
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
provide(){
|
|
103
|
+
return {
|
|
104
|
+
getController: this.getController
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
</script>
|
|
111
|
+
|
|
112
|
+
<style module>
|
|
113
|
+
|
|
114
|
+
.comp{
|
|
115
|
+
@apply flex flex-row;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
</style>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Modal ref="modal" width="360" height="480">
|
|
3
|
+
<template v-slot:head>
|
|
4
|
+
<div class="relative p-5">
|
|
5
|
+
<h3>Select Component</h3>
|
|
6
|
+
<div class="absolute top-0 right-0 p-2">
|
|
7
|
+
<button type="button" class="p-2" @click="$refs.modal.close()">
|
|
8
|
+
<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">
|
|
9
|
+
<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"/>
|
|
10
|
+
</svg>
|
|
11
|
+
</button>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
<template v-slot:foot>
|
|
16
|
+
<div class="p-5">
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
<div class="flex-1 divide-y divide-border-50">
|
|
21
|
+
|
|
22
|
+
<div class="flex flex-col">
|
|
23
|
+
<button v-for="component of components"
|
|
24
|
+
class="p-3 px-6 text-left"
|
|
25
|
+
@click="add(component)">
|
|
26
|
+
{{ component.type }}
|
|
27
|
+
</button>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
</Modal>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup>
|
|
36
|
+
|
|
37
|
+
import {ref, useTemplateRef} from "vue";
|
|
38
|
+
import md5 from "md5";
|
|
39
|
+
|
|
40
|
+
const modal = useTemplateRef('modal')
|
|
41
|
+
const callback = ref(null)
|
|
42
|
+
|
|
43
|
+
function open(_, cb){
|
|
44
|
+
callback.value = cb
|
|
45
|
+
modal.value.open()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function add(component){
|
|
49
|
+
if(typeof callback.value === 'function'){
|
|
50
|
+
const newComponent = JSON.parse(JSON.stringify(component))
|
|
51
|
+
newComponent.uid = md5(new Date().toString())
|
|
52
|
+
callback.value(newComponent)
|
|
53
|
+
}
|
|
54
|
+
modal.value.close()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const components = ref([
|
|
58
|
+
{
|
|
59
|
+
type: "Grid",
|
|
60
|
+
name: "Grid",
|
|
61
|
+
props: {
|
|
62
|
+
enabled: true
|
|
63
|
+
},
|
|
64
|
+
items: []
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: "VirtualTable",
|
|
68
|
+
name: "Virtual Table",
|
|
69
|
+
props: {
|
|
70
|
+
enabled: true,
|
|
71
|
+
class: "bg-base-500 max-h-[80vh]"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "Metric",
|
|
76
|
+
name: "Metric",
|
|
77
|
+
props: {
|
|
78
|
+
enabled: true,
|
|
79
|
+
class: "bg-base-500"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
defineExpose({
|
|
85
|
+
open
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<style module>
|
|
91
|
+
|
|
92
|
+
.comp{
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
</style>
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-col overflow-hidden relative">
|
|
3
|
+
|
|
4
|
+
<TransitionGroup name="openltr" tag="div" class="flex-1 flex flex-col">
|
|
5
|
+
|
|
6
|
+
<div v-if="view" class="flex-1 flex flex-col">
|
|
7
|
+
|
|
8
|
+
<div class="flex flex-row items-center gap-2 p-5">
|
|
9
|
+
<button type="button" @click="delete config.params.viewUid">
|
|
10
|
+
<svg width="14" height="14" 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>
|
|
11
|
+
</button>
|
|
12
|
+
<div class="flex-1">
|
|
13
|
+
<h5>{{ view.name }}</h5>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="flex-1 overflow-y-auto">
|
|
18
|
+
<component :is="`${view.type}Setting`"
|
|
19
|
+
:item="view"
|
|
20
|
+
:view-types="viewTypes"
|
|
21
|
+
:view-index="viewIndex"
|
|
22
|
+
:view-type="viewType">
|
|
23
|
+
</component>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div v-else-if="preset" class="flex-1 flex flex-col">
|
|
29
|
+
<div class="flex flex-row items-center gap-2 p-5">
|
|
30
|
+
<button type="button" @click="delete config.params.presetUid">
|
|
31
|
+
<svg width="14" height="14" 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>
|
|
32
|
+
</button>
|
|
33
|
+
<div class="flex-1">
|
|
34
|
+
<h5>{{ preset.name }}</h5>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="flex-1 overflow-y-auto">
|
|
39
|
+
<div class="p-5">
|
|
40
|
+
|
|
41
|
+
<div class="flex flex-col gap-1">
|
|
42
|
+
<div class="flex flex-row gap-3">
|
|
43
|
+
<label class="flex-1">Views</label>
|
|
44
|
+
<button type="button"
|
|
45
|
+
class="text-primary"
|
|
46
|
+
@click="$refs.componentSelector.open(null, comp => views.push(comp))">
|
|
47
|
+
Add
|
|
48
|
+
</button>
|
|
49
|
+
</div>
|
|
50
|
+
<TreeView2 :items="views">
|
|
51
|
+
<template #default="{ item, index, parent }">
|
|
52
|
+
<div class="flex flex-row gap-2 bg-base-500 hover:bg-text-50 p-3">
|
|
53
|
+
<div class="flex-1 flex flex-row"
|
|
54
|
+
@click="config.params.viewUid = item.uid">
|
|
55
|
+
<div class="text-ellipsis-nowrap flex-1">
|
|
56
|
+
{{ item.name }}
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
<button v-if="Array.isArray(item.items)" @click="$refs.componentSelector.open(null, comp => item.items.push(comp))">
|
|
60
|
+
<svg width="14" height="14" class="fill-text-300 hover:fill-primary" 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>
|
|
61
|
+
</button>
|
|
62
|
+
<button type="button" @click="parent.splice(index, 1)">
|
|
63
|
+
<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>
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
</template>
|
|
67
|
+
</TreeView2>
|
|
68
|
+
|
|
69
|
+
<DashboardComponentSelector ref="componentSelector" />
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div v-else-if="config" class="flex-1 flex flex-col">
|
|
77
|
+
<div class="p-5">
|
|
78
|
+
<h5>Select Presets</h5>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class="flex-1 overflow-y-auto">
|
|
82
|
+
<div class="p-5">
|
|
83
|
+
<div class="flex flex-row gap-3">
|
|
84
|
+
<label class="text-text-300 flex-1">Presets</label>
|
|
85
|
+
<button type="button" class="text-primary" @click="addPreset">Add</button>
|
|
86
|
+
</div>
|
|
87
|
+
<ListItem :items="presets"
|
|
88
|
+
class="mt-2"
|
|
89
|
+
@reorder="(from, to) => { presets.splice(to, 0, presets.splice(from, 1)[0]); }">
|
|
90
|
+
<template v-slot="{ item, index }">
|
|
91
|
+
<div class="flex flex-row items-center gap-3 p-3 bg-base-500 hover:bg-text-50">
|
|
92
|
+
<div data-reorder>
|
|
93
|
+
<svg width="14" height="14" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M496 288H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16zm0-128H16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h480c8.8 0 16-7.2 16-16v-32c0-8.8-7.2-16-16-16z"/></svg>
|
|
94
|
+
</div>
|
|
95
|
+
<Radio :value="item.uid" v-model="config.params.selectedUid" />
|
|
96
|
+
<div class="flex-1" @click="config.params.presetUid = item.uid">
|
|
97
|
+
{{ item.name }}
|
|
98
|
+
</div>
|
|
99
|
+
<div>
|
|
100
|
+
<button type="button" @click="presets.splice(index, 1)">
|
|
101
|
+
<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>
|
|
102
|
+
</button>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
|
106
|
+
</ListItem>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
</TransitionGroup>
|
|
112
|
+
|
|
113
|
+
</div>
|
|
114
|
+
</template>
|
|
115
|
+
|
|
116
|
+
<script setup>
|
|
117
|
+
|
|
118
|
+
import {computed, provide, ref} from "vue";
|
|
119
|
+
import md5 from "md5";
|
|
120
|
+
import DashboardComponentSelector from "./DashboardComponentSelector.vue";
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
const { config } = defineProps({
|
|
124
|
+
config: {
|
|
125
|
+
type: Object,
|
|
126
|
+
required: true
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const presets = computed(() => {
|
|
131
|
+
if(!Array.isArray(config.presets))
|
|
132
|
+
config.presets = []
|
|
133
|
+
return config.presets
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const preset = computed(() => {
|
|
137
|
+
return (presets.value ?? []).find(_ => _.uid === config.params.presetUid)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
const views = computed(() => {
|
|
141
|
+
if(!preset.value) return []
|
|
142
|
+
|
|
143
|
+
if(!Array.isArray(preset.value.views))
|
|
144
|
+
preset.value.views = []
|
|
145
|
+
return preset.value.views
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
const view = computed(() => {
|
|
149
|
+
if(config.params.viewUid && preset){
|
|
150
|
+
|
|
151
|
+
const getView = (uid, items) => {
|
|
152
|
+
for(let item of items){
|
|
153
|
+
if(item.uid === uid){
|
|
154
|
+
return item
|
|
155
|
+
}
|
|
156
|
+
else if(Array.isArray(item.items)){
|
|
157
|
+
const subItem = getView(uid, item.items)
|
|
158
|
+
if(subItem)
|
|
159
|
+
return subItem
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return getView(config.params.viewUid, views.value)
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
const viewTypes = ref([
|
|
169
|
+
{text: 'Mobile', value: ''},
|
|
170
|
+
{text: 'Tablet', value: 'md:'},
|
|
171
|
+
{text: 'Desktop', value: 'xl:'},
|
|
172
|
+
{text: 'TV', value: '2xl:'},
|
|
173
|
+
])
|
|
174
|
+
|
|
175
|
+
const viewIndex = ref(1)
|
|
176
|
+
const viewType = ref('md:')
|
|
177
|
+
|
|
178
|
+
function addPreset(obj){
|
|
179
|
+
|
|
180
|
+
const preset = {
|
|
181
|
+
uid: md5(Date.now().toString() + Math.random().toString()),
|
|
182
|
+
name: "New Preset",
|
|
183
|
+
views: [],
|
|
184
|
+
datasource: {},
|
|
185
|
+
...obj,
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
presets.value.push(preset)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function getPresetDatasource(){
|
|
192
|
+
return preset ? preset.value.datasource : {}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
provide('getPresetDatasource', getPresetDatasource)
|
|
196
|
+
|
|
197
|
+
</script>
|
|
198
|
+
|
|
199
|
+
<style module>
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
</style>
|