@mixd-id/web-scaffold 0.1.230406355 → 0.1.230406356
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/components/GHeatMaps.vue +8 -18
- package/src/components/List.vue +1 -0
- package/src/components/VirtualGrid.vue +29 -17
- package/src/components/VirtualTable.vue +0 -8
- package/src/mixin/ready-state.js +37 -0
- package/src/utils/dashboard.js +4 -4
- package/src/utils/event-bus.js +8 -0
- package/src/utils/helpers.mjs +8 -1
- package/src/utils/preset-selector.js +1 -1
- package/src/utils/preset-selector.mjs +8 -1
- package/src/widgets/Dashboard/BarChart.vue +22 -18
- package/src/widgets/Dashboard/BarChartSetting.vue +6 -3
- package/src/widgets/Dashboard/DatasourceSelector.vue +0 -1
- package/src/widgets/Dashboard/Doughnut.vue +12 -3
- package/src/widgets/Dashboard/DoughnutSetting.vue +14 -3
- package/src/widgets/Dashboard/InteractionEdit.vue +2 -2
- package/src/widgets/Dashboard/Metric.vue +10 -9
- package/src/widgets/Dashboard/MetricSetting.vue +5 -1
- package/src/widgets/Dashboard/Pie.vue +11 -7
- package/src/widgets/Dashboard/PieSetting.vue +14 -3
- package/src/widgets/Dashboard/PolarArea.vue +9 -2
- package/src/widgets/Dashboard/PolarAreaSetting.vue +14 -3
- package/src/widgets/Dashboard/VirtualColumnEdit.vue +97 -0
- package/src/widgets/Dashboard/VirtualTableSetting.vue +25 -2
- package/src/widgets/Dashboard.vue +834 -518
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mixd-id/web-scaffold",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.230406356",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite serve",
|
|
7
7
|
"build": "vite build",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"glob": "^8.0.3",
|
|
54
54
|
"lodash": "^4.17.21",
|
|
55
55
|
"md5": "^2.3.0",
|
|
56
|
+
"mitt": "^3.0.1",
|
|
56
57
|
"nprogress": "^0.2.0",
|
|
57
58
|
"pinia": "^2.0.2",
|
|
58
59
|
"prismjs": "^1.28.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="$style.comp">
|
|
2
|
+
<div v-if="readyState === 1" :class="$style.comp">
|
|
3
3
|
<div class="flex flex-row items-center gap-2 p-1 px-3 p-2">
|
|
4
4
|
<div class="flex-1">
|
|
5
5
|
<label class="text-text-400">{{ label }}</label>
|
|
@@ -37,11 +37,15 @@
|
|
|
37
37
|
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
|
+
<div v-else :class="$style.comp" class="min-h-[200px] flex items-center justify-center">
|
|
41
|
+
<label class="text-text-300">Loading...</label>
|
|
42
|
+
</div>
|
|
40
43
|
</template>
|
|
41
44
|
|
|
42
45
|
<script>
|
|
43
46
|
|
|
44
47
|
import { Loader } from '@googlemaps/js-api-loader';
|
|
48
|
+
import {readyStateMixin} from "../mixin/ready-state";
|
|
45
49
|
|
|
46
50
|
let loader = null
|
|
47
51
|
|
|
@@ -70,6 +74,8 @@ export default{
|
|
|
70
74
|
}
|
|
71
75
|
},
|
|
72
76
|
|
|
77
|
+
mixins: [ readyStateMixin ],
|
|
78
|
+
|
|
73
79
|
mounted() {
|
|
74
80
|
this.load()
|
|
75
81
|
},
|
|
@@ -196,23 +202,7 @@ export default{
|
|
|
196
202
|
]
|
|
197
203
|
});
|
|
198
204
|
|
|
199
|
-
var heatMapData = [
|
|
200
|
-
/*{location: new google.maps.LatLng(37.782, -122.447), weight: 0.5},
|
|
201
|
-
new google.maps.LatLng(37.782, -122.445),
|
|
202
|
-
{location: new google.maps.LatLng(37.782, -122.443), weight: 2},
|
|
203
|
-
{location: new google.maps.LatLng(37.782, -122.441), weight: 3},
|
|
204
|
-
{location: new google.maps.LatLng(37.782, -122.439), weight: 2},
|
|
205
|
-
new google.maps.LatLng(37.782, -122.437),
|
|
206
|
-
{location: new google.maps.LatLng(37.782, -122.435), weight: 0.5},
|
|
207
|
-
|
|
208
|
-
{location: new google.maps.LatLng(37.785, -122.447), weight: 3},
|
|
209
|
-
{location: new google.maps.LatLng(37.785, -122.445), weight: 2},
|
|
210
|
-
new google.maps.LatLng(37.785, -122.443),
|
|
211
|
-
{location: new google.maps.LatLng(37.785, -122.441), weight: 0.5},
|
|
212
|
-
new google.maps.LatLng(37.785, -122.439),
|
|
213
|
-
{location: new google.maps.LatLng(37.785, -122.437), weight: 2},
|
|
214
|
-
{location: new google.maps.LatLng(37.785, -122.435), weight: 3}*/
|
|
215
|
-
];
|
|
205
|
+
var heatMapData = [];
|
|
216
206
|
|
|
217
207
|
this.datasets.forEach((item) => {
|
|
218
208
|
if(item[0] && item[1] && item[2]){
|
package/src/components/List.vue
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="$style.virtualGrid" @click="resize">
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
<slot name="start"></slot>
|
|
5
|
+
|
|
6
|
+
<div ref="container" class="flex-1 overflow-y-auto">
|
|
7
|
+
<div ref="scroller" :class="$style.scroller" :style="scrollerStyle">
|
|
8
|
+
<div :class="spacerClass" ref="spacer" :style="spacerStyle">
|
|
9
|
+
<div v-for="(item, index) in visibleItems" :key="item" :data-id="item.id"
|
|
10
|
+
@click="">
|
|
11
|
+
<slot name="item" :item="item" :index="index">
|
|
12
|
+
{{ item }}
|
|
13
|
+
</slot>
|
|
14
|
+
</div>
|
|
15
|
+
<slot name="end"></slot>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<slot name="end"></slot>
|
|
13
21
|
|
|
14
22
|
<div :class="$style.calc" v-if="items && items.length > 0" ref="calc">
|
|
15
|
-
<slot name="item" :item="items[0]" :index="0"
|
|
23
|
+
<slot name="item" :item="items[0]" :index="0">
|
|
24
|
+
{{ items[0] }}
|
|
25
|
+
</slot>
|
|
16
26
|
</div>
|
|
17
27
|
|
|
18
28
|
<Teleport v-if="optBar" :to="optBar">
|
|
@@ -70,9 +80,11 @@ export default{
|
|
|
70
80
|
methods: {
|
|
71
81
|
|
|
72
82
|
handleScroll: throttle(function(){
|
|
73
|
-
|
|
83
|
+
if(!this.$refs.scroller) return
|
|
84
|
+
|
|
85
|
+
this.scrollTop = this.$refs.container.scrollTop
|
|
74
86
|
|
|
75
|
-
if(this.scrollTop > this.$refs.scroller.offsetHeight - this.$
|
|
87
|
+
if(this.scrollTop > this.$refs.scroller.offsetHeight - this.$refs.container.clientHeight - this.itemHeight){
|
|
76
88
|
if(!this.isOnEndScroll){
|
|
77
89
|
this.$emit('scroll-end')
|
|
78
90
|
this.isOnEndScroll = true
|
|
@@ -86,7 +98,7 @@ export default{
|
|
|
86
98
|
}, 16),
|
|
87
99
|
|
|
88
100
|
init(){
|
|
89
|
-
this.$
|
|
101
|
+
this.$refs.container.addEventListener(
|
|
90
102
|
"scroll",
|
|
91
103
|
this.handleScroll,
|
|
92
104
|
this.passiveScrollSupported() ? { passive: true } : false
|
|
@@ -121,9 +133,9 @@ export default{
|
|
|
121
133
|
|
|
122
134
|
this.$nextTick(() => {
|
|
123
135
|
if(this.$refs.calc){
|
|
124
|
-
const elHeight = parseInt(window.getComputedStyle(this.$
|
|
125
|
-
window.getComputedStyle(this.$
|
|
126
|
-
window.getComputedStyle(this.$
|
|
136
|
+
const elHeight = parseInt(window.getComputedStyle(this.$refs.container).height !== '0px' ?
|
|
137
|
+
window.getComputedStyle(this.$refs.container).height :
|
|
138
|
+
window.getComputedStyle(this.$refs.container).maxHeight)
|
|
127
139
|
|
|
128
140
|
if(isNaN(elHeight)) return
|
|
129
141
|
|
|
@@ -256,7 +268,7 @@ export default{
|
|
|
256
268
|
<style module>
|
|
257
269
|
|
|
258
270
|
.virtualGrid{
|
|
259
|
-
@apply flex-
|
|
271
|
+
@apply flex flex-col gap-3;
|
|
260
272
|
}
|
|
261
273
|
|
|
262
274
|
.scroller{
|
|
@@ -90,19 +90,11 @@
|
|
|
90
90
|
import throttle from "lodash/throttle";
|
|
91
91
|
import dayjs from "dayjs";
|
|
92
92
|
import {accessNestedObject} from "../utils/helpers.mjs";
|
|
93
|
-
import {useDatasource} from "../stores/datasource";
|
|
94
93
|
|
|
95
94
|
const _DEFAULT_COLUMN_WIDTH = '100px'
|
|
96
95
|
|
|
97
96
|
export default{
|
|
98
97
|
|
|
99
|
-
setup(){
|
|
100
|
-
const datasource = useDatasource()
|
|
101
|
-
return {
|
|
102
|
-
datasource
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
|
|
106
98
|
inject: [ 'emitRoot', 'listStyle' ],
|
|
107
99
|
|
|
108
100
|
emits: [ 'scroll-end', 'item-click' ],
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {useEmitter} from "../utils/event-bus";
|
|
2
|
+
|
|
3
|
+
export const readyStateMixin = {
|
|
4
|
+
|
|
5
|
+
data(){
|
|
6
|
+
return {
|
|
7
|
+
emitter: null,
|
|
8
|
+
readyState: 1,
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
methods: {
|
|
13
|
+
|
|
14
|
+
resetState(){
|
|
15
|
+
this.setState(1)
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
setState(state){
|
|
19
|
+
this.readyState = state
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
mounted() {
|
|
25
|
+
this.emitter = useEmitter()
|
|
26
|
+
this.emitter.on(`${this.uid}.readyState`, (state) => {
|
|
27
|
+
this.readyState = state
|
|
28
|
+
})
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
props: {
|
|
32
|
+
|
|
33
|
+
uid: String
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
package/src/utils/dashboard.js
CHANGED
|
@@ -56,7 +56,8 @@ const getModelFromDatasource = async (datasource, opt) => {
|
|
|
56
56
|
const tableColumns = await getSequelizeColumns(datasource.columns, opt)
|
|
57
57
|
|
|
58
58
|
opt.conn.define(datasource.datasourceUid, tableColumns, {
|
|
59
|
-
tableName: `datasource_${datasource.datasourceUid}
|
|
59
|
+
tableName: `datasource_${datasource.datasourceUid}`,
|
|
60
|
+
timestamps: false
|
|
60
61
|
})
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -93,12 +94,11 @@ const getSequelizeColumns = async (columns, opt) => {
|
|
|
93
94
|
autoIncrement: true,
|
|
94
95
|
primaryKey: true,
|
|
95
96
|
allowNull: false,
|
|
96
|
-
}
|
|
97
|
-
createdAt: { type: DataTypes.DATE },
|
|
98
|
-
updatedAt: { type: DataTypes.DATE },
|
|
97
|
+
}
|
|
99
98
|
}
|
|
100
99
|
|
|
101
100
|
for(let column of columns){
|
|
101
|
+
if(column.key === 'id') continue
|
|
102
102
|
|
|
103
103
|
let type
|
|
104
104
|
switch(column.type){
|
package/src/utils/helpers.mjs
CHANGED
|
@@ -372,13 +372,20 @@ const round = (num, precision = 0) => {
|
|
|
372
372
|
return Math.round(n) / p
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
|
|
375
|
+
let invokeAfterIdleStore = []
|
|
376
|
+
const invokeAfterIdle = (callback, delay = 1300) => {
|
|
376
377
|
let timeoutId
|
|
377
378
|
|
|
378
379
|
return function(){
|
|
380
|
+
if(invokeAfterIdleStore.includes(callback))
|
|
381
|
+
return
|
|
382
|
+
|
|
383
|
+
invokeAfterIdleStore.push(callback)
|
|
384
|
+
|
|
379
385
|
window.clearTimeout(timeoutId)
|
|
380
386
|
timeoutId = window.setTimeout(() => {
|
|
381
387
|
callback.apply(this, arguments)
|
|
388
|
+
invokeAfterIdleStore.splice(invokeAfterIdleStore.indexOf(callback), 1)
|
|
382
389
|
}, delay)
|
|
383
390
|
}
|
|
384
391
|
}
|
|
@@ -1274,7 +1274,7 @@ const presetToSequelizeList = async(preset, {
|
|
|
1274
1274
|
|
|
1275
1275
|
if(!initialOrder){
|
|
1276
1276
|
initialOrder = [
|
|
1277
|
-
[ updatedAtField.fieldName, 'desc' ],
|
|
1277
|
+
...(updatedAtField ? [[ updatedAtField.fieldName, 'desc' ]] : []),
|
|
1278
1278
|
[ 'id', 'desc' ],
|
|
1279
1279
|
]
|
|
1280
1280
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import md5 from "md5";
|
|
2
|
+
|
|
1
3
|
const sortsFn = function(a, b, sorts, index){
|
|
2
4
|
|
|
3
5
|
const sort = sorts[index]
|
|
@@ -176,10 +178,15 @@ const generateTotalColumns = (preset, items) => {
|
|
|
176
178
|
items.push(totalItem)
|
|
177
179
|
}
|
|
178
180
|
|
|
181
|
+
const getPresetUid = function(extra = ''){
|
|
182
|
+
return md5('preset-' + new Date().getTime() + extra)
|
|
183
|
+
}
|
|
184
|
+
|
|
179
185
|
export {
|
|
180
186
|
sortsFn,
|
|
181
187
|
pickColumns,
|
|
182
188
|
setupConfig,
|
|
183
189
|
generatePivotColumns,
|
|
184
|
-
generateTotalColumns
|
|
190
|
+
generateTotalColumns,
|
|
191
|
+
getPresetUid
|
|
185
192
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="$style.comp">
|
|
2
|
+
<div :class="$style.comp" :style="cStyle">
|
|
3
3
|
|
|
4
|
-
<div v-if="readyState === 2" class="flex-1 flex">
|
|
5
|
-
<
|
|
6
|
-
<svg class="animate-spin aspect-square w-[24px] h-[24px]" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
|
|
7
|
-
</div>
|
|
4
|
+
<div v-if="readyState === 2" class="flex-1 flex items-center justify-center">
|
|
5
|
+
<label class="text-text-300">Loading...</label>
|
|
8
6
|
</div>
|
|
9
7
|
|
|
10
8
|
<div v-else-if="isError" class="flex-1 flex">
|
|
@@ -76,6 +74,7 @@ import {Bar} from 'vue-chartjs'
|
|
|
76
74
|
import Chart from 'chart.js/auto'
|
|
77
75
|
import { color } from 'chart.js/helpers'
|
|
78
76
|
import {strVars} from "../../utils/helpers.mjs";
|
|
77
|
+
import {readyStateMixin} from "../../mixin/ready-state";
|
|
79
78
|
|
|
80
79
|
export default{
|
|
81
80
|
|
|
@@ -92,6 +91,12 @@ export default{
|
|
|
92
91
|
}
|
|
93
92
|
},
|
|
94
93
|
|
|
94
|
+
cStyle(){
|
|
95
|
+
return {
|
|
96
|
+
minHeight: this.height
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
|
|
95
100
|
chartData(){
|
|
96
101
|
if(!this.value?.datasets)
|
|
97
102
|
return { labels:[], datasets:[] }
|
|
@@ -219,9 +224,8 @@ export default{
|
|
|
219
224
|
'#EC87C0'
|
|
220
225
|
],
|
|
221
226
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
readyState: 1,
|
|
227
|
+
height: '',
|
|
228
|
+
datasets: null
|
|
225
229
|
}
|
|
226
230
|
},
|
|
227
231
|
|
|
@@ -261,14 +265,6 @@ export default{
|
|
|
261
265
|
|
|
262
266
|
},
|
|
263
267
|
|
|
264
|
-
resetState(){
|
|
265
|
-
this.setState(1)
|
|
266
|
-
},
|
|
267
|
-
|
|
268
|
-
setState(state){
|
|
269
|
-
this.readyState = state
|
|
270
|
-
},
|
|
271
|
-
|
|
272
268
|
toggleExcludes(yLegend){
|
|
273
269
|
if(this.excluded.includes(yLegend.key))
|
|
274
270
|
this.excluded.splice(this.excluded.indexOf(yLegend.key), 1)
|
|
@@ -278,6 +274,12 @@ export default{
|
|
|
278
274
|
|
|
279
275
|
},
|
|
280
276
|
|
|
277
|
+
mounted() {
|
|
278
|
+
this.height = this.$el.clientHeight + 'px'
|
|
279
|
+
},
|
|
280
|
+
|
|
281
|
+
mixins: [ readyStateMixin ],
|
|
282
|
+
|
|
281
283
|
props: {
|
|
282
284
|
|
|
283
285
|
datasourceUid: String,
|
|
@@ -309,7 +311,9 @@ export default{
|
|
|
309
311
|
|
|
310
312
|
value: Object,
|
|
311
313
|
|
|
312
|
-
interactions: Array
|
|
314
|
+
interactions: Array,
|
|
315
|
+
|
|
316
|
+
uid: String
|
|
313
317
|
|
|
314
318
|
},
|
|
315
319
|
|
|
@@ -321,7 +325,7 @@ export default{
|
|
|
321
325
|
|
|
322
326
|
.comp{
|
|
323
327
|
@apply border-[1px] border-text-50 bg-base-500 rounded-lg;
|
|
324
|
-
@apply p-3 flex flex-col;
|
|
328
|
+
@apply p-3 flex flex-col min-h-[200px];
|
|
325
329
|
}
|
|
326
330
|
|
|
327
331
|
</style>
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
61
|
<ListItem :items="cXAxes" class="mt-2 bg-transparent" container-class="flex flex-col gap-1"
|
|
62
|
-
@reorder="(from, to) => { cXAxes.splice(to, 0, cXAxes.splice(from, 1)[0]); }">
|
|
62
|
+
@reorder="(from, to) => { cXAxes.splice(to, 0, cXAxes.splice(from, 1)[0]); $emit('change') }">
|
|
63
63
|
<template v-slot="{ item, index }">
|
|
64
64
|
<div class="flex flex-row items-center gap-2">
|
|
65
65
|
<div data-reorder v-if="cXAxes.length > 1 && !readonly">
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
</div>
|
|
127
127
|
|
|
128
128
|
<ListItem :items="cYAxes" class="mt-2 bg-transparent" container-class="flex flex-col gap-1"
|
|
129
|
-
@reorder="(from, to) => { cYAxes.splice(to, 0, cYAxes.splice(from, 1)[0]); }">
|
|
129
|
+
@reorder="(from, to) => { cYAxes.splice(to, 0, cYAxes.splice(from, 1)[0]); $emit('change') }">
|
|
130
130
|
<template v-slot="{ item, index }">
|
|
131
131
|
<div class="flex flex-row items-center gap-2">
|
|
132
132
|
<div data-reorder v-if="cYAxes.length > 1">
|
|
@@ -238,7 +238,10 @@ export default{
|
|
|
238
238
|
|
|
239
239
|
return this.selectedDatasource.pivot?.enabled ?
|
|
240
240
|
this.selectedDatasource.pivot.columns :
|
|
241
|
-
|
|
241
|
+
[
|
|
242
|
+
...(this.selectedDatasource.computedColumns ?? []),
|
|
243
|
+
...this.selectedDatasource.columns
|
|
244
|
+
]
|
|
242
245
|
},
|
|
243
246
|
|
|
244
247
|
xAxes(){
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex flex-col gap-2"
|
|
2
|
+
<div v-if="readyState === 1" class="flex flex-col gap-2">
|
|
3
3
|
|
|
4
4
|
<Doughnut class="aspect-square"
|
|
5
5
|
:options="chartOptions"
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
|
+
|
|
14
|
+
<div v-else-if="readyState === 2" class="aspect-square flex items-center justify-center">
|
|
15
|
+
<label class="text-text-300">Loading...</label>
|
|
16
|
+
</div>
|
|
13
17
|
</template>
|
|
14
18
|
|
|
15
19
|
<script>
|
|
@@ -18,6 +22,7 @@ import { Doughnut } from 'vue-chartjs'
|
|
|
18
22
|
import Chart from 'chart.js/auto'
|
|
19
23
|
import {color} from "chart.js/helpers";
|
|
20
24
|
import {strVars} from "../../utils/helpers.mjs";
|
|
25
|
+
import {readyStateMixin} from "../../mixin/ready-state";
|
|
21
26
|
|
|
22
27
|
export default{
|
|
23
28
|
|
|
@@ -88,7 +93,7 @@ export default{
|
|
|
88
93
|
'#FFCE54',
|
|
89
94
|
'#ED5565',
|
|
90
95
|
'#EC87C0'
|
|
91
|
-
]
|
|
96
|
+
]
|
|
92
97
|
}
|
|
93
98
|
},
|
|
94
99
|
|
|
@@ -130,6 +135,8 @@ export default{
|
|
|
130
135
|
|
|
131
136
|
},
|
|
132
137
|
|
|
138
|
+
mixins: [ readyStateMixin ],
|
|
139
|
+
|
|
133
140
|
props: {
|
|
134
141
|
|
|
135
142
|
label: String,
|
|
@@ -142,7 +149,9 @@ export default{
|
|
|
142
149
|
|
|
143
150
|
interactions: Array,
|
|
144
151
|
|
|
145
|
-
|
|
152
|
+
uid: String,
|
|
153
|
+
|
|
154
|
+
},
|
|
146
155
|
|
|
147
156
|
}
|
|
148
157
|
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
v-model="value.props.rows"
|
|
34
34
|
:readonly="readonly"
|
|
35
35
|
@change="$emit('change')">
|
|
36
|
-
<option v-for="column in
|
|
36
|
+
<option v-for="column in selectedDatasourceColumns"
|
|
37
37
|
:value="column.key">
|
|
38
38
|
{{ column.label }}
|
|
39
39
|
</option>
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
v-model="value.props.column"
|
|
65
65
|
:readonly="readonly"
|
|
66
66
|
@change="onColumnChanged">
|
|
67
|
-
<option v-for="column in
|
|
67
|
+
<option v-for="column in selectedDatasourceColumns"
|
|
68
68
|
:value="column.key">
|
|
69
69
|
{{ column.label }}
|
|
70
70
|
</option>
|
|
@@ -139,7 +139,18 @@ export default{
|
|
|
139
139
|
|
|
140
140
|
selectedDatasource(){
|
|
141
141
|
return this.datasource.find(d => d.uid === this.value.props.datasourceUid)
|
|
142
|
-
}
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
selectedDatasourceColumns(){
|
|
145
|
+
if(!this.selectedDatasource) return []
|
|
146
|
+
|
|
147
|
+
return this.selectedDatasource.pivot?.enabled ?
|
|
148
|
+
this.selectedDatasource.pivot.columns :
|
|
149
|
+
[
|
|
150
|
+
...(this.selectedDatasource.computedColumns ?? []),
|
|
151
|
+
...this.selectedDatasource.columns
|
|
152
|
+
]
|
|
153
|
+
},
|
|
143
154
|
|
|
144
155
|
},
|
|
145
156
|
|
|
@@ -139,7 +139,7 @@ export default{
|
|
|
139
139
|
|
|
140
140
|
emits: [ 'save' ],
|
|
141
141
|
|
|
142
|
-
inject: [ '
|
|
142
|
+
inject: [ 'getPresets', 'socket' ],
|
|
143
143
|
|
|
144
144
|
computed: {
|
|
145
145
|
|
|
@@ -154,7 +154,7 @@ export default{
|
|
|
154
154
|
},
|
|
155
155
|
|
|
156
156
|
presets(){
|
|
157
|
-
return this.
|
|
157
|
+
return this.getPresets()
|
|
158
158
|
},
|
|
159
159
|
|
|
160
160
|
selectedPreset(){
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
<div :class="$style.comp">
|
|
3
3
|
<label class="text-text-400 text-ellipsis overflow-hidden whitespace-nowrap">{{ label }}</label>
|
|
4
4
|
<div class="flex flex-row gap-2">
|
|
5
|
-
<h1 class="text-ellipsis overflow-hidden whitespace-nowrap" :class="column2Enabled ? '' : 'text-green-600'">
|
|
5
|
+
<h1 v-if="readyState === 1" class="text-ellipsis overflow-hidden whitespace-nowrap" :class="column2Enabled ? '' : 'text-green-600'">
|
|
6
6
|
{{ cValue }}
|
|
7
7
|
</h1>
|
|
8
|
-
<
|
|
8
|
+
<h1 v-else class="text-ellipsis overflow-hidden whitespace-nowrap text-text-300">
|
|
9
|
+
Loading...
|
|
10
|
+
</h1>
|
|
11
|
+
|
|
12
|
+
<div class="flex flex-col" v-if="column2Enabled && readyState === 1">
|
|
9
13
|
<div class="text-sm text-ellipsis whitespace-nowrap overflow-hidden" :class="value?.comparedPercent <= 50 ? 'text-red-600' : 'text-green-600'">{{ value?.comparedPercent }}%</div>
|
|
10
14
|
<div class="text-sm text-ellipsis whitespace-nowrap overflow-hidden">{{ ccValue }}</div>
|
|
11
15
|
</div>
|
|
@@ -15,7 +19,7 @@
|
|
|
15
19
|
|
|
16
20
|
<script>
|
|
17
21
|
|
|
18
|
-
import {
|
|
22
|
+
import {readyStateMixin} from "../../mixin/ready-state";
|
|
19
23
|
|
|
20
24
|
export default{
|
|
21
25
|
|
|
@@ -37,6 +41,8 @@ export default{
|
|
|
37
41
|
|
|
38
42
|
},
|
|
39
43
|
|
|
44
|
+
mixins: [ readyStateMixin ],
|
|
45
|
+
|
|
40
46
|
props: {
|
|
41
47
|
|
|
42
48
|
column: String,
|
|
@@ -52,13 +58,8 @@ export default{
|
|
|
52
58
|
|
|
53
59
|
value: Object,
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
uid: String,
|
|
56
62
|
|
|
57
|
-
setup(){
|
|
58
|
-
const datasource = useDatasource()
|
|
59
|
-
return {
|
|
60
|
-
datasource
|
|
61
|
-
}
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
}
|
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
</div>
|
|
105
105
|
</div>
|
|
106
106
|
|
|
107
|
+
<pre class="text-xs break-all">{{ value.props }}</pre>
|
|
107
108
|
|
|
108
109
|
</div>
|
|
109
110
|
</template>
|
|
@@ -123,7 +124,10 @@ export default{
|
|
|
123
124
|
|
|
124
125
|
return this.selectedDatasource.pivot?.enabled ?
|
|
125
126
|
this.selectedDatasource.pivot.columns :
|
|
126
|
-
|
|
127
|
+
[
|
|
128
|
+
...(this.selectedDatasource.computedColumns ?? []),
|
|
129
|
+
...this.selectedDatasource.columns
|
|
130
|
+
]
|
|
127
131
|
},
|
|
128
132
|
|
|
129
133
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="flex flex-col gap-2">
|
|
2
|
+
<div v-if="readyState === 1" class="flex flex-col gap-2">
|
|
3
3
|
|
|
4
4
|
<Pie class="aspect-square"
|
|
5
5
|
:options="chartOptions"
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
|
+
|
|
14
|
+
<div v-else-if="readyState === 2" class="aspect-square flex items-center justify-center">
|
|
15
|
+
<label class="text-text-300">Loading...</label>
|
|
16
|
+
</div>
|
|
13
17
|
</template>
|
|
14
18
|
|
|
15
19
|
<script>
|
|
@@ -18,6 +22,7 @@ import { Pie } from 'vue-chartjs'
|
|
|
18
22
|
import Chart from 'chart.js/auto'
|
|
19
23
|
import { color } from 'chart.js/helpers'
|
|
20
24
|
import {strVars} from "../../utils/helpers.mjs";
|
|
25
|
+
import {readyStateMixin} from "../../mixin/ready-state";
|
|
21
26
|
|
|
22
27
|
export default{
|
|
23
28
|
|
|
@@ -74,11 +79,6 @@ export default{
|
|
|
74
79
|
|
|
75
80
|
},
|
|
76
81
|
|
|
77
|
-
data(){
|
|
78
|
-
return {
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
|
|
82
82
|
inject: [ 'selectPreset' ],
|
|
83
83
|
|
|
84
84
|
methods: {
|
|
@@ -117,6 +117,8 @@ export default{
|
|
|
117
117
|
|
|
118
118
|
},
|
|
119
119
|
|
|
120
|
+
mixins: [ readyStateMixin ],
|
|
121
|
+
|
|
120
122
|
props: {
|
|
121
123
|
|
|
122
124
|
label: String,
|
|
@@ -127,7 +129,9 @@ export default{
|
|
|
127
129
|
|
|
128
130
|
datasourceUid: String,
|
|
129
131
|
|
|
130
|
-
interactions: Array
|
|
132
|
+
interactions: Array,
|
|
133
|
+
|
|
134
|
+
uid: String
|
|
131
135
|
|
|
132
136
|
}
|
|
133
137
|
|