@mixd-id/web-scaffold 0.1.230406341 → 0.1.230406343

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 (46) hide show
  1. package/package.json +2 -1
  2. package/public/assets/dashboard/bar.png +0 -0
  3. package/public/assets/dashboard/doughnut.png +0 -0
  4. package/public/assets/dashboard/metric.png +0 -0
  5. package/public/assets/dashboard/pie.png +0 -0
  6. package/public/assets/dashboard/polar-area.png +0 -0
  7. package/public/assets/dashboard/virtual-table.png +0 -0
  8. package/public/static/dashboard/bar.png +0 -0
  9. package/public/static/dashboard/doughnut.png +0 -0
  10. package/public/static/dashboard/metric.png +0 -0
  11. package/public/static/dashboard/pie.png +0 -0
  12. package/public/static/dashboard/polar-area.png +0 -0
  13. package/public/static/dashboard/virtual-table.png +0 -0
  14. package/src/components/Grid.vue +2 -0
  15. package/src/components/PresetSelectorFilterItem.vue +15 -2
  16. package/src/components/VirtualTable.vue +5 -1
  17. package/src/configs/dashboard/bar.js +9 -0
  18. package/src/configs/dashboard/collection-1.js +5 -0
  19. package/src/configs/dashboard/doughnut.js +7 -0
  20. package/src/configs/dashboard/grid-2.js +32 -0
  21. package/src/configs/dashboard/grid-3.js +32 -0
  22. package/src/configs/dashboard/grid-4.js +32 -0
  23. package/src/configs/dashboard/grid.js +13 -0
  24. package/src/configs/dashboard/metric.js +10 -0
  25. package/src/configs/dashboard/pie.js +7 -0
  26. package/src/configs/dashboard/polar-area.js +7 -0
  27. package/src/configs/dashboard/virtual-table.js +9 -0
  28. package/src/utils/dashboard.js +100 -0
  29. package/src/widgets/Dashboard/BarChart.vue +7 -6
  30. package/src/widgets/Dashboard/BarChartSetting.vue +38 -33
  31. package/src/widgets/Dashboard/DatasourcePreview.vue +83 -0
  32. package/src/widgets/Dashboard/DatasourceSelector.vue +19 -5
  33. package/src/widgets/Dashboard/Doughnut.vue +1 -0
  34. package/src/widgets/Dashboard/DoughnutSetting.vue +30 -9
  35. package/src/widgets/Dashboard/InteractionEdit.vue +194 -0
  36. package/src/widgets/Dashboard/Metric.vue +11 -1
  37. package/src/widgets/Dashboard/MetricSetting.vue +55 -8
  38. package/src/widgets/Dashboard/Pie.vue +32 -1
  39. package/src/widgets/Dashboard/PieSetting.vue +127 -19
  40. package/src/widgets/Dashboard/PolarArea.vue +1 -0
  41. package/src/widgets/Dashboard/PolarAreaSetting.vue +30 -9
  42. package/src/widgets/Dashboard/SharingModal.vue +12 -9
  43. package/src/widgets/Dashboard/ViewSelector.vue +104 -36
  44. package/src/widgets/Dashboard/VirtualTableSetting.vue +71 -39
  45. package/src/widgets/Dashboard.vue +281 -159
  46. package/src/widgets/WebPageBuilder4/TreeViewItem.vue +0 -3
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.230406341",
4
+ "version": "0.1.230406343",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -26,6 +26,7 @@
26
26
  },
27
27
  "./importer": "./src/utils/importer.js",
28
28
  "./listpage1": "./src/utils/listpage1.js",
29
+ "./dashboard": "./src/utils/dashboard.js",
29
30
  "./listview": "./src/utils/listview.js",
30
31
  "./preset-selector": {
31
32
  "require": "./src/utils/preset-selector.js",
Binary file
Binary file
Binary file
Binary file
@@ -17,6 +17,8 @@ export default{
17
17
 
18
18
  mixins: [ componentMixin ],
19
19
 
20
+ name: "Grid",
21
+
20
22
  props:{
21
23
  items: Array
22
24
  }
@@ -5,6 +5,7 @@
5
5
  <div v-if="type === 'date'" class="flex-1 flex flex-row gap-2">
6
6
  <div class="flex-1 flex flex-row gap-2">
7
7
  <Dropdown v-model="value.operator"
8
+ :readonly="readonly"
8
9
  :class="![ 'yesterday', 'today', 'thisWeek', 'thisMonth', 'lastMonth', 'thisYear' ].includes(value.operator) ? 'w-[100px]' : 'w-full'"
9
10
  @change="apply">
10
11
  <option value="=">=</option>
@@ -24,10 +25,12 @@
24
25
  class="flex-1 flex flex-row gap-2">
25
26
  <Datepicker class="flex-1"
26
27
  mode="popup"
28
+ :readonly="readonly"
27
29
  v-model="value.value"
28
30
  @change="apply" />
29
31
  <Datepicker v-if="value.operator === 'between'"
30
32
  class="flex-1"
33
+ :readonly="readonly"
31
34
  mode="popup"
32
35
  v-model="value.value2"
33
36
  @change="apply" />
@@ -38,6 +41,7 @@
38
41
  <div v-else-if="type === 'number'" class="flex flex-row gap-2">
39
42
  <Dropdown v-model="value.operator"
40
43
  class="w-[100px]"
44
+ :readonly="readonly"
41
45
  @change="apply">
42
46
  <option value="=">=</option>
43
47
  <option value=">">&gt;</option>
@@ -49,13 +53,16 @@
49
53
  </Dropdown>
50
54
  <Textbox v-model="value.value"
51
55
  class="flex-1"
56
+ :readonly="readonly"
52
57
  @keyup.enter="apply"
53
58
  @blur="apply" />
54
59
  </div>
55
60
 
56
61
  <div v-else-if="type === 'boolean'" class="flex flex-row gap-2">
57
- <Radio :name="value.key" :value="true" v-model="value.value" @change="apply">True</Radio>
58
- <Radio :name="value.key" :value="false" v-model="value.value" @change="apply">False</Radio>
62
+ <Radio :name="value.key"
63
+ :readonly="readonly" :value="true" v-model="value.value" @change="apply">True</Radio>
64
+ <Radio :name="value.key"
65
+ :readonly="readonly" :value="false" v-model="value.value" @change="apply">False</Radio>
59
66
  </div>
60
67
 
61
68
  <div v-else-if="type === 'enum' && Array.isArray(cTypeParams) && cTypeParams.length > 0"
@@ -64,6 +71,7 @@
64
71
  <Checkbox v-for="param in cTypeParams"
65
72
  v-model="cValue.value"
66
73
  class="flex-1"
74
+ :readonly="readonly"
67
75
  :value="param.value"
68
76
  @change="apply">
69
77
  {{ param.text }}
@@ -74,11 +82,13 @@
74
82
  <div v-else-if="type === 'component'">
75
83
  <component :is="column.component"
76
84
  :value="value"
85
+ :readonly="readonly"
77
86
  @change="apply" />
78
87
  </div>
79
88
 
80
89
  <div v-else class="flex flex-row gap-2">
81
90
  <Dropdown v-model="value.operator" class="w-[100px]"
91
+ :readonly="readonly"
82
92
  @change="apply">
83
93
  <option value="eq">Equal</option>
84
94
  <option value="not">Not Equal</option>
@@ -91,6 +101,7 @@
91
101
  <option value="regex">Regex</option>
92
102
  </Dropdown>
93
103
  <Textbox v-model="value.value"
104
+ :readonly="readonly"
94
105
  class="flex-1"
95
106
  @keyup.enter="apply"
96
107
  @blur="apply" />
@@ -120,6 +131,8 @@ export default{
120
131
 
121
132
  value: Object,
122
133
 
134
+ readonly: [ Boolean, Number ],
135
+
123
136
  enumCache: Object,
124
137
 
125
138
  },
@@ -103,7 +103,7 @@ export default{
103
103
  }
104
104
  },
105
105
 
106
- inject: [ 'listStyle' ],
106
+ inject: [ 'emitRoot', 'listStyle' ],
107
107
 
108
108
  emits: [ 'scroll-end', 'item-click' ],
109
109
 
@@ -114,6 +114,8 @@ export default{
114
114
 
115
115
  itemClass: String,
116
116
 
117
+ uid: String,
118
+
117
119
  items: Array,
118
120
 
119
121
  pinned: Function,
@@ -314,6 +316,8 @@ export default{
314
316
  if(this.scrollTop > this.$refs.scroller.offsetHeight - this.$refs.cont.clientHeight - this.itemHeight){
315
317
  if(!this.isOnEndScroll){
316
318
  this.$emit('scroll-end')
319
+ if(typeof this.emitRoot === 'function')
320
+ this.emitRoot.apply(this, [ 'scroll-end', this.$props ])
317
321
  this.isOnEndScroll = true
318
322
  }
319
323
  }
@@ -0,0 +1,9 @@
1
+ export const component = {
2
+
3
+ type:"BarChart",
4
+
5
+ props:{
6
+ height:200
7
+ }
8
+
9
+ }
@@ -0,0 +1,5 @@
1
+ export const component = {
2
+
3
+ props: {}
4
+
5
+ }
@@ -0,0 +1,7 @@
1
+ export const component = {
2
+
3
+ type:"Doughnut",
4
+
5
+ props:{}
6
+
7
+ }
@@ -0,0 +1,32 @@
1
+ export const component = {
2
+
3
+ type:'Grid',
4
+
5
+ isContainer:true,
6
+
7
+ props:{
8
+
9
+ columns:[
10
+ 'grid-cols-1',
11
+ 'md:grid-cols-2',
12
+ '',
13
+ ''
14
+ ],
15
+
16
+ gap:[
17
+ 'gap-5',
18
+ 'md:gap-5',
19
+ '',
20
+ ''
21
+ ],
22
+
23
+ alignItems:[
24
+ 'items-start',
25
+ 'md:items-start',
26
+ '',
27
+ ''
28
+ ],
29
+
30
+ }
31
+
32
+ }
@@ -0,0 +1,32 @@
1
+ export const component = {
2
+
3
+ type:'Grid',
4
+
5
+ isContainer:true,
6
+
7
+ props:{
8
+
9
+ columns:[
10
+ 'grid-cols-1',
11
+ 'md:grid-cols-3',
12
+ '',
13
+ ''
14
+ ],
15
+
16
+ gap:[
17
+ 'gap-5',
18
+ 'md:gap-5',
19
+ '',
20
+ ''
21
+ ],
22
+
23
+ alignItems:[
24
+ 'items-start',
25
+ 'md:items-start',
26
+ '',
27
+ ''
28
+ ],
29
+
30
+ }
31
+
32
+ }
@@ -0,0 +1,32 @@
1
+ export const component = {
2
+
3
+ type:'Grid',
4
+
5
+ isContainer:true,
6
+
7
+ props:{
8
+
9
+ columns:[
10
+ 'grid-cols-2',
11
+ 'md:grid-cols-4',
12
+ '',
13
+ ''
14
+ ],
15
+
16
+ gap:[
17
+ 'gap-5',
18
+ 'md:gap-5',
19
+ '',
20
+ ''
21
+ ],
22
+
23
+ alignItems:[
24
+ 'items-start',
25
+ 'md:items-start',
26
+ '',
27
+ ''
28
+ ],
29
+
30
+ }
31
+
32
+ }
@@ -0,0 +1,13 @@
1
+ export const component = {
2
+
3
+ type:'Grid',
4
+
5
+ isContainer:true,
6
+
7
+ props:{
8
+ columns:['grid-cols-2', 'md:grid-cols-5', '', ''],
9
+ gap:['gap-5', 'md:gap-5', '', ''],
10
+ alignItems:['items-start', 'md:items-start', '', ''],
11
+ }
12
+
13
+ }
@@ -0,0 +1,10 @@
1
+ export const component = {
2
+
3
+ type:"Metric",
4
+
5
+ props:{
6
+ columnModifier:"sum",
7
+ column2Modifier:"sum"
8
+ }
9
+
10
+ }
@@ -0,0 +1,7 @@
1
+ export const component = {
2
+
3
+ type:"Pie",
4
+
5
+ props:{}
6
+
7
+ }
@@ -0,0 +1,7 @@
1
+ export const component = {
2
+
3
+ type:"PolarArea",
4
+
5
+ props:{}
6
+
7
+ }
@@ -0,0 +1,9 @@
1
+ export const component = {
2
+
3
+ type:"VirtualTable",
4
+
5
+ props:{
6
+ height:[ "h-[50vh]", "md:h-[50vh]", "", "" ]
7
+ }
8
+
9
+ }
@@ -0,0 +1,100 @@
1
+ const {presetToSequelizeList} = require("./preset-selector");
2
+
3
+ const backgroundColors = [
4
+ '#5D9CEC',
5
+ '#A0D468',
6
+ '#FFCE54',
7
+ '#FC6E51',
8
+ '#48CFAD',
9
+ '#AC92EC',
10
+ '#4FC1E9',
11
+ '#FFCE54',
12
+ '#ED5565',
13
+ '#EC87C0'
14
+ ]
15
+
16
+ const getModelFromDatasource = async (datasource, opt) => {
17
+ if(!opt.conn.models[datasource.datasourceUid]){
18
+ const tableColumns = await getSequelizeColumns(datasource.columns, opt)
19
+
20
+ opt.conn.define(datasource.datasourceUid, tableColumns, {
21
+ tableName: `datasource_${datasource.datasourceUid}`
22
+ })
23
+ }
24
+
25
+ return opt.conn.models[datasource.datasourceUid]
26
+ }
27
+
28
+ const getDatasourceItems = async (datasource, opt) => {
29
+
30
+ const Model = await getModelFromDatasource(datasource, opt)
31
+ const config = {
32
+ columns: datasource.columns
33
+ }
34
+ const findOpt = await presetToSequelizeList(datasource, {
35
+ config,
36
+ model: Model,
37
+ conn: opt.conn,
38
+ limit: 100
39
+ })
40
+
41
+ return await Model.findAll({
42
+ ...findOpt,
43
+ raw: true
44
+ })
45
+ }
46
+
47
+ const getSequelizeColumns = async (columns, opt) => {
48
+
49
+ const { DataTypes } = opt.Sequelize
50
+
51
+ const tableColumns = {
52
+ id: {
53
+ type: DataTypes.INTEGER,
54
+ autoIncrement: true,
55
+ primaryKey: true,
56
+ allowNull: false,
57
+ },
58
+ createdAt: { type: DataTypes.DATE },
59
+ updatedAt: { type: DataTypes.DATE },
60
+ }
61
+
62
+ for(let column of columns){
63
+
64
+ let type
65
+ switch(column.type){
66
+ case 'date':
67
+ type = DataTypes.DATE
68
+ break
69
+ case 'number':
70
+ type = DataTypes.BIGINT
71
+ break
72
+
73
+ default:
74
+ type = DataTypes.STRING(column.maxLength ?? 40)
75
+ break
76
+ }
77
+
78
+ tableColumns[column.key] = {
79
+ type
80
+ }
81
+ }
82
+
83
+ return tableColumns
84
+ }
85
+
86
+
87
+ module.exports = {
88
+ getModelFromDatasource,
89
+ getDatasourceItems,
90
+ getSequelizeColumns,
91
+
92
+ backgroundColors,
93
+
94
+ /*loadBarChart,
95
+ loadMetric,
96
+ loadDoughnut,
97
+ loadPie,
98
+ loadPolarArea,
99
+ loadVirtualTable*/
100
+ }
@@ -49,6 +49,7 @@ export default{
49
49
  return {
50
50
  responsive: true,
51
51
  maintainAspectRatio: false,
52
+ borderRadius: 4,
52
53
  plugins: {
53
54
  legend: {
54
55
  display: false // This hides the legend
@@ -69,7 +70,8 @@ export default{
69
70
  },
70
71
  minRotation: 0,
71
72
  maxRotation: 0
72
- }
73
+ },
74
+ stacked: !!this.stacked,
73
75
  },
74
76
  y: {
75
77
  beginAtZero: true,
@@ -82,6 +84,7 @@ export default{
82
84
  return `rgba(255,255,255, .1)`
83
85
  }
84
86
  },
87
+ stacked: !!this.stacked,
85
88
  }
86
89
  },
87
90
  onClick: function(evt, evt2) {
@@ -98,7 +101,7 @@ export default{
98
101
  },
99
102
 
100
103
  yLegends(){
101
- return this.value.yLegends ?? []
104
+ return this.value?.yLegends ?? []
102
105
  }
103
106
 
104
107
  },
@@ -126,10 +129,8 @@ export default{
126
129
 
127
130
  datasourceUid: String,
128
131
 
129
- usePercentage: {
130
- type: Number,
131
- default: false
132
- },
132
+ usePercentage: [ Boolean, Number ],
133
+ stacked: [ Boolean, Number ],
133
134
 
134
135
  barHeight: {
135
136
  type: Number,
@@ -1,19 +1,21 @@
1
1
  <template>
2
2
  <div class="flex flex-col gap-5 p-6">
3
3
 
4
- <div class="flex flex-row items-center">
5
- <label class="flex-1">Datasource</label>
6
- <div>
7
- <Dropdown class="w-[120px]"
8
- :readonly="readonly"
9
- v-model="value.props.datasourceUid"
10
- @change="delete value.props.columns">
11
- <option v-for="obj in datasource"
12
- :value="obj.uid">
13
- {{ obj.name }}
14
- </option>
15
- </Dropdown>
4
+ <div class="flex flex-col gap-1">
5
+ <div class="flex flex-row gap-2">
6
+ <label class="flex-1">Datasource</label>
7
+ <button type="button" class="text-primary"
8
+ @click="previewDatasource(selectedDatasource)">Preview</button>
16
9
  </div>
10
+ <Dropdown class="min-w-[150px]"
11
+ :readonly="readonly"
12
+ v-model="value.props.datasourceUid"
13
+ @change="delete value.props.columns">
14
+ <option v-for="obj in datasource"
15
+ :value="obj.uid">
16
+ {{ obj.name }}
17
+ </option>
18
+ </Dropdown>
17
19
  </div>
18
20
 
19
21
  <div class="flex flex-col gap-1">
@@ -28,9 +30,9 @@
28
30
  <div class="flex-1">
29
31
  <label class="text-primary cursor-pointer"
30
32
  ref="xAxis"
31
- @click="$refs.context1.open($refs.xAxis)">
33
+ @click="!readonly ? $refs.context1.open($refs.xAxis) : null">
32
34
  {{ value.props.xAxeMultiple ? 'X Axes' : 'X Axis' }}
33
- <svg class="fill-primary inline relative top-[-1px]" width="12" height="12" 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 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"/></svg>
35
+ <svg v-if="!readonly" class="fill-primary inline relative top-[-1px]" width="12" height="12" 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 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"/></svg>
34
36
  </label>
35
37
  <ContextMenu ref="context1">
36
38
  <div class="flex flex-col min-w-[100px]">
@@ -55,14 +57,14 @@
55
57
  @reorder="(from, to) => { cXAxes.splice(to, 0, cXAxes.splice(from, 1)[0]); }">
56
58
  <template v-slot="{ item, index }">
57
59
  <div class="flex flex-row items-center gap-2">
58
- <div data-reorder v-if="cXAxes.length > 1">
60
+ <div data-reorder v-if="cXAxes.length > 1 && !readonly">
59
61
  <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>
60
62
  </div>
61
63
  <div class="flex-1">
62
64
  <Dropdown v-model="item.key" :readonly="readonly">
63
- <option v-for="column in selectedDatasource?.columns"
65
+ <option v-for="column in selectedDatasourceColumns"
64
66
  :value="column.key">
65
- {{ column.label }}
67
+ {{ selectedDatasource.pivot?.enabled ? column.key : column.label }}
66
68
  </option>
67
69
  </Dropdown>
68
70
  </div>
@@ -79,9 +81,9 @@
79
81
  <div class="flex-1">
80
82
  <label class="text-primary cursor-pointer"
81
83
  ref="yAxis"
82
- @click="$refs.context2.open($refs.yAxis)">
84
+ @click="!readonly ? $refs.context2.open($refs.yAxis) : null">
83
85
  {{ value.props.yAxeMultiple ? 'Y Axes' : 'Y Axis' }}
84
- <svg class="fill-primary inline relative top-[-1px]" width="12" height="12" 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 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"/></svg>
86
+ <svg v-if="!readonly" class="fill-primary inline relative top-[-1px]" width="12" height="12" 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 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z"/></svg>
85
87
  </label>
86
88
  <ContextMenu ref="context2">
87
89
  <div class="flex flex-col min-w-[100px]">
@@ -110,10 +112,10 @@
110
112
  <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>
111
113
  </div>
112
114
  <div class="flex-1">
113
- <Dropdown v-model="item.key">
114
- <option v-for="column in selectedDatasource?.columns"
115
+ <Dropdown v-model="item.key" :readonly="readonly">
116
+ <option v-for="column in selectedDatasourceColumns"
115
117
  :value="column.key">
116
- {{ column.label }}
118
+ {{ selectedDatasource.pivot?.enabled ? column.key : column.label }}
117
119
  </option>
118
120
  </Dropdown>
119
121
  </div>
@@ -125,7 +127,7 @@
125
127
  </ListItem>
126
128
  </div>
127
129
 
128
- <div class="flex justify-center">
130
+ <div class="flex justify-center" v-if="!readonly">
129
131
  <button type="button" class="text-primary p-3 flex flex-row items-center gap-2"
130
132
  @click="swap">
131
133
  <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="M449.9 39.96l-48.5 48.53C362.5 53.19 311.4 32 256 32C161.5 32 78.59 92.34 49.58 182.2c-5.438 16.81 3.797 34.88 20.61 40.28c16.97 5.5 34.86-3.812 40.3-20.59C130.9 138.5 189.4 96 256 96c37.96 0 73 14.18 100.2 37.8L311.1 178C295.1 194.8 306.8 223.4 330.4 224h146.9C487.7 223.7 496 215.3 496 204.9V59.04C496 34.99 466.9 22.95 449.9 39.96zM441.8 289.6c-16.94-5.438-34.88 3.812-40.3 20.59C381.1 373.5 322.6 416 256 416c-37.96 0-73-14.18-100.2-37.8L200 334C216.9 317.2 205.2 288.6 181.6 288H34.66C24.32 288.3 16 296.7 16 307.1v145.9c0 24.04 29.07 36.08 46.07 19.07l48.5-48.53C149.5 458.8 200.6 480 255.1 480c94.45 0 177.4-60.34 206.4-150.2C467.9 313 458.6 294.1 441.8 289.6z"/></svg>
@@ -135,17 +137,12 @@
135
137
 
136
138
  <div v-if="value.props.yAxeMultiple" class="flex flex-row items-center gap-2">
137
139
  <label class="flex-1">Use Percentage</label>
138
- <Switch v-model="value.props.usePercentage" />
140
+ <Switch v-model="value.props.usePercentage" :readonly="readonly" />
139
141
  </div>
140
142
 
141
- <div class="flex flex-row items-center gap-2">
142
- <label class="flex-1">Height</label>
143
- <Dropdown class="w-[100px]"
144
- v-model.number="value.props.barHeight">
145
- <option :value="200">200px</option>
146
- <option :value="300">300px</option>
147
- <option :value="400">400px</option>
148
- </Dropdown>
143
+ <div v-if="value.props.yAxeMultiple" class="flex flex-row items-center gap-2">
144
+ <label class="flex-1">Stacked</label>
145
+ <Switch v-model="value.props.stacked" :readonly="readonly" />
149
146
  </div>
150
147
 
151
148
  </div>
@@ -164,6 +161,14 @@ export default{
164
161
  return this.datasource.find(d => d.uid === this.value.props.datasourceUid)
165
162
  },
166
163
 
164
+ selectedDatasourceColumns(){
165
+ if(!this.selectedDatasource) return []
166
+
167
+ return this.selectedDatasource.pivot?.enabled ?
168
+ this.selectedDatasource.pivot.columns :
169
+ this.selectedDatasource.columns
170
+ },
171
+
167
172
  xAxes(){
168
173
  if(!Array.isArray(this.value.props.xAxes))
169
174
  this.value.props.xAxes = [{ key:"" }]
@@ -188,7 +193,7 @@ export default{
188
193
 
189
194
  },
190
195
 
191
- inject: [ 'appStyle' ],
196
+ inject: [ 'appStyle', 'previewDatasource' ],
192
197
 
193
198
  methods: {
194
199