@mixd-id/web-scaffold 0.1.230406338 → 0.1.230406339

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.230406338",
4
+ "version": "0.1.230406339",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -331,10 +331,8 @@ export default{
331
331
  @apply panel-400;
332
332
  @apply border-[1px] border-text-50 z-20 flex max-h-[90vh];
333
333
  @apply rounded-xl overflow-hidden transition-all;
334
- background-color: rgba(255, 255, 255, .6)
335
334
  }
336
335
  html[data-theme='dark'] .modal{
337
- background-color: rgba(0, 0, 0, .6)
338
336
  }
339
337
 
340
338
  .modal.v-show{
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <div :class="$style.comp">
3
+
3
4
  <div :class="$style.header" v-if="visibleColumns.length > 0">
4
5
  <table :class="$style.table" ref="tableHead" :style="tableHeadStyle">
5
6
  <thead>
@@ -62,21 +63,21 @@
62
63
  <div v-else-if="visibleColumns.length <= 0 && Array.isArray(columns)" class="text-center p-3 flex-1 min-h-[100%] flex items-center justify-center">
63
64
  <h5 class="text-text-300">No active column</h5>
64
65
  </div>
65
- <div v-else-if="Array.isArray(items) && items.length <= 0" class="text-center p-3 flex-1 min-h-[100%] flex items-center justify-center">
66
+ <div v-else-if="Array.isArray(cItems) && cItems.length <= 0" class="text-center p-3 flex-1 min-h-[100%] flex items-center justify-center">
66
67
  <h5 class="text-text-300">No data available</h5>
67
68
  </div>
68
69
 
69
- <div :class="$style.calc" v-if="visibleColumns.length > 0 && items && items.length > 0" ref="calc">
70
+ <div :class="$style.calc" v-if="visibleColumns.length > 0 && cItems && cItems.length > 0" ref="calc">
70
71
  <table :class="$style.table">
71
72
  <tbody>
72
- <tr>
73
- <td v-for="column in columns" :style="thStyle(column)" :class="thClass(column)">
74
- <slot v-if="$slots[column.key]" :name="column.key" :column="column" :item="items[0]"></slot>
75
- <slot v-else-if="$slots.default" name="default" :column="column" :item="items[0]"></slot>
76
- <div v-else :class="columnClass(column)" v-html="formatColumn(items[0] ?? {}, column)"></div>
77
- </td>
78
- <td :class="$style.spacer"></td>
79
- </tr>
73
+ <tr>
74
+ <td v-for="column in cColumns" :style="thStyle(column)" :class="thClass(column)">
75
+ <slot v-if="$slots[column.key]" :name="column.key" :column="column" :item="cItems[0]"></slot>
76
+ <slot v-else-if="$slots.default" name="default" :column="column" :item="cItems[0]"></slot>
77
+ <div v-else :class="columnClass(column)" v-html="formatColumn(cItems[0] ?? {}, column)"></div>
78
+ </td>
79
+ <td :class="$style.spacer"></td>
80
+ </tr>
80
81
  </tbody>
81
82
  </table>
82
83
  </div>
@@ -89,11 +90,19 @@
89
90
  import throttle from "lodash/throttle";
90
91
  import dayjs from "dayjs";
91
92
  import {accessNestedObject} from "../utils/helpers.mjs";
93
+ import {useDatasource} from "../stores/datasource";
92
94
 
93
95
  const _DEFAULT_COLUMN_WIDTH = '100px'
94
96
 
95
97
  export default{
96
98
 
99
+ setup(){
100
+ const datasource = useDatasource()
101
+ return {
102
+ datasource
103
+ }
104
+ },
105
+
97
106
  inject: [ 'listStyle' ],
98
107
 
99
108
  emits: [ 'scroll-end', 'item-click' ],
@@ -109,6 +118,10 @@ export default{
109
118
 
110
119
  pinned: Function,
111
120
 
121
+ datasourceColumns: Array,
122
+
123
+ datasourceUid: String,
124
+
112
125
  defaultColumnWidth: {
113
126
  type: String,
114
127
  default: _DEFAULT_COLUMN_WIDTH
@@ -118,6 +131,8 @@ export default{
118
131
  type: Object,
119
132
  default: {}
120
133
  },
134
+
135
+ type: String
121
136
  },
122
137
 
123
138
  data(){
@@ -134,17 +149,27 @@ export default{
134
149
 
135
150
  computed:{
136
151
 
152
+ cColumns(){
153
+ return this.datasourceColumns ?? this.columns
154
+ },
155
+
156
+ cItems(){
157
+ return this.datasourceUid ?
158
+ this.datasource.keys[this.datasourceUid]?.items :
159
+ this.items
160
+ },
161
+
137
162
  visibleStartIndex(){
138
163
  return Math.floor((this.scrollTop < 0 ? 0 : this.scrollTop) / this.itemHeight)
139
164
  },
140
165
 
141
166
  sortedItems(){
142
- if(!Array.isArray(this.items)) return []
167
+ if(!Array.isArray(this.cItems)) return []
143
168
 
144
169
  if(typeof this.pinned === 'function'){
145
170
  const pinnedItems = []
146
171
  const unpinnedItems = []
147
- this.items.forEach((item) => {
172
+ this.cItems.forEach((item) => {
148
173
  if(this.pinned(item))
149
174
  pinnedItems.push(item)
150
175
  else
@@ -156,7 +181,7 @@ export default{
156
181
  ...unpinnedItems
157
182
  ]
158
183
  }
159
- return this.items
184
+ return this.cItems
160
185
  },
161
186
 
162
187
  visibleItems(){
@@ -171,10 +196,10 @@ export default{
171
196
  },
172
197
 
173
198
  scrollerStyle(){
174
- if(!this.items || this.items.length < 1)
199
+ if(!this.cItems || this.cItems.length < 1)
175
200
  return {}
176
201
 
177
- const height = (this.items.length * this.itemHeight) + (this.state === 2 ? 48 : 0)
202
+ const height = (this.cItems.length * this.itemHeight) + (this.state === 2 ? 48 : 0)
178
203
  const width = this.visibleColumns.reduce((r, item) => r + parseInt(item.width ?? _DEFAULT_COLUMN_WIDTH), 0)
179
204
 
180
205
  return {
@@ -190,7 +215,7 @@ export default{
190
215
  },
191
216
 
192
217
  visibleColumns(){
193
- return (this.columns ?? []).filter(_ => !('visible' in _) || _.visible)
218
+ return (this.cColumns ?? []).filter(_ => !('visible' in _) || _.visible)
194
219
  },
195
220
 
196
221
  visibleColumnKeys(){
@@ -270,7 +295,7 @@ export default{
270
295
  window.getComputedStyle(this.$el).height :
271
296
  window.getComputedStyle(this.$el).maxHeight)
272
297
  this.itemHeight = Math.ceil(parseFloat(window.getComputedStyle(this.$refs.calc).height))
273
- this.maxVisibleItems = elHeight > 0 ? Math.ceil(elHeight / this.itemHeight) + 1 : this.items.length
298
+ this.maxVisibleItems = elHeight > 0 ? Math.ceil(elHeight / this.itemHeight) + 1 : this.cItems.length
274
299
 
275
300
  if(this.itemHeight <= 0 && import.meta.env.DEV){
276
301
  console.error('[VirtualTable] Unable to calculate item height, make sure not async component.')
@@ -319,7 +344,7 @@ export default{
319
344
 
320
345
  startResize(e, column){
321
346
 
322
- const idx = this.columns.findIndex((_) => _ === column)
347
+ const idx = this.cColumns.findIndex((_) => _ === column)
323
348
  let x1 = e.touches ? e.touches[0].clientX : e.clientX
324
349
 
325
350
  const onMouseMove = (e) => {
@@ -327,9 +352,9 @@ export default{
327
352
  const d = x2 - x1
328
353
  x1 = x2
329
354
 
330
- let width = parseInt(this.columns[idx].width ?? _DEFAULT_COLUMN_WIDTH) + d
355
+ let width = parseInt(this.cColumns[idx].width ?? _DEFAULT_COLUMN_WIDTH) + d
331
356
  if(width < 20) width = 20
332
- this.columns[idx].width = width
357
+ this.cColumns[idx].width = width
333
358
  }
334
359
 
335
360
  const onMouseUp = (e) => {
@@ -563,7 +588,7 @@ export default{
563
588
 
564
589
  watch: {
565
590
 
566
- items: {
591
+ cItems: {
567
592
  deep: true,
568
593
  handler(to, from){
569
594
  if((to ?? []).length !== (from ?? []).length){
package/src/index.js CHANGED
@@ -671,6 +671,12 @@ export default{
671
671
  app.component('MenuEditor', defineAsyncComponent(() => import("./widgets/MenuEditor.vue")))
672
672
  app.component('Dashboard', defineAsyncComponent(() => import("./widgets/Dashboard.vue")))
673
673
  app.component('Text', defineAsyncComponent(() => import("./components/Text.vue")))
674
+
675
+ app.component('Doughnut', defineAsyncComponent(() => import("./widgets/Dashboard/Doughnut.vue")))
676
+ app.component('Pie', defineAsyncComponent(() => import("./widgets/Dashboard/Pie.vue")))
677
+ app.component('PolarArea', defineAsyncComponent(() => import("./widgets/Dashboard/PolarArea.vue")))
678
+ app.component('Metric', defineAsyncComponent(() => import("./widgets/Dashboard/Metric.vue")))
679
+ app.component('BarChart', defineAsyncComponent(() => import("./widgets/Dashboard/BarChart.vue")))
674
680
  }
675
681
 
676
682
  }
@@ -0,0 +1,11 @@
1
+ import { defineStore } from 'pinia'
2
+
3
+ export const useDatasource = defineStore('datasource', {
4
+
5
+ state: () => ({
6
+ keys: {}
7
+ }),
8
+
9
+ actions: {}
10
+
11
+ })
@@ -0,0 +1,265 @@
1
+ <template>
2
+ <div :class="$style.comp" class="flex flex-col gap-5">
3
+
4
+ <div v-if="yAxeMultiple" class="flex flex-row justify-center gap-1">
5
+ <div v-for="(yLegend, idx) in yLegends"
6
+ 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"
7
+ :style="{ backgroundColor:backgroundColors[idx % backgroundColors.length] }">
8
+ {{ (yLegend ?? '').toString().split(' ')[0].toLowerCase() }}
9
+ </div>
10
+ </div>
11
+
12
+ <div class="flex-1">
13
+ <Bar :style="barStyles"
14
+ :options="chartOptions"
15
+ :data="chartData" />
16
+ </div>
17
+
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+
23
+ import {Bar} from 'vue-chartjs'
24
+ import Chart from 'chart.js/auto'
25
+ import {useDatasource} from "../../stores/datasource";
26
+
27
+ export default{
28
+
29
+ components: {
30
+ Bar
31
+ },
32
+
33
+ computed: {
34
+
35
+ barStyles(){
36
+ return {
37
+ position: "relative",
38
+ height: `${this.barHeight}px`
39
+ }
40
+ },
41
+
42
+ chartData(){
43
+ if(!this.xAxes || !this.cValue?.items)
44
+ return { labels:[], datasets:[] }
45
+
46
+ let labels = []
47
+ let datasets = [
48
+ /*{
49
+ data:[ 1, 2, 3, 4, 5 ]
50
+ },
51
+ {
52
+ data:[ 2, 3, 4, 5, 6 ]
53
+ }*/
54
+ ]
55
+
56
+ let xAxes
57
+ if(this.xAxeMultiple){
58
+ xAxes = this.xAxes
59
+ }
60
+ else{
61
+ const xAxesKey = this.xAxes[0].key
62
+ const reduced = this.cValue.items.reduce((acc, item) => {
63
+ const key = item[xAxesKey]
64
+ acc[key] = { key, parentKey:xAxesKey }
65
+ return acc
66
+ }, {})
67
+
68
+ xAxes = Object.values(reduced)
69
+ }
70
+
71
+ let yAxes
72
+ if(this.yAxeMultiple){
73
+ const yAxesKey = this.yAxes[0].key
74
+ const reduced = this.cValue.items.reduce((acc, item) => {
75
+ const key = item[yAxesKey]
76
+ acc[key] = { key, parentKey:yAxesKey }
77
+ return acc
78
+ }, {})
79
+
80
+ yAxes = Object.values(reduced)
81
+ }
82
+ else{
83
+ yAxes = [ this.yAxes[0] ]
84
+ }
85
+
86
+ let idx = 0
87
+ const yLegends = []
88
+ for(let yAxe of yAxes){
89
+
90
+ let data
91
+
92
+ let items
93
+ if(this.yAxeMultiple){
94
+ items = this.cValue.items.filter(_ => _[yAxe.parentKey] === yAxe.key)
95
+ }
96
+ else{
97
+ items = this.cValue.items
98
+ }
99
+
100
+ if(this.xAxeMultiple){
101
+ data = xAxes.map(_ => {
102
+ return items.reduce((acc, item) => {
103
+ return acc + item[_.key]
104
+ }, 0)
105
+ })
106
+ }
107
+ else{
108
+ data = xAxes.map(_ => {
109
+ const curItems = items.filter(__ => __[_.parentKey] === _.key)
110
+
111
+ return curItems.reduce((acc, item) => {
112
+ return acc + item[yAxe.key]
113
+ }, 0)
114
+ })
115
+ }
116
+
117
+ datasets.push({
118
+ label: this.yAxeMultiple ? yAxe.key : 'All',
119
+ data,
120
+ backgroundColor: yAxes.length > 1 ?
121
+ [ this.backgroundColors[idx % this.backgroundColors.length] ]:
122
+ this.backgroundColors,
123
+ borderColor: yAxes.length > 1 ?
124
+ [ this.backgroundColors[idx % this.backgroundColors.length] ]:
125
+ this.backgroundColors,
126
+ borderWidth: 1
127
+ })
128
+
129
+ yLegends.push(yAxe.key)
130
+
131
+ idx++
132
+ }
133
+
134
+ labels = xAxes.map(_ => _.key)
135
+
136
+ this.yLegends = yLegends
137
+
138
+ if(this.relativeValue){
139
+
140
+
141
+ }
142
+
143
+ console.log('chartData', {
144
+ labels,
145
+ datasets
146
+ })
147
+
148
+ return {
149
+ labels,
150
+ datasets
151
+ }
152
+ },
153
+
154
+ chartOptions(){
155
+ return {
156
+ responsive: true,
157
+ maintainAspectRatio: false,
158
+ plugins: {
159
+ legend: {
160
+ display: false // This hides the legend
161
+ }
162
+ },
163
+ scales: {
164
+ x: {
165
+ grid: {
166
+ display: true,
167
+ color: function(context){
168
+ return `rgba(255,255,255, .1)`
169
+ }
170
+ },
171
+ ticks: {
172
+ callback: function(value) {
173
+ const label = this.getLabelForValue(value);
174
+ return label.length > 10 ? label.slice(0, 10) + '...' : label;
175
+ },
176
+ minRotation: 0,
177
+ maxRotation: 0
178
+ }
179
+ },
180
+ y: {
181
+ beginAtZero: true,
182
+ ticks: {
183
+ display: false,
184
+ },
185
+ grid: {
186
+ display: true,
187
+ color: function(context){
188
+ return `rgba(255,255,255, .1)`
189
+ }
190
+ },
191
+ }
192
+ }
193
+ }
194
+ },
195
+
196
+ cValue(){
197
+ return this.datasourceUid && this.datasource ?
198
+ this.datasource.keys[this.datasourceUid] :
199
+ this.value
200
+ }
201
+
202
+ },
203
+
204
+ data(){
205
+ return {
206
+ backgroundColors: [
207
+ '#5D9CEC',
208
+ '#A0D468',
209
+ '#FFCE54',
210
+ '#FC6E51',
211
+ '#48CFAD',
212
+ '#AC92EC',
213
+ '#4FC1E9',
214
+ '#FFCE54',
215
+ '#ED5565',
216
+ '#EC87C0'
217
+ ],
218
+
219
+ yLegends: []
220
+ }
221
+ },
222
+
223
+ props: {
224
+
225
+ datasourceUid: String,
226
+
227
+ relativeValue: {
228
+ type: Boolean,
229
+ default: false
230
+ },
231
+
232
+ barHeight: {
233
+ type: Number,
234
+ default: 200
235
+ },
236
+
237
+ xAxes: Array,
238
+ yAxes: Array,
239
+ xAxeMultiple: Boolean,
240
+ yAxeMultiple: Boolean,
241
+
242
+ segments: Array,
243
+ xAxesGroup: String,
244
+
245
+ },
246
+
247
+ setup(){
248
+ const datasource = useDatasource()
249
+ return {
250
+ datasource
251
+ }
252
+ },
253
+
254
+ }
255
+
256
+ </script>
257
+
258
+ <style module>
259
+
260
+ .comp{
261
+ @apply border-[1px] border-text-50 bg-base-500 rounded-lg;
262
+ @apply p-3;
263
+ }
264
+
265
+ </style>