@mixd-id/web-scaffold 0.1.230406346 → 0.1.230406348

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.230406346",
4
+ "version": "0.1.230406348",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -0,0 +1,256 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <div v-if="apiKey" ref="map" class="flex-1"></div>
4
+ <div v-else class="flex-1 flex items-center justify-center text-text-400">{{ $t('Google maps api required') }}</div>
5
+ </div>
6
+ </template>
7
+
8
+ <script>
9
+
10
+ import { Loader } from '@googlemaps/js-api-loader';
11
+
12
+ export default{
13
+
14
+ name: "GHeatMaps",
15
+
16
+ props: {
17
+ column: String,
18
+
19
+ value: Object,
20
+
21
+ apiKey: {
22
+ type: String,
23
+ default: 'AIzaSyBmzMlmrR5St-njtN--64y_oLTa9FDLYfQ'
24
+ },
25
+ },
26
+
27
+ data(){
28
+ return {
29
+ map: null,
30
+ zoom: 4,
31
+ center: null,
32
+ }
33
+ },
34
+
35
+ mounted() {
36
+ this.load()
37
+ },
38
+
39
+ methods: {
40
+
41
+ load(){
42
+ if(!this.apiKey) return
43
+ if(!Array.isArray(this.datasets) || this.datasets.length < 1)
44
+ return
45
+
46
+ const loader = new Loader({
47
+ apiKey: this.apiKey // "AIzaSyBmzMlmrR5St-njtN--64y_oLTa9FDLYfQ"
48
+ })
49
+
50
+ loader.load()
51
+ .then(async () => {
52
+
53
+ const { Map } = await google.maps.importLibrary([ "maps" ]);
54
+ await google.maps.importLibrary("visualization", ["HeatmapLayer"]);
55
+
56
+ var center = new google.maps.LatLng(
57
+ this.center ? this.center[0] : -6.2088,
58
+ this.center ? this.center[1] : 106.8456);
59
+
60
+ this.map = new Map(this.$refs.map, {
61
+ center: center,
62
+ zoom: this.zoom ?? 4,
63
+ mapTypeId: 'roadmap',
64
+ streetViewControl: false,
65
+ keyboardShortcuts: false,
66
+ styles: [
67
+ { elementType: "geometry", stylers: [{ color: "#242f3e" }] },
68
+ { elementType: "labels.text.stroke", stylers: [{ color: "#242f3e" }] },
69
+ { elementType: "labels.text.fill", stylers: [{ color: "#746855" }] },
70
+ {
71
+ featureType: "administrative.locality",
72
+ elementType: "labels.text.fill",
73
+ stylers: [{ color: "#d59563" }],
74
+ },
75
+ {
76
+ featureType: "poi",
77
+ elementType: "labels.text.fill",
78
+ stylers: [{ color: "#d59563" }],
79
+ },
80
+ {
81
+ featureType: "poi.park",
82
+ elementType: "geometry",
83
+ stylers: [{ color: "#263c3f" }],
84
+ },
85
+ {
86
+ featureType: "poi.park",
87
+ elementType: "labels.text.fill",
88
+ stylers: [{ color: "#6b9a76" }],
89
+ },
90
+ {
91
+ featureType: "road",
92
+ elementType: "geometry",
93
+ stylers: [{ color: "#38414e" }],
94
+ },
95
+ {
96
+ featureType: "road",
97
+ elementType: "geometry.stroke",
98
+ stylers: [{ color: "#212a37" }],
99
+ },
100
+ {
101
+ featureType: "road",
102
+ elementType: "labels.text.fill",
103
+ stylers: [{ color: "#9ca5b3" }],
104
+ },
105
+ {
106
+ featureType: "road.highway",
107
+ elementType: "geometry",
108
+ stylers: [{ color: "#746855" }],
109
+ },
110
+ {
111
+ featureType: "road.highway",
112
+ elementType: "geometry.stroke",
113
+ stylers: [{ color: "#1f2835" }],
114
+ },
115
+ {
116
+ featureType: "road.highway",
117
+ elementType: "labels.text.fill",
118
+ stylers: [{ color: "#f3d19c" }],
119
+ },
120
+ {
121
+ featureType: "transit",
122
+ elementType: "geometry",
123
+ stylers: [{ color: "#2f3948" }],
124
+ },
125
+ {
126
+ featureType: "transit.station",
127
+ elementType: "labels.text.fill",
128
+ stylers: [{ color: "#d59563" }],
129
+ },
130
+ {
131
+ featureType: "water",
132
+ elementType: "geometry",
133
+ stylers: [{ color: "#17263c" }],
134
+ },
135
+ {
136
+ featureType: "water",
137
+ elementType: "labels.text.fill",
138
+ stylers: [{ color: "#515c6d" }],
139
+ },
140
+ {
141
+ featureType: "water",
142
+ elementType: "labels.text.stroke",
143
+ stylers: [{ color: "#17263c" }],
144
+ },
145
+ ]
146
+ });
147
+
148
+ google.maps.event.addListener(this.map, 'zoom_changed', () => {
149
+ this.zoom = this.map.getZoom();
150
+ });
151
+
152
+ google.maps.event.addListener(this.map, 'center_changed', () => {
153
+ this.center = [
154
+ this.map.getCenter().lat(),
155
+ this.map.getCenter().lng()
156
+ ]
157
+ });
158
+
159
+ var heatMapData = [
160
+ /*{location: new google.maps.LatLng(37.782, -122.447), weight: 0.5},
161
+ new google.maps.LatLng(37.782, -122.445),
162
+ {location: new google.maps.LatLng(37.782, -122.443), weight: 2},
163
+ {location: new google.maps.LatLng(37.782, -122.441), weight: 3},
164
+ {location: new google.maps.LatLng(37.782, -122.439), weight: 2},
165
+ new google.maps.LatLng(37.782, -122.437),
166
+ {location: new google.maps.LatLng(37.782, -122.435), weight: 0.5},
167
+
168
+ {location: new google.maps.LatLng(37.785, -122.447), weight: 3},
169
+ {location: new google.maps.LatLng(37.785, -122.445), weight: 2},
170
+ new google.maps.LatLng(37.785, -122.443),
171
+ {location: new google.maps.LatLng(37.785, -122.441), weight: 0.5},
172
+ new google.maps.LatLng(37.785, -122.439),
173
+ {location: new google.maps.LatLng(37.785, -122.437), weight: 2},
174
+ {location: new google.maps.LatLng(37.785, -122.435), weight: 3}*/
175
+ ];
176
+
177
+ this.datasets.forEach((item) => {
178
+ if(item[0] && item[1] && item[2]){
179
+ heatMapData.push({
180
+ location: new google.maps.LatLng(item[0], item[1]),
181
+ weight: item[2]
182
+ })
183
+ }
184
+ })
185
+
186
+ var heatmap = new google.maps.visualization.HeatmapLayer({
187
+ data: heatMapData,
188
+ dissipating: true
189
+ });
190
+ heatmap.set('radius', parseInt(this.mapRadius ?? 12))
191
+ heatmap.setMap(this.map);
192
+
193
+ const gradient = [
194
+ "rgba(0, 255, 255, 0)",
195
+ "rgba(0, 255, 255, 1)",
196
+ "rgba(0, 191, 255, 1)",
197
+ "rgba(0, 127, 255, 1)",
198
+ "rgba(0, 63, 255, 1)",
199
+ "rgba(0, 0, 255, 1)",
200
+ "rgba(0, 0, 223, 1)",
201
+ "rgba(0, 0, 191, 1)",
202
+ "rgba(0, 0, 159, 1)",
203
+ "rgba(0, 0, 127, 1)",
204
+ "rgba(63, 0, 91, 1)",
205
+ "rgba(127, 0, 63, 1)",
206
+ "rgba(191, 0, 31, 1)",
207
+ "rgba(255, 0, 0, 1)",
208
+ ];
209
+ heatmap.set("gradient", gradient);
210
+
211
+ //console.log('Gmap, data count:', this.data.length)
212
+ });
213
+ }
214
+
215
+ },
216
+
217
+ computed: {
218
+
219
+ datasets(){
220
+ if(!Array.isArray(this.value?.items)) return []
221
+
222
+ const grouped = this.value.items.reduce((acc, item) => {
223
+ if(!acc[item[this.column]]) acc[item[this.column]] = 0
224
+ acc[item[this.column]] += 1
225
+ return acc
226
+ }, {})
227
+
228
+ const datasets = []
229
+ for(let coord in grouped){
230
+ datasets.push([parseFloat(coord.split(',')[0]), parseFloat(coord.split(',')[1]), grouped[coord]])
231
+ }
232
+
233
+ return datasets
234
+ }
235
+
236
+ },
237
+
238
+ watch: {
239
+
240
+ datasets(){
241
+ this.load()
242
+ }
243
+
244
+ }
245
+
246
+ }
247
+
248
+ </script>
249
+
250
+ <style module>
251
+
252
+ .comp{
253
+ @apply flex flex-col h-[40vh] bg-base-500;
254
+ }
255
+
256
+ </style>
@@ -464,7 +464,6 @@ export default{
464
464
  columns: [
465
465
  { key:attr, visible:true }
466
466
  ],
467
- itemsPerPage: 1000,
468
467
  filters: [
469
468
  {
470
469
  key:key, value: [ { operator:'in', value:reqItems } ]
@@ -573,8 +573,8 @@ export default{
573
573
  enumText = typeParam && typeParam.text ? typeParam.text : enumText
574
574
  }
575
575
 
576
- if(this.enumCache && this.enumCache[column.key] && this.enumCache[column.key][value]){
577
- enumText = this.enumCache[column.key][value].text ?? enumText
576
+ else if(this.enumCache && this.enumCache[column.key] && this.enumCache[column.key][value?.toString()]){
577
+ enumText = this.enumCache[column.key][value?.toString()].text ?? enumText
578
578
  }
579
579
 
580
580
  text = enumText ? enumText : text
@@ -0,0 +1,9 @@
1
+ export const component = {
2
+
3
+ type:"GHeatMaps",
4
+
5
+ props:{
6
+
7
+ }
8
+
9
+ }
package/src/index.js CHANGED
@@ -336,8 +336,6 @@ export default{
336
336
  app.directive('tooltip', (el, binding) => {
337
337
  if(!binding.value) return
338
338
 
339
- console.log(binding)
340
-
341
339
  if(!el.getAttribute('data-tooltip')) {
342
340
 
343
341
  const uid = uniqid()
@@ -528,6 +526,7 @@ export default{
528
526
  app.component('ErrorText', defineAsyncComponent(() => import("./components/ErrorText.vue")))
529
527
  app.component('Feed', defineAsyncComponent(() => import("./components/Feed.vue")))
530
528
  app.component('Gmaps', defineAsyncComponent(() => import("./components/Gmaps.vue")))
529
+ app.component('GHeatMaps', defineAsyncComponent(() => import("./components/GHeatMaps.vue")))
531
530
  app.component('HTMLEditor', defineAsyncComponent(() => import("./components/HTMLEditor.vue")))
532
531
  app.component('Switch', defineAsyncComponent(() => import("./components/Switch.vue")))
533
532
  app.component('IconMenu', defineAsyncComponent(() => import("./components/IconMenu.vue")))
@@ -45,15 +45,23 @@ const backgroundColors = [
45
45
  ]
46
46
 
47
47
  const getModelFromDatasource = async (datasource, opt) => {
48
- if(!opt.conn.models[datasource.datasourceUid]){
49
- const tableColumns = await getSequelizeColumns(datasource.columns, opt)
50
48
 
51
- opt.conn.define(datasource.datasourceUid, tableColumns, {
52
- tableName: `datasource_${datasource.datasourceUid}`
53
- })
54
- }
49
+ switch(datasource.type){
50
+
51
+ case 2:
52
+ return opt.conn.models[datasource.key]
53
+
54
+ default:
55
+ if(!opt.conn.models[datasource.datasourceUid]){
56
+ const tableColumns = await getSequelizeColumns(datasource.columns, opt)
55
57
 
56
- return opt.conn.models[datasource.datasourceUid]
58
+ opt.conn.define(datasource.datasourceUid, tableColumns, {
59
+ tableName: `datasource_${datasource.datasourceUid}`
60
+ })
61
+ }
62
+
63
+ return opt.conn.models[datasource.datasourceUid]
64
+ }
57
65
  }
58
66
 
59
67
  const getDatasourceItems = async (datasource, opt) => {
@@ -524,8 +524,16 @@ const dayTimeRange = (params, value) => {
524
524
  })
525
525
  }
526
526
 
527
+ function capitalize(str) {
528
+ return (str ?? '')
529
+ .toString()
530
+ .split(' ')
531
+ .map(_ => _.charAt(0).toUpperCase() + _.slice(1).toLowerCase())
532
+ .join(' ')
533
+ }
527
534
 
528
535
  module.exports = {
536
+ capitalize,
529
537
  ceil,
530
538
  floor,
531
539
  ftWildcard,
@@ -1270,9 +1270,11 @@ const presetToSequelizeList = async(preset, {
1270
1270
  order:initialOrder
1271
1271
  }) => {
1272
1272
 
1273
+ const updatedAtField = model.rawAttributes['updatedAt'] ?? model.rawAttributes['updated_at']
1274
+
1273
1275
  if(!initialOrder){
1274
1276
  initialOrder = [
1275
- [ 'updatedAt', 'desc' ],
1277
+ [ updatedAtField.fieldName, 'desc' ],
1276
1278
  [ 'id', 'desc' ],
1277
1279
  ]
1278
1280
  }
@@ -1381,7 +1383,8 @@ const presetToSequelizeList = async(preset, {
1381
1383
  ...replacements,
1382
1384
  ...filterReplacements,
1383
1385
  ...searchReplacements
1384
- ]
1386
+ ],
1387
+ itemsPerPage
1385
1388
  }
1386
1389
  }
1387
1390
  }
@@ -1,20 +1,67 @@
1
1
  <template>
2
- <div :class="$style.comp" class="flex flex-col gap-3">
2
+ <div :class="$style.comp">
3
3
 
4
- <label class="text-text-400 text-ellipsis overflow-hidden whitespace-nowrap">{{ label }}</label>
4
+ <div v-if="readyState === 2" class="flex-1 flex">
5
+ <div :style="barStyles" class="flex-1 flex items-center justify-center">
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>
8
+ </div>
5
9
 
6
- <div class="flex-1">
7
- <Bar :style="barStyles"
8
- :options="chartOptions"
9
- :data="chartData"/>
10
+ <div v-else-if="isError" class="flex-1 flex">
11
+ <div :style="barStyles" class="flex-1 flex items-center justify-center">
12
+ <p class="text-text-300">{{ value.message }}</p>
13
+ </div>
10
14
  </div>
11
15
 
12
- <div v-if="yAxeMultiple" class="flex flex-row justify-center gap-1">
13
- <div v-for="(yLegend, idx) in yLegends"
14
- class="p-0.5 px-1 rounded-lg text-black cursor-default text-xs w-[50px] text-center text-ellipsis overflow-hidden whitespace-nowrap capitalize"
15
- :style="{ backgroundColor:yLegend.color }">
16
- {{ (yLegend.key ?? '').toString().split(' ')[0].toLowerCase() }}
16
+ <div v-else class="flex flex-col gap-3">
17
+ <div class="flex flex-row items-center gap-4">
18
+ <label class="text-text-400 text-ellipsis overflow-hidden whitespace-nowrap flex-1">{{ label }}</label>
19
+ <div v-if="yAxeMultiple && yLegends?.length > 0" class="flex flex-row items-center flex-wrap justify-center gap-1">
20
+ <div v-for="yLegend in showedYLegends"
21
+ v-tooltip="`${yLegend.key}`"
22
+ class="p-0.5 px-1 rounded-full text-black cursor-default text-xs min-w-[50px] max-w-[60px] text-center text-ellipsis overflow-hidden whitespace-nowrap capitalize"
23
+ :style="{ backgroundColor:yLegend.color }">
24
+ {{ (yLegend.key ?? '').toString().split(' ')[0].toLowerCase() }}
25
+ </div>
26
+ <button v-if="yLegends.length > showedYLegends.length" @click="$refs.legendModal.open()"
27
+ class="bg-text-200 hover:bg-primary-600 w-[21px] h-[21px] rounded-full flex items-center justify-center">
28
+ <svg width="14" height="14" class="fill-white opacity-70" 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="M64 192C28.61 192 0 220.6 0 256s28.61 64 64 64s64-28.62 64-64S99.39 192 64 192zM256 192C220.6 192 192 220.6 192 256s28.61 64 64 64s64-28.62 64-64S291.4 192 256 192zM448 192c-35.39 0-64 28.62-64 64s28.61 64 64 64s64-28.62 64-64S483.4 192 448 192z"/></svg>
29
+ </button>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="flex-1">
34
+ <Bar :style="barStyles"
35
+ :options="chartOptions"
36
+ :data="chartData"/>
17
37
  </div>
38
+
39
+ <Modal ref="legendModal" width="320" height="360" :dismissable="true" @dismiss="$refs.legendModal.close()">
40
+ <template v-slot:head>
41
+ <div class="relative p-5">
42
+ <h3>Legend</h3>
43
+ <div class="absolute top-0 right-0 p-2">
44
+ <button type="button" class="p-2" @click="$refs.legendModal.close()">
45
+ <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">
46
+ <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"/>
47
+ </svg>
48
+ </button>
49
+ </div>
50
+ </div>
51
+ </template>
52
+ <div class="flex-1 p-5 pt-0">
53
+
54
+ <div class="flex flex-col divide-y divide-text-50">
55
+ <div v-for="yLegend in yLegends" class="flex flex-row items-center gap-2 py-2">
56
+ <div class="w-[24px] h-[24px] rounded-full" :style="{ backgroundColor:yLegend.color }"></div>
57
+ <div class="flex-1 text-ellipsis whitespace-nowrap overflow-hidden">{{ yLegend.key }}</div>
58
+ </div>
59
+ </div>
60
+
61
+ <br />
62
+
63
+ </div>
64
+ </Modal>
18
65
  </div>
19
66
 
20
67
  </div>
@@ -25,7 +72,7 @@
25
72
  import {Bar} from 'vue-chartjs'
26
73
  import Chart from 'chart.js/auto'
27
74
  import { color } from 'chart.js/helpers'
28
- import {useDatasource} from "../../stores/datasource";
75
+ import {strVars} from "../../utils/helpers.mjs";
29
76
 
30
77
  export default{
31
78
 
@@ -51,7 +98,7 @@ export default{
51
98
  datasets: this.value.datasets.map(_ => {
52
99
  return {
53
100
  ..._,
54
- borderWidth: 1,
101
+ borderWidth: 0,
55
102
  borderColor: function(context, options) {
56
103
  const hex = options.color;
57
104
  return color(hex).darken(0.5).rgbString()
@@ -76,7 +123,7 @@ export default{
76
123
  return `${tooltipItems[0].label}`;
77
124
  },
78
125
  label: (tooltipItem) => {
79
- if(this.usePercentage)
126
+ if(this.yAxeMultiple && this.usePercentage)
80
127
  return `${tooltipItem.dataset.label}: ${tooltipItem.dataset.data0[tooltipItem.dataIndex]} (${tooltipItem.raw}%)`
81
128
  return `${tooltipItem.dataset.label}: ${tooltipItem.raw}`;
82
129
  }
@@ -94,10 +141,13 @@ export default{
94
141
  ticks: {
95
142
  callback: function(value) {
96
143
  const label = this.getLabelForValue(value) ?? '';
97
- return label.length > 10 ? label.slice(0, 10) + '...' : label;
144
+ return label.length > 10 ? label.slice(0, 30) + '...' : label;
98
145
  },
99
146
  minRotation: 0,
100
- maxRotation: 0
147
+ maxRotation: 0,
148
+ font: {
149
+ size: 11
150
+ }
101
151
  },
102
152
  stacked: !!this.stacked,
103
153
  },
@@ -105,6 +155,9 @@ export default{
105
155
  beginAtZero: true,
106
156
  ticks: {
107
157
  display: !this.yAxeMultiple || this.usePercentage,
158
+ font: {
159
+ size: 11,
160
+ },
108
161
  },
109
162
  grid: {
110
163
  display: true,
@@ -112,25 +165,24 @@ export default{
112
165
  return `rgba(255,255,255, .1)`
113
166
  }
114
167
  },
115
- stacked: !!this.stacked,
168
+ stacked: !!this.stacked
116
169
  }
117
170
  },
118
- onClick: function(evt, evt2) {
119
- console.log(evt);
120
- console.log(evt2);
121
- }
171
+ onClick: this.onClick
122
172
  }
123
173
  },
124
174
 
125
- cValue(){
126
- return this.datasourceUid && this.datasource ?
127
- this.datasource.keys[this.datasourceUid] :
128
- this.value
175
+ isError(){
176
+ return this.value?.error === 1
129
177
  },
130
178
 
131
179
  yLegends(){
132
180
  return this.value?.yLegends ?? []
133
- }
181
+ },
182
+
183
+ showedYLegends(){
184
+ return this.yLegends.slice(0, 5)
185
+ },
134
186
 
135
187
  },
136
188
 
@@ -150,9 +202,57 @@ export default{
150
202
  ],
151
203
 
152
204
  datasets: null,
205
+
206
+ readyState: 1,
153
207
  }
154
208
  },
155
209
 
210
+ inject: [ 'selectPreset' ],
211
+
212
+ methods: {
213
+
214
+ onClick(e, segments){
215
+
216
+ const clickInteractions = (this.interactions ?? []).filter(_ => _.event === 'click')
217
+ const segment = segments[0]
218
+ if(!segment) return
219
+
220
+ const dataset = this.value.datasets[segment.datasetIndex]
221
+ const obj = {
222
+ segment: this.value.labels[segment.index],
223
+ key: dataset.label,
224
+ value: dataset.data[segment.index]
225
+ }
226
+
227
+ for(let click of clickInteractions){
228
+ const { action, presetUid, filters } = click
229
+
230
+ const params = filters.reduce((res, cur) => {
231
+ res[cur.datasourceUid + '.filters.' + cur.key + '.' + cur.operator] = strVars(cur.value, obj)
232
+ return res
233
+ }, {})
234
+
235
+ switch(action){
236
+
237
+ case 'openDashboardPreset':
238
+ if(typeof this.selectPreset === 'function')
239
+ this.selectPreset(presetUid, params)
240
+ break
241
+ }
242
+ }
243
+
244
+ },
245
+
246
+ resetState(){
247
+ this.setState(1)
248
+ },
249
+
250
+ setState(state){
251
+ this.readyState = state
252
+ },
253
+
254
+ },
255
+
156
256
  props: {
157
257
 
158
258
  datasourceUid: String,
@@ -177,15 +277,10 @@ export default{
177
277
 
178
278
  yAxeOnClick: Array,
179
279
 
180
- value: Object
280
+ value: Object,
181
281
 
182
- },
282
+ interactions: Array
183
283
 
184
- setup(){
185
- const datasource = useDatasource()
186
- return {
187
- datasource
188
- }
189
284
  },
190
285
 
191
286
  }
@@ -196,7 +291,7 @@ export default{
196
291
 
197
292
  .comp{
198
293
  @apply border-[1px] border-text-50 bg-base-500 rounded-lg;
199
- @apply p-3;
294
+ @apply p-3 flex flex-col;
200
295
  }
201
296
 
202
297
  </style>