@mixd-id/web-scaffold 0.1.240411027 → 0.1.240411029

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.240411027",
4
+ "version": "0.1.240411029",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -177,6 +177,17 @@ export default {
177
177
  left = Math.round(rect.x)
178
178
  top = Math.round(rect.y + rect.height)
179
179
  transformOrigin = 'top left'
180
+ maxHeight = window.innerHeight - top - 16
181
+ this.transition = 'slidedown'
182
+
183
+ if(top > window.innerHeight * .8){
184
+ top = null
185
+ bottom = window.innerHeight - rect.top + 8
186
+ transformOrigin = 'bottom'
187
+ maxHeight = Math.round(rect.top - 16)
188
+ console.log('maxHeight', maxHeight)
189
+ this.transition = 'slideup'
190
+ }
180
191
  break
181
192
  }
182
193
 
@@ -234,7 +245,7 @@ export default {
234
245
 
235
246
  .contextMenu{
236
247
  @apply fixed bg-base-300 min-w-[150px] overflow-y-auto rounded-xl z-50;
237
- @apply whitespace-nowrap shadow-2xl border-[1px] border-text-50 mt-[1px];
248
+ @apply whitespace-nowrap shadow-2xl border-[1px] border-text-200 mt-[1px];
238
249
  }
239
250
 
240
251
  @media screen and (min-width: 640px){
@@ -0,0 +1,88 @@
1
+ <template>
2
+ <ContextMenu ref="contextMenu" class="mt-1">
3
+ <div class="flex flex-col min-w-[200px]">
4
+
5
+ <div class="p-1 sticky top-0 bg-base-500" @click.stop>
6
+ <Textbox :clearable="true" @clear="search = ''" placeholder="Search or add..." v-model="search" />
7
+ </div>
8
+
9
+ <button v-if="viewedItems.length > 0" v-for="text in viewedItems" class="w-full p-3 text-left flex flex-row menu-item"
10
+ @click="select(text)">
11
+ {{ text }}
12
+ </button>
13
+
14
+ <button v-else-if="search.length > 0" type="button" class="w-full p-3 text-primary" @click="add(search)">
15
+ Tambah {{ search }}
16
+ </button>
17
+
18
+ </div>
19
+ </ContextMenu>
20
+ </template>
21
+
22
+ <script>
23
+ import ContextMenu from "./ContextMenu.vue";
24
+
25
+ export default{
26
+ components: {ContextMenu},
27
+
28
+ emits: [ 'select' ],
29
+
30
+ props: {
31
+ items: Array
32
+ },
33
+
34
+ computed: {
35
+
36
+ viewedItems(){
37
+ return (this.items ?? [])
38
+ .filter(text => {
39
+ return text.toLowerCase().includes(this.search.toLowerCase())
40
+ })
41
+ .sort((a, b) => {
42
+ return a.toLowerCase().localeCompare(b.toLowerCase())
43
+ })
44
+ }
45
+
46
+ },
47
+
48
+ data(){
49
+ return {
50
+ search: '',
51
+ cb: null
52
+ }
53
+ },
54
+
55
+ methods: {
56
+
57
+ add(text){
58
+ if(`${text}`.length < 1) return
59
+
60
+ this.items.push(text)
61
+ this.select(text)
62
+ },
63
+
64
+ select(text){
65
+ this.$emit('select', text)
66
+ if(typeof this.cb === 'function')
67
+ this.cb(text)
68
+ },
69
+
70
+ open(caller, cb){
71
+ this.search = ''
72
+ this.cb = cb
73
+ this.$refs.contextMenu.open(caller)
74
+ }
75
+
76
+ }
77
+
78
+ }
79
+
80
+ </script>
81
+
82
+ <style module>
83
+
84
+ .comp{
85
+
86
+ }
87
+
88
+ </style>
@@ -88,7 +88,8 @@
88
88
  </div>
89
89
 
90
90
  <div v-else class="flex flex-row gap-2">
91
- <Dropdown v-model="value.operator" class="w-[100px]"
91
+ <Dropdown v-model="value.operator"
92
+ :class="![ 'notEmpty' ].includes(value.operator) ? 'w-[100px]' : 'w-full'"
92
93
  :readonly="readonly"
93
94
  @change="apply">
94
95
  <option value="eq">Equal</option>
@@ -100,8 +101,10 @@
100
101
  <option value="in">Multiple with comma</option>
101
102
  <option value="notIn">Except with comma</option>
102
103
  <option value="regex">Regex</option>
104
+ <option value="notEmpty">Not Empty</option>
103
105
  </Dropdown>
104
- <Textbox v-model="value.value"
106
+ <Textbox v-if="![ 'notEmpty' ].includes(value.operator)"
107
+ v-model="value.value"
105
108
  :readonly="readonly"
106
109
  class="flex-1"
107
110
  @keyup.enter="apply"
@@ -74,6 +74,7 @@ export default{
74
74
  this.$style.textbox,
75
75
  this.$style['state-' + this.computedState],
76
76
  this.readonly ? this.$style.readonly : '',
77
+ this.disabled ? this.$style.disabled : '',
77
78
  this.isActive && !this.readonly ? this.$style.active : '',
78
79
  this.align ? this.$style['align-' + this.align] : '',
79
80
  this.size ? this.$style['size-' + this.size] : ''
@@ -186,7 +187,6 @@ export default{
186
187
  }
187
188
 
188
189
  .textbox.readonly{
189
- @apply bg-text-50;
190
190
  }
191
191
 
192
192
  .size-sm input{ @apply text-sm; }
package/src/index.js CHANGED
@@ -489,6 +489,7 @@ export default{
489
489
  app.component('MultiDropdown', defineAsyncComponent(() => import("./components/MultiDropdown.vue")))
490
490
  app.component('Carousel', defineAsyncComponent(() => import("./components/Carousel.vue")))
491
491
  app.component('ContextMenu', defineAsyncComponent(() => import("./components/ContextMenu.vue")))
492
+ app.component('ListContextMenu', defineAsyncComponent(() => import("./components/ListContextMenu.vue")))
492
493
  app.component('FAQ', defineAsyncComponent(() => import("./widgets/FAQ.vue")))
493
494
  app.component('Flex', defineAsyncComponent(() => import("./components/Flex.vue")))
494
495
  app.component('Grid', defineAsyncComponent(() => import("./components/Grid.vue")))
@@ -560,34 +560,37 @@ const arrayRemove = (arr, items, opt = {}) => {
560
560
  }
561
561
  }
562
562
 
563
- const arrayUnshift = (arr, item, opt = {}) => {
563
+ const arrayUnshift = (arr, items, opt = { update:true }) => {
564
564
  if(!Array.isArray(arr)) return
565
+ if(!Array.isArray(items)) items = [ items ]
565
566
  if(!opt.key){
566
- opt.key = item && item.uid ? 'uid' : 'id'
567
+ opt.key = items[0] && items[0].uid ? 'uid' : 'id'
567
568
  }
568
569
 
569
- opt = Object.assign({ key:"id", highlight:false }, opt)
570
+ if(!Array.isArray(opt.key)){
571
+ opt.key = [ opt.key ]
572
+ }
570
573
 
571
- const index = arr.findIndex((_) => _[opt.key] === item[opt.key])
572
- if(index >= 0){
574
+ for(let item of items){
575
+ if(!item) continue
573
576
 
574
- const keys = []
575
- for(let key in item){
576
- if(!(key in arr[index]) || arr[index][key] !== item[key]){
577
- keys.push(key)
577
+ const index = arr.findIndex((_) => {
578
+ for(let key of opt.key){
579
+ if(_[key] !== item[key]){
580
+ return false
581
+ }
578
582
  }
579
- }
583
+ return true
584
+ })
580
585
 
581
- if(opt.highlight){
582
- item._highlight = keys
586
+ if(index >= 0){
587
+ if(opt.update !== false){
588
+ Object.assign(arr[index], item)
589
+ }
583
590
  }
584
- Object.assign(arr[index], item)
585
- }
586
- else{
587
- if(opt.highlight){
588
- item._highlight = true
591
+ else{
592
+ arr.unshift(item)
589
593
  }
590
- arr.unshift(item)
591
594
  }
592
595
  }
593
596
 
@@ -307,6 +307,17 @@ const getValue = (filter, opt) => {
307
307
  }
308
308
  break
309
309
 
310
+ case 'notEmpty':
311
+ whereObj = {
312
+ [key]:{
313
+ [Op.or]: [
314
+ { [Op.ne]: null },
315
+ { [Op.ne]: '' }
316
+ ]
317
+ }
318
+ }
319
+ break
320
+
310
321
  case 'in':
311
322
  withoutKey ?
312
323
  whereObj = {
@@ -676,6 +687,17 @@ const filtersToSequelizeWhere = async(filters, opt) => {
676
687
  }
677
688
  break
678
689
 
690
+ case 'notEmpty':
691
+ whereObj = {
692
+ [key]:{
693
+ [Op.or]: [
694
+ { [Op.ne]: null },
695
+ { [Op.ne]: '' }
696
+ ]
697
+ }
698
+ }
699
+ break
700
+
679
701
  case 'in':
680
702
  whereObj = {
681
703
  [key]:{
@@ -307,6 +307,17 @@ const getValue = (filter, opt) => {
307
307
  }
308
308
  break
309
309
 
310
+ case 'notEmpty':
311
+ whereObj = {
312
+ [key]:{
313
+ [Op.or]: [
314
+ { [Op.ne]: null },
315
+ { [Op.ne]: '' }
316
+ ]
317
+ }
318
+ }
319
+ break
320
+
310
321
  case 'in':
311
322
  withoutKey ?
312
323
  whereObj = {
@@ -676,6 +687,17 @@ const filtersToSequelizeWhere = async(filters, opt) => {
676
687
  }
677
688
  break
678
689
 
690
+ case 'notEmpty':
691
+ whereObj = {
692
+ [key]:{
693
+ [Op.or]: [
694
+ { [Op.ne]: null },
695
+ { [Op.ne]: '' }
696
+ ]
697
+ }
698
+ }
699
+ break
700
+
679
701
  case 'in':
680
702
  whereObj = {
681
703
  [key]:{