@mixd-id/web-scaffold 0.1.230406312 → 0.1.230406313

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.230406312",
4
+ "version": "0.1.230406313",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -250,7 +250,7 @@ import VirtualGrid from "./VirtualGrid.vue";
250
250
  import throttle from "lodash/throttle";
251
251
  import PresetSelector from "../widgets/PresetSelector.vue";
252
252
  import groupBy from "lodash/groupBy";
253
- import { generatePivotColumns, sortsFn } from "../utils/preset-selector.mjs";
253
+ import { generatePivotColumns, generateTotalColumns, sortsFn } from "../utils/preset-selector.mjs";
254
254
  import PresetBar from "../widgets/PresetBar.vue";
255
255
 
256
256
  export default{
@@ -340,12 +340,11 @@ export default{
340
340
  itemsPerPage: this.data.itemsPerPage,
341
341
  })
342
342
  .then(data => {
343
-
344
343
  generatePivotColumns(this.preset, data.items)
344
+ generateTotalColumns(this.preset, data.items)
345
345
  this.loadEnums(data.items)
346
346
  Object.assign(this.data, data ?? {})
347
347
  this.$emit('after-load')
348
-
349
348
  })
350
349
  .catch(err => {
351
350
  this.toast(err)
@@ -586,24 +585,60 @@ export default{
586
585
  const filters = []
587
586
 
588
587
  for(let idx in this.preset.pivot.rows){
589
- const key = this.preset.pivot.rows[idx].key
588
+ const pivotRow = this.preset.pivot.rows[idx]
589
+ const key = pivotRow.key
590
590
  const presetColumn = this.preset.columns.find(_ => _.key === key)
591
- let value = item[this.preset.pivot.rows[idx].key]
591
+ let value = item[pivotRow.key]
592
592
  switch(presetColumn.type){
593
593
 
594
594
  case 'bool':
595
595
  case 'boolean':
596
- value = value === 'true'
596
+ filters.push({
597
+ key,
598
+ value: [{
599
+ operator: '=',
600
+ value: value === 'true'
601
+ }]
602
+ })
603
+ break
604
+
605
+ case 'date':
606
+ switch(pivotRow.aggregrate){
607
+
608
+ case 'hour':
609
+ value = value.split('-')
610
+ filters.push({
611
+ key,
612
+ value: [{
613
+ operator: '>=',
614
+ value: value[0] + ':00',
615
+ fn: 'format_hour'
616
+ }]
617
+ })
618
+ filters.push({
619
+ key,
620
+ value: [{
621
+ operator: '<=',
622
+ value: value[1] + ':59',
623
+ fn: 'format_hour'
624
+ }]
625
+ })
626
+ break
627
+
628
+ }
629
+ break
630
+
631
+ default:
632
+ filters.push({
633
+ key,
634
+ value: [{
635
+ operator: '=',
636
+ value
637
+ }]
638
+ })
597
639
  break
598
640
  }
599
641
 
600
- filters.push({
601
- key,
602
- value: [{
603
- operator: '=',
604
- value
605
- }]
606
- })
607
642
  }
608
643
 
609
644
  let [ kk, ...vv ] = column.key.split('-')
@@ -32,18 +32,23 @@
32
32
  </tr>
33
33
  </thead>
34
34
  <tbody ref="tbody">
35
- <tr v-for="(item, index) in visibleItems" :key="item"
36
- @click="select(item, index)"
37
- :class="trClass(item, index)">
38
- <td v-for="column in visibleColumns"
39
- :class="tdClass(item, column)"
40
- @click="$emit('item-click', item, column)">
41
- <slot v-if="$slots[column.key]" :name="column.key" :column="column" :item="item" :index="visibleStartIndex + index"></slot>
42
- <slot v-else-if="$slots.default" name="default" :column="column" :item="item" :index="visibleStartIndex + index"></slot>
43
- <div v-else :class="columnClass(column, item)" v-html="formatColumn(item, column)"></div>
44
- </td>
45
- <td :class="$style.spacer"></td>
46
- </tr>
35
+ <tr v-for="(item, index) in visibleItems" :key="item"
36
+ @click="select(item, index)"
37
+ :class="trClass(item, index)">
38
+ <td v-for="(column, columnIndex) in visibleColumns"
39
+ :class="tdClass(item, column)"
40
+ @click="$emit('item-click', item, column)">
41
+
42
+ <div v-if="columnIndex === 0 && item._type === 'totalRow'" :class="$style.total">Total</div>
43
+ <div v-else-if="item._type === 'totalRow' && !column.key.startsWith('_')"></div>
44
+
45
+ <slot v-else-if="$slots[column.key]" :name="column.key" :column="column" :item="item" :index="visibleStartIndex + index"></slot>
46
+ <slot v-else-if="$slots.default" name="default" :column="column" :item="item" :index="visibleStartIndex + index"></slot>
47
+ <div v-else :class="columnClass(column, item)" v-html="formatColumn(item, column)"></div>
48
+
49
+ </td>
50
+ <td :class="$style.spacer"></td>
51
+ </tr>
47
52
  </tbody>
48
53
  </table>
49
54
  <div v-if="state === 2" ref="spinner" class="h-[44px] relative">
@@ -343,8 +348,16 @@ export default{
343
348
  case 'currency':
344
349
  align = 'right'
345
350
  break
351
+
352
+ default:
353
+ if(column.key.startsWith('_'))
354
+ align = 'center'
355
+ break
346
356
  }
347
357
  }
358
+ else{
359
+ align = column.align
360
+ }
348
361
 
349
362
  let appearanceClass = ''
350
363
  if(item && Array.isArray(column.appearances)){
@@ -361,93 +374,95 @@ export default{
361
374
  break
362
375
  }
363
376
 
364
- for(let appearance of column.appearances){
365
-
366
- let conditionMatched = false
367
- for(let condition of appearance.conditions ?? []){
368
- switch(condition.operator){
369
-
370
- case '>':
371
- if(value > condition.value){
377
+ if(!('_type' in item)){
378
+ for(let appearance of column.appearances){
379
+
380
+ let conditionMatched = false
381
+ for(let condition of appearance.conditions ?? []){
382
+ switch(condition.operator){
383
+
384
+ case '>':
385
+ if(value > condition.value){
386
+ conditionMatched = true
387
+ }
388
+ break
389
+
390
+ case '>=':
391
+ if(value >= condition.value){
392
+ conditionMatched = true
393
+ }
394
+ break
395
+
396
+ case '=':
397
+ if(value === condition.value){
398
+ conditionMatched = true
399
+ }
400
+ break
401
+
402
+ case '<':
403
+ if(value < condition.value){
404
+ conditionMatched = true
405
+ }
406
+ break
407
+
408
+ case '<=':
409
+ if(value <= condition.value){
410
+ conditionMatched = true
411
+ }
412
+ break
413
+
414
+ case 'startsWith':
415
+ if(value.startsWith(condition.value)){
416
+ conditionMatched = true
417
+ }
418
+ break
419
+
420
+ case 'notStartsWith':
421
+ if(!value.startsWith(condition.value)){
422
+ conditionMatched = true
423
+ }
424
+ break
425
+
426
+ case 'contains':
427
+ if(value.indexOf(condition.value) >= 0){
428
+ conditionMatched = true
429
+ }
430
+ break
431
+
432
+ case 'notContains':
433
+ if(value.indexOf(condition.value) < 0){
434
+ conditionMatched = true
435
+ }
436
+ break
437
+
438
+ case 'endsWith':
439
+ if(value.endsWith(condition.value)){
440
+ conditionMatched = true
441
+ }
442
+ break
443
+
444
+ case 'notEndsWith':
445
+ if(!value.endsWith(condition.value)){
446
+ conditionMatched = true
447
+ }
448
+ break
449
+
450
+ case 'none':
372
451
  conditionMatched = true
373
- }
374
- break
452
+ break
375
453
 
376
- case '>=':
377
- if(value >= condition.value){
378
- conditionMatched = true
379
- }
380
- break
454
+ case 'regex':
455
+ break
381
456
 
382
- case '=':
383
- if(value === condition.value){
384
- conditionMatched = true
385
- }
386
- break
387
-
388
- case '<':
389
- if(value < condition.value){
390
- conditionMatched = true
391
- }
392
- break
393
-
394
- case '<=':
395
- if(value <= condition.value){
396
- conditionMatched = true
397
- }
398
- break
399
-
400
- case 'startsWith':
401
- if(value.startsWith(condition.value)){
402
- conditionMatched = true
403
- }
404
- break
405
-
406
- case 'notStartsWith':
407
- if(!value.startsWith(condition.value)){
408
- conditionMatched = true
409
- }
410
- break
411
-
412
- case 'contains':
413
- if(value.indexOf(condition.value) >= 0){
414
- conditionMatched = true
415
- }
416
- break
417
-
418
- case 'notContains':
419
- if(value.indexOf(condition.value) < 0){
420
- conditionMatched = true
421
- }
422
- break
423
-
424
- case 'endsWith':
425
- if(value.endsWith(condition.value)){
426
- conditionMatched = true
427
- }
428
- break
429
-
430
- case 'notEndsWith':
431
- if(!value.endsWith(condition.value)){
432
- conditionMatched = true
433
- }
434
- break
435
-
436
- case 'none':
437
- conditionMatched = true
438
- break
439
-
440
- case 'regex':
441
- break
457
+ }
442
458
 
459
+ if(conditionMatched) break
443
460
  }
444
461
 
445
- if(conditionMatched) break
446
- }
447
-
448
- if(conditionMatched){
449
- appearanceClass = appearance.class
450
- break
462
+ if(conditionMatched){
463
+ appearanceClass = appearance.class
464
+ break
465
+ }
451
466
  }
452
467
  }
453
468
  }
@@ -675,4 +690,8 @@ export default{
675
690
  @apply inline-block m-1 rounded-md bg-orange-600 text-white px-2 text-sm;
676
691
  }
677
692
 
693
+ .total{
694
+ @apply px-3 uppercase font-bold;
695
+ }
696
+
678
697
  </style>
@@ -2,14 +2,17 @@ const groupBy = require("lodash/groupBy");
2
2
  const dayjs = require("dayjs");
3
3
  const {Op, literal, fn, DataTypes} = require("sequelize");
4
4
  const {ftWildcard} = require("./helpers");
5
+ const util = require("util");
5
6
 
6
7
  const getValue = (filter, opt) => {
7
8
 
8
9
  const { columns, withoutKey = false } = opt
9
- const { key, operator } = filter
10
+ const { key, operator, fn } = filter
10
11
  const keyColumns = groupBy(columns, 'key')
11
12
  const type = ((keyColumns[key] ?? [])[0] ?? {}).type
12
13
 
14
+ console.log('fn', fn)
15
+
13
16
  let whereObj = {}
14
17
 
15
18
  switch(type){
@@ -213,17 +216,26 @@ const getValue = (filter, opt) => {
213
216
  break
214
217
 
215
218
  case '<=':
216
- withoutKey ?
217
- whereObj = {
218
- [Op.lte]: [
219
- dayjs(filter.value).format('YYYY-MM-DD 23:59:59'),
220
- ]
221
- } :
222
- whereObj[key] = {
223
- [Op.lte]: [
224
- dayjs(filter.value).format('YYYY-MM-DD 23:59:59'),
225
- ]
226
- }
219
+ switch(fn){
220
+
221
+ case 'format_hour':
222
+ //console.log('<=', filter.value)
223
+ break
224
+
225
+ default:
226
+ withoutKey ?
227
+ whereObj = {
228
+ [Op.lte]: [
229
+ dayjs(filter.value).format('YYYY-MM-DD 23:59:59'),
230
+ ]
231
+ } :
232
+ whereObj[key] = {
233
+ [Op.lte]: [
234
+ dayjs(filter.value).format('YYYY-MM-DD 23:59:59'),
235
+ ]
236
+ }
237
+ }
238
+
227
239
  break
228
240
 
229
241
  case '=':
@@ -257,17 +269,25 @@ const getValue = (filter, opt) => {
257
269
  break
258
270
 
259
271
  case '>=':
260
- withoutKey ?
261
- whereObj = {
262
- [Op.gte]: [
263
- dayjs(filter.value).format('YYYY-MM-DD 00:00:00'),
264
- ]
265
- } :
266
- whereObj[key] = {
267
- [Op.gte]: [
268
- dayjs(filter.value).format('YYYY-MM-DD 00:00:00'),
269
- ]
270
- }
272
+ switch(fn) {
273
+
274
+ case 'format_hour':
275
+ //console.log('>=', filter.value)
276
+ break
277
+
278
+ default:
279
+ withoutKey ?
280
+ whereObj = {
281
+ [Op.gte]: [
282
+ dayjs(filter.value).format('YYYY-MM-DD 00:00:00'),
283
+ ]
284
+ } :
285
+ whereObj[key] = {
286
+ [Op.gte]: [
287
+ dayjs(filter.value).format('YYYY-MM-DD 00:00:00'),
288
+ ]
289
+ }
290
+ }
271
291
  break
272
292
 
273
293
  }
@@ -724,6 +744,12 @@ const pivotToSequelizeWhere = async (pivot, opt) => {
724
744
  if(!sortExists) order.push([ fn('DATE_FORMAT', literal(`${model.name}.${field}`), '%Y'), 'asc' ])
725
745
  break
726
746
 
747
+ case 'hour':
748
+ attributes.push([ fn('DATE_FORMAT', literal(`${model.name}.${field}`), '%H:00-%H:59'), row.key ])
749
+ group.push([ fn('DATE_FORMAT', literal(`${model.name}.${field}`), '%H:00-%H:59'), row.key ])
750
+ if(!sortExists) order.push([ fn('DATE_FORMAT', literal(`${model.name}.${field}`), '%H:00-%H:59'), 'asc' ])
751
+ break
752
+
727
753
  default:
728
754
  attributes.push([ literal(`${model.name}.${field}`), row.key ])
729
755
  group.push(`${model.name}.${field}`)
@@ -157,9 +157,29 @@ const generatePivotColumns = (preset, items) => {
157
157
 
158
158
  }
159
159
 
160
+ const generateTotalColumns = (preset, items) => {
161
+ if(!preset.pivot || !preset.pivot.enabled || !preset.pivot.useTotal || (items ?? []).length < 1) return
162
+
163
+ const totalItem = { _type:'totalRow' }
164
+
165
+ for(let item of items){
166
+ for(let key in item){
167
+ if(key.startsWith('_')){
168
+ if(!totalItem[key]){
169
+ totalItem[key] = 0
170
+ }
171
+ totalItem[key] += parseFloat(item[key])
172
+ }
173
+ }
174
+ }
175
+
176
+ items.push(totalItem)
177
+ }
178
+
160
179
  export {
161
180
  sortsFn,
162
181
  pickColumns,
163
182
  setupConfig,
164
- generatePivotColumns
183
+ generatePivotColumns,
184
+ generateTotalColumns
165
185
  }
@@ -490,6 +490,7 @@
490
490
  v-model="item.aggregrate"
491
491
  class="px-1 appearance-none bg-base-300 rounded-md border-[1px] border-text-50 outline-none"
492
492
  @change="apply()">
493
+ <option value="hour">Hour</option>
493
494
  <option value="date">Date</option>
494
495
  <option value="month">Month</option>
495
496
  <option value="year">Year</option>
@@ -578,6 +579,11 @@
578
579
  <PresetBarPivotColumnEdit ref="presetBarPivotColumnEdit" />
579
580
  </div>
580
581
 
582
+ <div class="flex flex-row items-center gap-3">
583
+ <label>Total</label>
584
+ <Switch v-model="presetPivot.useTotal" />
585
+ </div>
586
+
581
587
  </div>
582
588
 
583
589
  </div>