@mixd-id/web-scaffold 0.1.230406132 → 0.1.230406134

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.230406132",
4
+ "version": "0.1.230406134",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -0,0 +1,193 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+ <pre class="hidden whitespace-nowrap text-xs overflow-x-auto">{{ options }}</pre>
4
+ <Bar :class="$style.chart" :data="chartData" :options="chartOptions" />
5
+ </div>
6
+ </template>
7
+
8
+ <script>
9
+
10
+ import { Bar } from 'vue-chartjs';
11
+ import Chart from 'chart.js/auto'
12
+ import dayjs from "dayjs";
13
+ import groupBy from "lodash/groupBy";
14
+
15
+ export default{
16
+
17
+ name: 'BarChart',
18
+
19
+ components: { Bar },
20
+
21
+ props: {
22
+
23
+ items: Array,
24
+
25
+ options: Object,
26
+
27
+ },
28
+
29
+ methods: {
30
+
31
+ setInitialData(){
32
+
33
+ const items = []
34
+ const end = new Date();
35
+ const start = new Date(end);
36
+ start.setMinutes(end.getMinutes() - 2);
37
+
38
+ let currentTime = new Date(start);
39
+ while (currentTime <= end) {
40
+
41
+ const count = Math.round(Math.random() * 100)
42
+ for(let i = 0 ; i < count ; i++){
43
+ items.push({
44
+ createdAt: currentTime.toISOString()
45
+ })
46
+ }
47
+
48
+ currentTime.setSeconds(currentTime.getSeconds() + 1);
49
+ }
50
+
51
+ this.items = items
52
+ },
53
+
54
+ play(){
55
+
56
+ const arr = []
57
+ const end = new Date();
58
+ //end.setHours(16, 7, 0, 0)
59
+ const start = new Date(end);
60
+ start.setHours(end.getHours() - 2);
61
+
62
+ let currentTime = new Date(start);
63
+ while (currentTime <= end) {
64
+ arr.push(dayjs(currentTime).format('YYYYMMDDHHmm'))
65
+ currentTime.setMinutes(currentTime.getMinutes() + 1);
66
+ }
67
+
68
+ this.labels = arr
69
+
70
+ /*let count = Math.round(Math.random() * 100)
71
+ if(count < 10) count = 0
72
+ const newItems = []
73
+ for(let i = 0 ; i < count ; i++){
74
+ newItems.push({
75
+ createdAt: currentTime.toISOString()
76
+ })
77
+ }
78
+ this.items.push(...newItems)*/
79
+
80
+ /*window.setTimeout(() => {
81
+ this.play()
82
+ }, 1000)*/
83
+ },
84
+
85
+ },
86
+
87
+ data(){
88
+ return {
89
+ labels: [],
90
+ groupedData: {},
91
+ // items: []
92
+ }
93
+ },
94
+
95
+ mounted() {
96
+
97
+ //this.setInitialData()
98
+
99
+ this.play()
100
+ },
101
+
102
+ computed: {
103
+
104
+ columnKey(){
105
+ return this.options.bar.rows[0].key
106
+ },
107
+
108
+ interval(){
109
+ return this.options.bar.rows[0].format
110
+ },
111
+
112
+ groupedItems(){
113
+ console.log('#1', this.columnKey)
114
+ return groupBy(this.items, (item) => {
115
+ return dayjs(item[this.columnKey]).format('YYYYMMDDHHmm')
116
+ })
117
+ },
118
+
119
+ data(){
120
+ const arr = []
121
+ for(let i = 0 ; i < this.labels.length ; i++){
122
+ arr.push((this.groupedItems[this.labels[i]] ?? []).length)
123
+ }
124
+
125
+ /*if(Array.isArray(this.labels))
126
+ console.log(this.labels[0], this.labels[this.labels.length - 1], Object.keys(this.groupedItems), arr)*/
127
+
128
+ return arr
129
+ },
130
+
131
+ chartData() {
132
+ return {
133
+ labels: this.labels,
134
+ datasets: [ { data: this.data } ],
135
+ }
136
+ },
137
+
138
+ chartOptions() {
139
+
140
+ var style = getComputedStyle(document.body)
141
+ var gridColor = style.getPropertyValue('--text-50')
142
+ var gridColor2 = style.getPropertyValue('--text-200')
143
+
144
+ return {
145
+ responsive: true,
146
+ maintainAspectRatio: false,
147
+ animation: false,
148
+ plugins: {
149
+ legend: {
150
+ display: false, // Disable the legend
151
+ },
152
+ },
153
+ scales: {
154
+ x: {
155
+ display: false, // Disable x-axis labels
156
+ grid: {
157
+ display: true,
158
+ color: function(context){
159
+ return `rgb(${gridColor2})`
160
+ }
161
+ },
162
+ },
163
+ y: {
164
+ beginAtZero: true, // Adjust y-axis as needed
165
+ grid: {
166
+ display: true,
167
+ color: function(context){
168
+ return `rgb(${gridColor})`
169
+ }
170
+ },
171
+ },
172
+ },
173
+ }
174
+ }
175
+
176
+ },
177
+
178
+ }
179
+
180
+ </script>
181
+
182
+ <style module>
183
+
184
+ .comp{
185
+ @apply flex-1;
186
+ }
187
+
188
+ .chart{
189
+ position: relative;
190
+ width: 100%;
191
+ }
192
+
193
+ </style>
@@ -88,8 +88,9 @@
88
88
  </Textbox>
89
89
  </div>
90
90
 
91
- <div v-if="presetSummary && summary" class="h-[300px] max-h-[30vh] flex">
91
+ <div v-if="presetSummary" class="h-[300px] flex" :class="presetSummary.mode === 'liveBar' ? 'max-h-[20vh]' : 'max-h-[30vh]'">
92
92
  <Bar v-if="presetSummary.mode === 'bar'" :data="chartData" :options="chartOptions" class="flex-1 w-full p-2"/>
93
+ <ChartBar v-else-if="presetSummary.mode === 'liveBar'" :items="items" :options="presetSummary" class="flex-1"/>
93
94
  <Line v-else-if="presetSummary.mode === 'line'" :data="chartData" :options="chartOptions" class="flex-1 w-full p-2"/>
94
95
  <VirtualTable v-else-if="presetSummary.mode === 'table'" :items="summaryItems" :columns="summaryColumns" class="flex-1"></VirtualTable>
95
96
  <Gmaps v-else-if="presetSummary.mode === 'map'" :data="summary.items" :config="presetSummary.map"
@@ -345,6 +346,8 @@ export default{
345
346
  break
346
347
  }
347
348
 
349
+ itemsPerPage = 300
350
+
348
351
  this.socketEmit2(this.src, { columns:this.config.columns, preset:this.preset, itemsPerPage })
349
352
  .then((res) => {
350
353
  Object.assign(this.$data, res)
@@ -411,6 +414,7 @@ export default{
411
414
  switch(event){
412
415
 
413
416
  case 'create':
417
+ case 'bulk-create':
414
418
  case 'update':
415
419
  if(items[0] && Object.keys(items[0]).length <= 1 && Object.keys(items[0])[0] === 'uid'){
416
420
  this.socketEmit2(this.src, {
@@ -596,6 +600,7 @@ export default{
596
600
  },
597
601
 
598
602
  chartOptions(){
603
+ if(!this.summary) return {}
599
604
 
600
605
  var style = getComputedStyle(document.body)
601
606
  var gridColor = style.getPropertyValue('--text-50')
@@ -10,6 +10,7 @@
10
10
  </Dropdown>
11
11
  <Dropdown v-model="summary.bar.rows[0].format" class="w-[100px]">
12
12
  <option value="">{{ $t('Default') }}</option>
13
+ <option value="hour">{{ $t('Hour') }}</option>
13
14
  <option value="date">{{ $t('Date') }}</option>
14
15
  <option value="month">{{ $t('Month') }}</option>
15
16
  <option value="quarter">{{ $t('Quarterly') }}</option>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ <div class="p-3">
5
+ <label class="text-text-400 flex-1">{{ $t('X-axis') }}</label>
6
+ <div class="flex flex-row mt-2 gap-2">
7
+ <Dropdown v-model="summary.bar.rows[0].key" class="flex-1">
8
+ <option value="" disabled selected>{{ $t('Add Column') }}</option>
9
+ <option v-for="column in columns" :value="column.key">{{ column.label ?? column.key }}</option>
10
+ </Dropdown>
11
+ <Dropdown v-model="summary.bar.rows[0].format" class="w-[100px]">
12
+ <option value="">{{ $t('Default') }}</option>
13
+ <option value="second">{{ $t('Second') }}</option>
14
+ <option value="minute">{{ $t('Minute') }}</option>
15
+ <option value="hour">{{ $t('Hour') }}</option>
16
+ <option value="date">{{ $t('Date') }}</option>
17
+ <option value="month">{{ $t('Month') }}</option>
18
+ <option value="quarter">{{ $t('Quarterly') }}</option>
19
+ <option value="year">{{ $t('Year') }}</option>
20
+ </Dropdown>
21
+ </div>
22
+ </div>
23
+
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+
29
+ export default{
30
+
31
+ props: {
32
+
33
+ columns: Array,
34
+
35
+ summary: {
36
+ type: Object,
37
+ required: true
38
+ }
39
+
40
+ }
41
+
42
+ }
43
+
44
+ </script>
45
+
46
+ <style module>
47
+
48
+ .comp{
49
+
50
+ }
51
+
52
+ </style>
@@ -210,6 +210,7 @@
210
210
  <Dropdown v-model="openedPresetSummary.mode" class="flex-1">
211
211
  <option value="table">{{ $t('Table') }}</option>
212
212
  <option value="bar">{{ $t('Bar Chart') }}</option>
213
+ <option value="liveBar">{{ $t('Live Bar Chart') }}</option>
213
214
  <option value="line">{{ $t('Line Chart') }}</option>
214
215
  <option value="map">{{ $t('Maps') }}</option>
215
216
  </Dropdown>
@@ -225,6 +226,9 @@
225
226
  <ListViewBarSummary v-else-if="openedPresetSummary.mode === 'bar'"
226
227
  :summary="openedPresetSummary" :columns="filterableColumns" />
227
228
 
229
+ <ListViewLiveBarSummary v-else-if="openedPresetSummary.mode === 'liveBar'"
230
+ :summary="openedPresetSummary" :columns="filterableColumns" />
231
+
228
232
  <ListViewLineSummary v-else-if="openedPresetSummary.mode === 'line'"
229
233
  :summary="openedPresetSummary" :columns="filterableColumns" />
230
234
 
@@ -280,7 +280,7 @@ export default{
280
280
 
281
281
  .slider>div:nth-child(3),
282
282
  .slider>div:nth-child(4){
283
- @apply absolute w-[2.1rem] h-[2.1rem] rounded-full bg-white shadow-sm border-[1px] border-text-200;
283
+ @apply absolute w-[2.3rem] h-[2.3rem] rounded-full bg-white shadow-sm border-[1px] border-text-200;
284
284
  @apply flex;
285
285
  top: 50%;
286
286
  transform: translate3d(0, -50%, 0);
@@ -250,6 +250,8 @@ export default{
250
250
  },
251
251
 
252
252
  handleScroll: throttle(function(){
253
+ if(!this.$refs.scroller || !this.$refs.cont) return
254
+
253
255
  this.scrollTop = this.$refs.cont.scrollTop
254
256
  this.scrollLeft = this.$refs.cont.scrollLeft
255
257
 
package/src/index.js CHANGED
@@ -337,6 +337,7 @@ export default{
337
337
  app.component('Block', defineAsyncComponent(() => import("./components/Block.vue")))
338
338
  app.component('Button', defineAsyncComponent(() => import("./components/Button.vue")))
339
339
  app.component('Box', defineAsyncComponent(() => import("./components/Box.vue")))
340
+ app.component('ChartBar', defineAsyncComponent(() => import("./components/ChartBar.vue")))
340
341
  app.component('ColorPicker', defineAsyncComponent(() => import("./components/ColorPicker.vue")))
341
342
  app.component('SearchButton', defineAsyncComponent(() => import("./components/SearchButton.vue")))
342
343
  app.component('ChatTyping', defineAsyncComponent(() => import("./components/ChatTyping.vue")))
@@ -367,6 +368,7 @@ export default{
367
368
  app.component('ListView', defineAsyncComponent(() => import("./components/ListView.vue")))
368
369
  app.component('ListViewSettings', defineAsyncComponent(() => import("./components/ListViewSettings.vue")))
369
370
  app.component('ListViewBarSummary', defineAsyncComponent(() => import("./components/ListViewBarSummary.vue")))
371
+ app.component('ListViewLiveBarSummary', defineAsyncComponent(() => import("./components/ListViewLiveBarSummary.vue")))
370
372
  app.component('ListViewTableSummary', defineAsyncComponent(() => import("./components/ListViewTableSummary.vue")))
371
373
  app.component('ListViewLineSummary', defineAsyncComponent(() => import("./components/ListViewLineSummary.vue")))
372
374
  app.component('ListViewMapSummary', defineAsyncComponent(() => import("./components/ListViewMapSummary.vue")))
@@ -10,6 +10,7 @@ let ListView = {
10
10
  itemsPerPage: 24,
11
11
  model: '',
12
12
  channel: '',
13
+ conn: null,
13
14
 
14
15
  async load(params){
15
16
 
@@ -48,7 +49,11 @@ let ListView = {
48
49
  return
49
50
  }
50
51
 
51
- const summary = ((params.preset ?? {}).summaries ?? []).filter((_) => _.enabled).pop()
52
+ if(!params || !params.preset){
53
+ return
54
+ }
55
+
56
+ const summary = (params.preset.summaries ?? []).filter((_) => _.enabled).pop()
52
57
  if(!summary) return
53
58
 
54
59
  const { derivedSql, where, replacements } = loadResults
@@ -418,6 +423,12 @@ let ListView = {
418
423
  const rowKey = row.key
419
424
  const rowLabel = this.columns.find((_) => _.key === row.key).label
420
425
  switch(row.format){
426
+ case 'minute':
427
+ attributes.push(`DATE_FORMAT(${rowKey}, '%Y-%m-%d %H:%i:00') as dfDate`)
428
+ group.push(`DATE_FORMAT(${rowKey}, '%Y-%m-%d %H:%i:00')`)
429
+ summaryColumns.push({ key:"dfDate", label:rowLabel, width:"200px", visible:true, type:"date", format:"HH:mm" })
430
+ break
431
+
421
432
  case 'date':
422
433
  attributes.push(`DATE_FORMAT(${rowKey}, '%Y-%m-%d') as dfDate`)
423
434
  group.push(`DATE_FORMAT(${rowKey}, '%Y-%m-%d')`)
@@ -1,17 +1,16 @@
1
1
  <template>
2
2
  <div :class="$style.comp" v-if="Array.isArray(items) && items.length > 0">
3
- <pre></pre>
4
3
  <div v-if="id" :id="id" :class="$style.anchor"></div>
5
4
  <h3>{{ title ?? '' }}</h3>
6
5
  <p v-if="description" class="mt-2 text-lg">{{ description }}</p>
7
6
  <div :class="computedContainerClass">
8
7
  <div v-for="item in items" class="flex gap-4" :class="computedItemClass">
9
8
  <div>
10
- <Image :src="imageUrl(item.imageUrl)" class="bg-gray-200 rounded-xl w-full aspect-square object-contain" />
9
+ <Image :src="imageUrl(item.imageUrl)" :class="`object-contain ${item.sizeClass}`" />
11
10
  </div>
12
- <div class="flex-1 flex flex-col gap-1">
13
- <h5>{{ item.title ?? 'Untitled' }}</h5>
14
- <p>{{ item.description ?? '' }}</p>
11
+ <div class="flex-1 flex flex-col gap-1" v-if="item.title || item.description">
12
+ <h5 v-if="item.title">{{ item.title }}</h5>
13
+ <p v-if="item.description">{{ item.description }}</p>
15
14
  </div>
16
15
  </div>
17
16
  </div>
@@ -36,7 +35,7 @@ export default{
36
35
  type: Array,
37
36
  default: [ 2, 4 ]
38
37
  },
39
- variant: Array
38
+ variant: Array,
40
39
 
41
40
  },
42
41
 
@@ -82,7 +81,7 @@ export default{
82
81
  }
83
82
 
84
83
  .container{
85
- @apply grid gap-6 mt-8;
84
+ @apply grid gap-6 mt-4;
86
85
  }
87
86
 
88
87
  .item{
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="flex-1 flex flex-row items-center gap-2">
3
- {{ item.props.name ?? 'Feature List' }}
3
+ {{ item.props.name ?? (item.props.title ?? 'Feature List') }}
4
4
  </div>
5
5
  </template>
6
6
 
@@ -139,6 +139,27 @@
139
139
  <Textarea v-model="context.image.description" rows="3" placeholder="Description" />
140
140
  </div>
141
141
 
142
+ <div class="flex flex-col gap-1">
143
+ <label class="flex-1 text-text-400">Size</label>
144
+ <Dropdown v-model="context.image.sizeClass" class="w-[100px]">
145
+ <option value="">Unset</option>
146
+ <option value="w-1">1</option>
147
+ <option value="w-2">2</option>
148
+ <option value="w-3">3</option>
149
+ <option value="w-4">4</option>
150
+ <option value="w-5">5</option>
151
+ <option value="w-6">6</option>
152
+ <option value="w-8">8</option>
153
+ <option value="w-12">12</option>
154
+ <option value="w-16">16</option>
155
+ <option value="w-20">20</option>
156
+ <option value="w-28">28</option>
157
+ <option value="w-32">32</option>
158
+ <option value="w-36">36</option>
159
+ <option value="w-48">48</option>
160
+ </Dropdown>
161
+ </div>
162
+
142
163
  </div>
143
164
  </template>
144
165
  </Modal>