@mixd-id/web-scaffold 0.1.230406290 → 0.1.230406291
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 +1 -1
- package/src/components/Button.vue +5 -5
- package/src/components/Image.vue +1 -1
- package/src/components/List.vue +9 -4
- package/src/components/VirtualTable.vue +108 -5
- package/src/index.js +2 -1
- package/src/mixin/component.js +4 -1
- package/src/utils/preset-selector.js +9 -8
- package/src/utils/preset-selector.mjs +3 -0
- package/src/widgets/PresetBar.vue +18 -4
- package/src/widgets/PresetBarPivotColumnEdit.vue +172 -0
package/package.json
CHANGED
|
@@ -146,7 +146,7 @@ export default{
|
|
|
146
146
|
@apply flex items-center justify-center
|
|
147
147
|
}
|
|
148
148
|
.button:disabled{
|
|
149
|
-
|
|
149
|
+
@apply text-opacity-50;
|
|
150
150
|
}
|
|
151
151
|
.button:active{
|
|
152
152
|
@apply top-[1px] left-[1px] relative;
|
|
@@ -164,7 +164,7 @@ export default{
|
|
|
164
164
|
@apply bg-primary-600;
|
|
165
165
|
}
|
|
166
166
|
.button-primary:disabled{
|
|
167
|
-
@apply bg-primary-500
|
|
167
|
+
@apply bg-primary-500 top-0 left-0 cursor-not-allowed;
|
|
168
168
|
@apply top-0 left-0;
|
|
169
169
|
}
|
|
170
170
|
.button-primary *{
|
|
@@ -188,7 +188,7 @@ export default{
|
|
|
188
188
|
.button-outline:hover{
|
|
189
189
|
}
|
|
190
190
|
.button-outline:disabled{
|
|
191
|
-
@apply
|
|
191
|
+
@apply top-0 left-0 cursor-not-allowed;
|
|
192
192
|
@apply text-text border-primary-500;
|
|
193
193
|
}
|
|
194
194
|
.button-outline *{
|
|
@@ -214,7 +214,7 @@ export default{
|
|
|
214
214
|
@apply bg-primary-200 border-primary-200;
|
|
215
215
|
}
|
|
216
216
|
.button-secondary:disabled{
|
|
217
|
-
@apply bg-primary-100
|
|
217
|
+
@apply bg-primary-100 top-0 left-0 cursor-not-allowed;
|
|
218
218
|
}
|
|
219
219
|
.button-secondary *{
|
|
220
220
|
@apply text-text-500 fill-white;
|
|
@@ -238,7 +238,7 @@ export default{
|
|
|
238
238
|
@apply bg-red-600 border-red-600;
|
|
239
239
|
}
|
|
240
240
|
.button-red:disabled{
|
|
241
|
-
@apply bg-red-500 border-red-500
|
|
241
|
+
@apply bg-red-500 border-red-500 top-0 left-0 cursor-not-allowed;
|
|
242
242
|
}
|
|
243
243
|
.button-red *{
|
|
244
244
|
@apply text-white fill-white;
|
package/src/components/Image.vue
CHANGED
package/src/components/List.vue
CHANGED
|
@@ -120,7 +120,11 @@
|
|
|
120
120
|
</div>
|
|
121
121
|
</slot>
|
|
122
122
|
|
|
123
|
-
<
|
|
123
|
+
<div v-if="readyState === 3" class="flex-1 flex items-center justify-center">
|
|
124
|
+
<svg class="animate-spin" width="36" height="36" 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>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<VirtualTable v-else-if="presetView === 'table' || pivotEnabled"
|
|
124
128
|
ref="table"
|
|
125
129
|
:columns="columns"
|
|
126
130
|
class="flex-1 rounded-lg panel-400"
|
|
@@ -310,6 +314,7 @@ export default{
|
|
|
310
314
|
this.preset.columns = JSON.parse(JSON.stringify(this.config.columns))
|
|
311
315
|
}
|
|
312
316
|
|
|
317
|
+
this.readyState = 3
|
|
313
318
|
return this.socket.send(this.src, {
|
|
314
319
|
...this.preset,
|
|
315
320
|
itemsPerPage: this.data.itemsPerPage,
|
|
@@ -325,6 +330,7 @@ export default{
|
|
|
325
330
|
.catch(err => {
|
|
326
331
|
this.toast(err)
|
|
327
332
|
})
|
|
333
|
+
.finally(_ => this.readyState = 1)
|
|
328
334
|
}
|
|
329
335
|
return new Promise(resolve => resolve())
|
|
330
336
|
},
|
|
@@ -581,7 +587,7 @@ export default{
|
|
|
581
587
|
let [ kk, ...vv ] = column.key.split('-')
|
|
582
588
|
vv = vv.join('-')
|
|
583
589
|
|
|
584
|
-
if(![ 'count' ].includes(vv)){
|
|
590
|
+
if(![ 'count', 'countDistinct' ].includes(vv)){
|
|
585
591
|
|
|
586
592
|
const key = kk.substring(1)
|
|
587
593
|
const presetColumn = this.preset.columns.find(_ => _.key === key)
|
|
@@ -627,7 +633,7 @@ export default{
|
|
|
627
633
|
switch(e.code){
|
|
628
634
|
|
|
629
635
|
case 'Backquote':
|
|
630
|
-
this
|
|
636
|
+
this.togglePreset()
|
|
631
637
|
break
|
|
632
638
|
|
|
633
639
|
default:
|
|
@@ -850,7 +856,6 @@ export default{
|
|
|
850
856
|
|
|
851
857
|
.resize2{
|
|
852
858
|
@apply h-[5px] hover:bg-primary bg-text-50 cursor-n-resize absolute top-0 left-0 right-0 flex items-center justify-center;
|
|
853
|
-
@apply z-20;
|
|
854
859
|
}
|
|
855
860
|
|
|
856
861
|
.extClose{
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
<table :class="$style.table" ref="tableHead" :style="tableHeadStyle">
|
|
5
5
|
<thead>
|
|
6
6
|
<tr>
|
|
7
|
-
<th v-for="column in visibleColumns" :style="thStyle(column)"
|
|
7
|
+
<th v-for="column in visibleColumns" :style="thStyle(column)"
|
|
8
|
+
v-tooltip="`${column.label ? column.label : column.key}`">
|
|
8
9
|
<slot v-if="$slots['col-' + column.key]" :name="'col-' + column.key" :column="column"></slot>
|
|
9
10
|
<div v-else :class="headerColumnClass(column)">
|
|
10
|
-
<span>{{ column.label2 ? column.label2 : (column.label
|
|
11
|
+
<span>{{ column.label2 ? column.label2 : (column.label ?? column.key) }}</span>
|
|
11
12
|
</div>
|
|
12
13
|
<div :class="$style.separator" @mousedown="startResize($event, column)"></div>
|
|
13
14
|
</th>
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
@click="$emit('item-click', item, column)">
|
|
40
41
|
<slot v-if="$slots[column.key]" :name="column.key" :column="column" :item="item" :index="visibleStartIndex + index"></slot>
|
|
41
42
|
<slot v-else-if="$slots.default" name="default" :column="column" :item="item" :index="visibleStartIndex + index"></slot>
|
|
42
|
-
<div v-else :class="columnClass(column)" v-html="formatColumn(item, column)"></div>
|
|
43
|
+
<div v-else :class="columnClass(column, item)" v-html="formatColumn(item, column)"></div>
|
|
43
44
|
</td>
|
|
44
45
|
<td :class="$style.spacer"></td>
|
|
45
46
|
</tr>
|
|
@@ -322,7 +323,7 @@ export default{
|
|
|
322
323
|
window.addEventListener('mouseup', onMouseUp)
|
|
323
324
|
},
|
|
324
325
|
|
|
325
|
-
columnClass(column){
|
|
326
|
+
columnClass(column, item){
|
|
326
327
|
|
|
327
328
|
let align
|
|
328
329
|
if(!column.align){
|
|
@@ -333,9 +334,111 @@ export default{
|
|
|
333
334
|
}
|
|
334
335
|
}
|
|
335
336
|
|
|
337
|
+
let appearanceClass = ''
|
|
338
|
+
if(item && Array.isArray(column.appearances)){
|
|
339
|
+
|
|
340
|
+
let value
|
|
341
|
+
switch(column.type){
|
|
342
|
+
|
|
343
|
+
case 'number':
|
|
344
|
+
value = parseInt(item[column.key])
|
|
345
|
+
break
|
|
346
|
+
|
|
347
|
+
default:
|
|
348
|
+
value = (item[column.key] ?? '').toString()
|
|
349
|
+
break
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
for(let appearance of column.appearances){
|
|
353
|
+
|
|
354
|
+
let conditionMatched = true
|
|
355
|
+
for(let condition of appearance.conditions ?? []){
|
|
356
|
+
switch(condition.operator){
|
|
357
|
+
|
|
358
|
+
case '>':
|
|
359
|
+
if(value <= condition.value){
|
|
360
|
+
conditionMatched = false
|
|
361
|
+
}
|
|
362
|
+
break
|
|
363
|
+
|
|
364
|
+
case '>=':
|
|
365
|
+
if(value < condition.value){
|
|
366
|
+
conditionMatched = false
|
|
367
|
+
}
|
|
368
|
+
break
|
|
369
|
+
|
|
370
|
+
case '=':
|
|
371
|
+
if(value !== condition.value){
|
|
372
|
+
conditionMatched = false
|
|
373
|
+
}
|
|
374
|
+
break
|
|
375
|
+
|
|
376
|
+
case '<':
|
|
377
|
+
if(value >= condition.value){
|
|
378
|
+
conditionMatched = false
|
|
379
|
+
}
|
|
380
|
+
break
|
|
381
|
+
|
|
382
|
+
case '<=':
|
|
383
|
+
if(value > condition.value){
|
|
384
|
+
conditionMatched = false
|
|
385
|
+
}
|
|
386
|
+
break
|
|
387
|
+
|
|
388
|
+
case 'startsWith':
|
|
389
|
+
if(!value.startsWith(condition.value)){
|
|
390
|
+
conditionMatched = false
|
|
391
|
+
}
|
|
392
|
+
break
|
|
393
|
+
|
|
394
|
+
case 'notStartsWith':
|
|
395
|
+
if(value.startsWith(condition.value)){
|
|
396
|
+
conditionMatched = false
|
|
397
|
+
}
|
|
398
|
+
break
|
|
399
|
+
|
|
400
|
+
case 'contains':
|
|
401
|
+
if(value.indexOf(condition.value) < 0){
|
|
402
|
+
conditionMatched = false
|
|
403
|
+
}
|
|
404
|
+
break
|
|
405
|
+
|
|
406
|
+
case 'notContains':
|
|
407
|
+
if(value.indexOf(condition.value) >= 0){
|
|
408
|
+
conditionMatched = false
|
|
409
|
+
}
|
|
410
|
+
break
|
|
411
|
+
|
|
412
|
+
case 'endsWith':
|
|
413
|
+
if(!value.endsWith(condition.value)){
|
|
414
|
+
conditionMatched = false
|
|
415
|
+
}
|
|
416
|
+
break
|
|
417
|
+
|
|
418
|
+
case 'notEndsWith':
|
|
419
|
+
if(value.endsWith(condition.value)){
|
|
420
|
+
conditionMatched = false
|
|
421
|
+
}
|
|
422
|
+
break
|
|
423
|
+
|
|
424
|
+
case 'regex':
|
|
425
|
+
break
|
|
426
|
+
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if(!conditionMatched) break
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if(conditionMatched){
|
|
433
|
+
appearanceClass = appearance.class
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
336
438
|
return [
|
|
337
439
|
this.$style.tdDiv,
|
|
338
|
-
this.$style['align-' + align]
|
|
440
|
+
this.$style['align-' + align],
|
|
441
|
+
appearanceClass
|
|
339
442
|
]
|
|
340
443
|
.join(' ')
|
|
341
444
|
},
|
package/src/index.js
CHANGED
|
@@ -332,7 +332,7 @@ export default{
|
|
|
332
332
|
tooltip.classList.add('active')
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
|
-
},
|
|
335
|
+
}, 1000)
|
|
336
336
|
el.setAttribute('data-tooltip-open', true)
|
|
337
337
|
})
|
|
338
338
|
|
|
@@ -565,6 +565,7 @@ export default{
|
|
|
565
565
|
app.component('SvgSetting', defineAsyncComponent(() => import("./widgets/SvgSetting.vue")))
|
|
566
566
|
app.component('PresetBar', defineAsyncComponent(() => import("./widgets/PresetBar.vue")))
|
|
567
567
|
app.component('PresetSelector', defineAsyncComponent(() => import("./widgets/PresetSelector.vue")))
|
|
568
|
+
app.component('PresetBarPivotColumnEdit', defineAsyncComponent(() => import("./widgets/PresetBarPivotColumnEdit.vue")))
|
|
568
569
|
app.component('LogViewer', defineAsyncComponent(() => import("./widgets/LogViewer.vue")))
|
|
569
570
|
app.component('ColumnSelector', defineAsyncComponent(() => import("./widgets/ColumnSelector.vue")))
|
|
570
571
|
},
|
package/src/mixin/component.js
CHANGED
|
@@ -737,33 +737,34 @@ const pivotToSequelizeWhere = async (pivot, opt) => {
|
|
|
737
737
|
|
|
738
738
|
const sortKeyToOrders = {} // Helper to determine group ordering
|
|
739
739
|
for(let value of pivot.values){
|
|
740
|
+
const valueKey = model.rawAttributes[value.key].field
|
|
740
741
|
|
|
741
742
|
switch(value.aggregrate){
|
|
742
743
|
|
|
743
744
|
case 'sum':
|
|
744
|
-
attributes.push([ fn('SUM', literal(`${model.name}.${
|
|
745
|
+
attributes.push([ fn('SUM', literal(`${model.name}.${valueKey}`)), `_${value.key}-${value.aggregrate}` ])
|
|
745
746
|
break
|
|
746
747
|
|
|
747
748
|
case 'avg':
|
|
748
|
-
attributes.push([ fn('AVG', literal(`${model.name}.${
|
|
749
|
+
attributes.push([ fn('AVG', literal(`${model.name}.${valueKey}`)), `_${value.key}-${value.aggregrate}` ])
|
|
749
750
|
break
|
|
750
751
|
|
|
751
752
|
case 'min':
|
|
752
|
-
attributes.push([ fn('MIN', literal(`${model.name}.${
|
|
753
|
+
attributes.push([ fn('MIN', literal(`${model.name}.${valueKey}`)), `_${value.key}-${value.aggregrate}` ])
|
|
753
754
|
break
|
|
754
755
|
|
|
755
756
|
case 'max':
|
|
756
|
-
attributes.push([ fn('MAX', literal(`${model.name}.${
|
|
757
|
+
attributes.push([ fn('MAX', literal(`${model.name}.${valueKey}`)), `_${value.key}-${value.aggregrate}` ])
|
|
757
758
|
break
|
|
758
759
|
|
|
759
760
|
case 'countDistinct':
|
|
760
|
-
attributes.push([ literal(`COUNT(DISTINCT ${model.name}.${
|
|
761
|
-
sortKeyToOrders[`_${value.key}-${value.aggregrate}`] = literal(`COUNT(DISTINCT ${model.name}.${
|
|
761
|
+
attributes.push([ literal(`COUNT(DISTINCT ${model.name}.${valueKey})`), `_${value.key}-${value.aggregrate}` ])
|
|
762
|
+
sortKeyToOrders[`_${value.key}-${value.aggregrate}`] = literal(`COUNT(DISTINCT ${model.name}.${valueKey})`)
|
|
762
763
|
break
|
|
763
764
|
|
|
764
765
|
case 'count':
|
|
765
|
-
attributes.push([ fn('COUNT', literal(`${model.name}.${
|
|
766
|
-
sortKeyToOrders[`_${value.key}-${value.aggregrate}`] = fn('COUNT', literal(`${model.name}.${
|
|
766
|
+
attributes.push([ fn('COUNT', literal(`${model.name}.${valueKey}`)), `_${value.key}-${value.aggregrate}` ])
|
|
767
|
+
sortKeyToOrders[`_${value.key}-${value.aggregrate}`] = fn('COUNT', literal(`${model.name}.${valueKey}`))
|
|
767
768
|
break
|
|
768
769
|
|
|
769
770
|
default:
|
|
@@ -139,6 +139,9 @@ const generatePivotColumns = (preset, items) => {
|
|
|
139
139
|
label,
|
|
140
140
|
label2: (((tableColumns[k1] ?? {}).label ?? '') + ': ' + label).trim(),
|
|
141
141
|
type: 'number',
|
|
142
|
+
appearances: [
|
|
143
|
+
{ class:"text-primary cursor-pointer", conditions:[ { operator:'none' } ] }
|
|
144
|
+
]
|
|
142
145
|
})
|
|
143
146
|
}
|
|
144
147
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
16
|
<div class="p-3">
|
|
17
|
-
<div class="
|
|
17
|
+
<div class="px-2">
|
|
18
18
|
<label class="text-text-300">Presets</label>
|
|
19
19
|
</div>
|
|
20
20
|
<div class="flex flex-col divide-y divide-text-50 bg-base-500 border-[1px] border-text-50 overflow-hidden rounded-lg">
|
|
@@ -95,7 +95,8 @@
|
|
|
95
95
|
body-class="divide-y divide-text-50 rounded-lg border-[1px] border-text-50 bg-base-300"
|
|
96
96
|
@reorder="(from, to) => { presetColumns.splice(to, 0, presetColumns.splice(from, 1)[0]); }">
|
|
97
97
|
<template v-slot="{ item }">
|
|
98
|
-
<div v-if="!item.key.startsWith('_') || (item.key.startsWith('_') && (preset.pivot && preset.pivot.enabled))"
|
|
98
|
+
<div v-if="!item.key.startsWith('_') || (item.key.startsWith('_') && (preset.pivot && preset.pivot.enabled))"
|
|
99
|
+
class="flex flex-row items-center gap-3 px-3 p-1 hover:bg-primary-100">
|
|
99
100
|
<div data-reorder>
|
|
100
101
|
<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>
|
|
101
102
|
</div>
|
|
@@ -103,7 +104,9 @@
|
|
|
103
104
|
<div>
|
|
104
105
|
<Checkbox v-model="item.visible" default="true" />
|
|
105
106
|
</div>
|
|
106
|
-
|
|
107
|
+
<Textbox v-model="item.label2" :placeholder="item.label"
|
|
108
|
+
class="border-none bg-transparent" :class="$style.columnTextbox"
|
|
109
|
+
item-class="p-1 px-0" />
|
|
107
110
|
</div>
|
|
108
111
|
</div>
|
|
109
112
|
</template>
|
|
@@ -558,14 +561,21 @@
|
|
|
558
561
|
<div data-reorder>
|
|
559
562
|
<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>
|
|
560
563
|
</div>
|
|
561
|
-
<Textbox class="flex-1 border-none" v-model="item.label2" :placeholder="item.label"
|
|
564
|
+
<Textbox class="flex-1 border-none" :class="$style.columnTextbox" v-model="item.label2" :placeholder="item.label"
|
|
562
565
|
item-class="p-1"/>
|
|
566
|
+
<button type="button" v-if="[ 'number' ].includes(item.type)" @click="">
|
|
567
|
+
<svg width="13" height="13" :class="(item.appearances ?? []).length > 0 ? 'fill-primary' : 'fill-text-300 hover:fill-primary'"
|
|
568
|
+
@click="$refs.presetBarPivotColumnEdit.open(item, next => { Object.assign(item, next); apply() })"
|
|
569
|
+
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="M176 0h-128C21.49 0 0 21.49 0 48v128C0 202.5 21.49 224 48 224h128C202.5 224 224 202.5 224 176v-128C224 21.49 202.5 0 176 0zM176 288h-128C21.49 288 0 309.5 0 336v128C0 490.5 21.49 512 48 512h128C202.5 512 224 490.5 224 464v-128C224 309.5 202.5 288 176 288zM464 0h-128C309.5 0 288 21.49 288 48v128C288 202.5 309.5 224 336 224h128C490.5 224 512 202.5 512 176v-128C512 21.49 490.5 0 464 0zM488 376h-64v-64C424 298.8 413.3 288 400 288s-24 10.75-24 24v64h-64c-13.25 0-24 10.75-24 24s10.75 24 24 24h64v64c0 13.25 10.75 24 24 24s24-10.75 24-24v-64h64c13.25 0 24-10.75 24-24S501.3 376 488 376z"/></svg>
|
|
570
|
+
</button>
|
|
563
571
|
<button type="button" @click="presetPivot.columns.splice(index, 1); presetPivot.manualColumns = true; apply()">
|
|
564
572
|
<svg width="16" height="16" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
|
|
565
573
|
</button>
|
|
566
574
|
</div>
|
|
567
575
|
</template>
|
|
568
576
|
</ListItem>
|
|
577
|
+
|
|
578
|
+
<PresetBarPivotColumnEdit ref="presetBarPivotColumnEdit" />
|
|
569
579
|
</div>
|
|
570
580
|
|
|
571
581
|
</div>
|
|
@@ -846,4 +856,8 @@ export default{
|
|
|
846
856
|
@apply flex flex-col relative;
|
|
847
857
|
}
|
|
848
858
|
|
|
859
|
+
.columnTextbox input::placeholder{
|
|
860
|
+
@apply text-text;
|
|
861
|
+
}
|
|
862
|
+
|
|
849
863
|
</style>
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Modal ref="modal" :hash="hash" :state="state" width="480" height="480">
|
|
3
|
+
<template v-slot:head>
|
|
4
|
+
<div class="relative p-6">
|
|
5
|
+
<h3>{{ obj.label }}</h3>
|
|
6
|
+
<div class="absolute top-0 right-0 p-2">
|
|
7
|
+
<button type="button" class="p-2" @click="close">
|
|
8
|
+
<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">
|
|
9
|
+
<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"/>
|
|
10
|
+
</svg>
|
|
11
|
+
</button>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
<template v-slot:foot>
|
|
16
|
+
<div class="p-6">
|
|
17
|
+
<Button class="w-[100px]" @click="apply">Apply</Button>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
<div class="flex-1 p-6 flex flex-col gap-4">
|
|
21
|
+
|
|
22
|
+
<div class="flex flex-col gap-1">
|
|
23
|
+
<div class="flex flex-row gap-2">
|
|
24
|
+
<label class="text-text-400">Appearances</label>
|
|
25
|
+
<button type="button" class="text-primary" @click="appearances.push({ conditions:[{}], class:'' })">
|
|
26
|
+
<svg width="16" height="16" class="fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"/></svg>
|
|
27
|
+
</button>
|
|
28
|
+
</div>
|
|
29
|
+
<ListItem :items="appearances"
|
|
30
|
+
class="bg-transparent"
|
|
31
|
+
@reorder="(from, to) => { appearances.splice(to, 0, appearances.splice(from, 1)[0]); }"
|
|
32
|
+
container-class="flex flex-col gap-1">
|
|
33
|
+
<template v-slot="{ item, index }">
|
|
34
|
+
<div class="flex flex-row items-center gap-3">
|
|
35
|
+
<div class="flex-1 flex flex-col gap-1">
|
|
36
|
+
<div v-for="condition in item.conditions" class="flex flex-row gap-1">
|
|
37
|
+
<Dropdown v-model="condition.operator" :class="condition.operator === 'none' ? 'w-[200px]' : 'w-[100px]'">
|
|
38
|
+
<option v-for="op in operators" :value="op.value">{{ op.text }}</option>
|
|
39
|
+
<option value="none">No Condition</option>
|
|
40
|
+
</Dropdown>
|
|
41
|
+
<Textbox v-if="condition.operator !== 'none'" v-model.numberconditions="condition.value" class="w-[100px]"/>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
<div :class="item.class" class="px-2">
|
|
45
|
+
Sample
|
|
46
|
+
</div>
|
|
47
|
+
<div>
|
|
48
|
+
<Dropdown class="w-[120px]" v-model="item.class">
|
|
49
|
+
<option value="text-primary cursor-pointer">Default</option>
|
|
50
|
+
<option value="bg-red-100 text-red-600">Red 1</option>
|
|
51
|
+
<option value="bg-red-200 text-red-600">Red 2</option>
|
|
52
|
+
<option value="bg-red-300 text-red-600">Red 3</option>
|
|
53
|
+
<option value="bg-red-400 text-white">Red 4</option>
|
|
54
|
+
<option value="bg-red-500 text-white">Red 5</option>
|
|
55
|
+
<option value="bg-green-100 text-green-700">Green 1</option>
|
|
56
|
+
<option value="bg-green-200 text-green-700">Green 2</option>
|
|
57
|
+
<option value="bg-green-300 text-green-700">Green 3</option>
|
|
58
|
+
<option value="bg-green-400 text-white">Green 4</option>
|
|
59
|
+
<option value="bg-green-500 border-[1px] border-green-600 text-white">Green 5</option>
|
|
60
|
+
<option value="text-primary underline cursor-pointer">Underline</option>
|
|
61
|
+
</Dropdown>
|
|
62
|
+
</div>
|
|
63
|
+
<div>
|
|
64
|
+
<button type="button" @click="appearances.splice(index, 1)">
|
|
65
|
+
<svg width="16" height="16" class="fill-text-300 hover:fill-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
|
|
66
|
+
</button>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</template>
|
|
70
|
+
</ListItem>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</Modal>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<script>
|
|
77
|
+
|
|
78
|
+
export default{
|
|
79
|
+
|
|
80
|
+
emits: [ 'apply' ],
|
|
81
|
+
|
|
82
|
+
inject: [ 'socketEmit2' ],
|
|
83
|
+
|
|
84
|
+
props: {
|
|
85
|
+
|
|
86
|
+
hash: String,
|
|
87
|
+
state: Boolean
|
|
88
|
+
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
computed: {
|
|
92
|
+
|
|
93
|
+
appearances(){
|
|
94
|
+
if(!Array.isArray(this.obj.appearances)){
|
|
95
|
+
this.obj.appearances = []
|
|
96
|
+
}
|
|
97
|
+
return this.obj.appearances
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
operators(){
|
|
101
|
+
|
|
102
|
+
let operators = []
|
|
103
|
+
|
|
104
|
+
switch(this.obj?.type){
|
|
105
|
+
|
|
106
|
+
case 'number':
|
|
107
|
+
operators = [
|
|
108
|
+
{ value:">", text:">" },
|
|
109
|
+
{ value:">=", text:">=" },
|
|
110
|
+
{ value:"=", text:"=" },
|
|
111
|
+
{ value:"<=", text:"<=" },
|
|
112
|
+
{ value:"<", text:"<" }
|
|
113
|
+
]
|
|
114
|
+
break
|
|
115
|
+
|
|
116
|
+
default:
|
|
117
|
+
operators = [
|
|
118
|
+
{ value:"contains", text:"Contains" },
|
|
119
|
+
{ value:"startsWith", text:"Starts With" },
|
|
120
|
+
{ value:"endsWith", text:"Ends With" },
|
|
121
|
+
{ value:"notContains", text:"Not Contains" },
|
|
122
|
+
{ value:"notStartsWith", text:"Not Starts With" },
|
|
123
|
+
{ value:"notEndsWith", text:"Not StartEnds With" },
|
|
124
|
+
{ value:"regex", text:"Match Pattern" }
|
|
125
|
+
]
|
|
126
|
+
break
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return operators
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
data(){
|
|
135
|
+
return {
|
|
136
|
+
obj: null,
|
|
137
|
+
callback: null
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
methods: {
|
|
142
|
+
|
|
143
|
+
apply(){
|
|
144
|
+
if(typeof this.callback === 'function')
|
|
145
|
+
this.callback(this.obj)
|
|
146
|
+
this.$emit('apply', this.obj)
|
|
147
|
+
this.close()
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
open(obj, callback){
|
|
151
|
+
this.obj = JSON.parse(JSON.stringify(obj))
|
|
152
|
+
this.callback = callback
|
|
153
|
+
this.$refs.modal.open()
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
close(){
|
|
157
|
+
this.$refs.modal.close()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
</script>
|
|
165
|
+
|
|
166
|
+
<style module>
|
|
167
|
+
|
|
168
|
+
.comp{
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
</style>
|