@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.230406290",
4
+ "version": "0.1.230406291",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -146,7 +146,7 @@ export default{
146
146
  @apply flex items-center justify-center
147
147
  }
148
148
  .button:disabled{
149
- @apply opacity-60;
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 opacity-50 top-0 left-0 cursor-not-allowed;
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 opacity-50 top-0 left-0 cursor-not-allowed;
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 opacity-50 top-0 left-0 cursor-not-allowed;
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 opacity-50 top-0 left-0 cursor-not-allowed;
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;
@@ -288,7 +288,7 @@ export default{
288
288
  }
289
289
 
290
290
  .img{
291
- @apply object-contain w-full h-full;
291
+ @apply w-full h-full;
292
292
  }
293
293
 
294
294
  .editArea{
@@ -120,7 +120,11 @@
120
120
  </div>
121
121
  </slot>
122
122
 
123
- <VirtualTable v-if="presetView === 'table' || pivotEnabled"
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.$refs.contextMenu.open(this.$refs.title)
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 ? column.label : column.key) }}</span>
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
- }, 1300)
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
  },
@@ -61,7 +61,10 @@ export const componentMixin = {
61
61
  itemRatio: Array,
62
62
 
63
63
  containerClass: String,
64
- itemClass: String,
64
+ itemClass: {
65
+ type: String,
66
+ default: 'bg-contain'
67
+ },
65
68
 
66
69
  htmlText: String,
67
70
 
@@ -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}.${value.key}`)), `_${value.key}-${value.aggregrate}` ])
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}.${value.key}`)), `_${value.key}-${value.aggregrate}` ])
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}.${value.key}`)), `_${value.key}-${value.aggregrate}` ])
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}.${value.key}`)), `_${value.key}-${value.aggregrate}` ])
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}.${value.key})`), `_${value.key}-${value.aggregrate}` ])
761
- sortKeyToOrders[`_${value.key}-${value.aggregrate}`] = literal(`COUNT(DISTINCT ${model.name}.${value.key})`)
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}.${value.key}`)), `_${value.key}-${value.aggregrate}` ])
766
- sortKeyToOrders[`_${value.key}-${value.aggregrate}`] = fn('COUNT', literal(`${model.name}.${value.key}`))
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="p-2">
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))" class="flex flex-row items-center gap-3 px-3 p-2 hover:bg-primary-100">
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
- {{ item.label2 ? item.label2 : (item.label ? item.label : item.key) }}
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>