@mixd-id/web-scaffold 0.1.230406331 → 0.1.230406333

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.230406331",
4
+ "version": "0.1.230406333",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -120,57 +120,77 @@
120
120
  </div>
121
121
  </slot>
122
122
 
123
- <div v-if="readyState === 2" 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>
123
+ <div class="flex-1 flex" ref="content">
124
+ <div v-if="readyState === 2" class="flex-1 flex items-center justify-center">
125
+ <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>
126
+ </div>
126
127
 
127
- <div v-else-if="presetView === 'table' || pivotEnabled" class="flex-1 flex" :class="pivotEnabled ? 'p-3 panel-400 md:p-0' : ''">
128
- <VirtualTable
129
- ref="table"
130
- :columns="columns"
131
- class="flex-1 rounded-lg panel-400"
132
- :items="data.items"
133
- :enumCache="enumCache"
134
- @scroll-end="loadNext"
135
- @item-click="onTableItemClick">
136
-
137
- <template v-for="(_, slot) in headerSlots" #[slot]="{ item, index }">
138
- <div :class="getHeader(slot.replace('col-', ''))">
139
- <slot :name="slot" :item="item" :index="index"></slot>
140
- </div>
141
- </template>
128
+ <div v-else-if="presetView === 'table' || pivotEnabled" class="flex-1 flex" :class="pivotEnabled ? 'p-3 panel-400 md:p-0' : ''">
129
+ <VirtualTable
130
+ ref="table"
131
+ :columns="columns"
132
+ class="flex-1 rounded-lg panel-400"
133
+ :items="data.items"
134
+ :enumCache="enumCache"
135
+ @scroll-end="loadNext"
136
+ @item-click="onTableItemClick">
137
+
138
+ <template v-for="(_, slot) in headerSlots" #[slot]="{ item, index }">
139
+ <div :class="getHeader(slot.replace('col-', ''))">
140
+ <slot :name="slot" :item="item" :index="index"></slot>
141
+ </div>
142
+ </template>
142
143
 
143
- <template v-for="(_, slot) in contentSlots" #[slot]="{ item, index }">
144
- <slot :name="slot" :item="item" :index="index"></slot>
145
- </template>
144
+ <template v-for="(_, slot) in contentSlots" #[slot]="{ item, index }">
145
+ <slot :name="slot" :item="item" :index="index"></slot>
146
+ </template>
147
+
148
+ <template #end>
149
+ <div v-if="data?.hasNext" class="flex justify-center p-3">
150
+ <svg v-if="readyState === 4" class="animate-spin aspect-square w-[14px] h-[14px] fill-text-300" 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>
151
+ <button v-else type="button" class="text-text-300" @click="loadNext()">
152
+ {{ $t('Load More' )}}
153
+ </button>
154
+ </div>
155
+ </template>
146
156
 
147
- </VirtualTable>
148
- </div>
157
+ </VirtualTable>
158
+ </div>
149
159
 
150
- <VirtualGrid v-else-if="presetView === 'grid'"
151
- ref="grid"
152
- :items="dataItems"
153
- :column="computedGridColumn"
154
- :class="gridClass"
155
- @scroll-end="loadNext"
156
- :container-class="`${gridContainerClass}`"
157
- :config="config">
158
- <template #item="{ item }">
159
- <slot name="gridItem" :item="item" :enumCache="enumCache" :getEnumText="getEnumText">
160
- <div class="flex flex-row panel-400 rounded-lg overflow-hidden md:rounded-lg overflow-hidden p-3 gap-3">
161
- <div>
162
- <Image :src="item.imageUrl" class="bg-text-50 w-[64px] h-[64px] rounded-lg" />
163
- </div>
164
- <div class="flex-1 flex flex-col leading-tight">
165
- <small>{{ item.code }}</small>
166
- <strong>{{ item.name }}</strong>
160
+ <VirtualGrid v-else-if="presetView === 'grid'"
161
+ ref="grid"
162
+ :items="dataItems"
163
+ :column="computedGridColumn"
164
+ :class="gridClass"
165
+ @scroll-end="loadNext"
166
+ :container-class="`${gridContainerClass}`"
167
+ :config="config">
168
+ <template #item="{ item }">
169
+ <slot name="gridItem" :item="item" :enumCache="enumCache" :getEnumText="getEnumText">
170
+ <div class="flex flex-row panel-400 rounded-lg overflow-hidden md:rounded-lg overflow-hidden p-3 gap-3">
171
+ <div>
172
+ <Image :src="item.imageUrl" class="bg-text-50 w-[64px] h-[64px] rounded-lg" />
173
+ </div>
174
+ <div class="flex-1 flex flex-col leading-tight">
175
+ <small>{{ item.code }}</small>
176
+ <strong>{{ item.name }}</strong>
177
+ </div>
167
178
  </div>
179
+ </slot>
180
+ </template>
181
+
182
+ <template #end>
183
+ <div v-if="data?.hasNext" class="flex justify-center p-3">
184
+ <svg v-if="readyState === 4" class="animate-spin aspect-square w-[14px] h-[14px] fill-text-300" 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>
185
+ <button v-else type="button" class="text-text-300" @click="loadNext()">
186
+ {{ $t('Load More' )}}
187
+ </button>
168
188
  </div>
169
- </slot>
170
- </template>
171
- </VirtualGrid>
189
+ </template>
190
+ </VirtualGrid>
172
191
 
173
- <PresetSelector ref="presetSelector" :config="config" @select="load" />
192
+ <PresetSelector ref="presetSelector" :config="config" @select="load" />
193
+ </div>
174
194
  </div>
175
195
 
176
196
  <div v-if="extBar.open && pivotEnabled"
@@ -300,6 +320,14 @@ export default{
300
320
 
301
321
  methods: {
302
322
 
323
+ calcItemsPerPage(){
324
+
325
+ if(this.$refs.content){
326
+ this.data.itemsPerPage = Math.round((this.$refs.content.clientHeight - 36) / 36) + 3
327
+ }
328
+
329
+ },
330
+
303
331
  getEnumText(key, value){
304
332
 
305
333
  let enumText
@@ -361,6 +389,7 @@ export default{
361
389
 
362
390
  //console.log('last id', this.dataItems[this.dataItems.length - 1].id)
363
391
 
392
+ this.readyState = 4
364
393
  this.socket.send(this.src, {
365
394
  ...this.preset,
366
395
  itemsPerPage: this.data.itemsPerPage,
@@ -373,6 +402,7 @@ export default{
373
402
  this.loadEnums(data.items)
374
403
  })
375
404
  .catch(err => this.toast(err))
405
+ .finally(_ => this.readyState = 1)
376
406
  }
377
407
  return new Promise(resolve => resolve())
378
408
  },
@@ -761,8 +791,11 @@ export default{
761
791
  this.loadPreset()
762
792
  .then(() => {
763
793
  this.readyState = 1
764
- this.load()
765
- this.loadExt()
794
+ this.$nextTick(() => {
795
+ this.calcItemsPerPage()
796
+ this.load()
797
+ this.loadExt()
798
+ })
766
799
  })
767
800
 
768
801
  if(this.subscribeKey){
@@ -6,6 +6,7 @@
6
6
  ref="html"
7
7
  v-html="html"
8
8
  :class="itemClass"
9
+ @blur="saveSelection($refs.html)"
9
10
  @input="onInput"></p>
10
11
 
11
12
  <button v-if="variant === 'minimal'" type="button" class="p-3" @click="$refs.modal.open()">
@@ -59,7 +60,8 @@
59
60
  </template>
60
61
 
61
62
  <script>
62
- import groupBy from "lodash/groupBy";
63
+
64
+ import {restoreSelection, saveSelection} from "../utils/selection";
63
65
 
64
66
  export default{
65
67
 
@@ -69,6 +71,8 @@ export default{
69
71
 
70
72
  addFn: Function,
71
73
 
74
+ itemFn: Function,
75
+
72
76
  modelValue: String,
73
77
 
74
78
  items: Array,
@@ -82,7 +86,12 @@ export default{
82
86
  computed:{
83
87
 
84
88
  groupedItems(){
85
- return groupBy(this.items ?? [], 'group')
89
+ return this.items.reduce((acc, item) => {
90
+ const key = item.group ?? ''
91
+ if(!acc[key]) acc[key] = []
92
+ acc[key].push(item)
93
+ return acc
94
+ }, {})
86
95
  },
87
96
 
88
97
  viewedItems(){
@@ -99,6 +108,8 @@ export default{
99
108
  },
100
109
 
101
110
  methods: {
111
+ restoreSelection,
112
+ saveSelection,
102
113
 
103
114
  insertElement(newNode){
104
115
  let selection = window.getSelection();
@@ -123,12 +134,8 @@ export default{
123
134
  selection.addRange(range);
124
135
  },
125
136
 
126
- add(item){
127
- this.$refs.modal.close()
128
-
129
- if(typeof this.addFn === 'function'){
130
- item = this.addFn(item)
131
- }
137
+ addItem(item){
138
+ this.restoreSelection()
132
139
 
133
140
  const el = document.createElement('span')
134
141
  el.setAttribute('contenteditable', 'false')
@@ -140,6 +147,28 @@ export default{
140
147
  this.onInput()
141
148
  },
142
149
 
150
+ add(item){
151
+ this.$refs.modal.close()
152
+
153
+ if(typeof this.addFn === 'function'){
154
+
155
+ if(this.addFn.constructor.name === 'AsyncFunction'){
156
+ this.addFn(item).then(newItem => {
157
+ if(newItem === false) return
158
+ item = newItem ? newItem : item
159
+ this.addItem(item)
160
+ })
161
+ return
162
+ }
163
+
164
+ const newItem = this.addFn(item)
165
+ if(newItem === false) return
166
+ item = newItem ? newItem : item
167
+ }
168
+
169
+ this.addItem(item)
170
+ },
171
+
143
172
  remove(e){
144
173
  e.target.parentNode.removeChild(e.target)
145
174
  },
@@ -179,10 +208,19 @@ export default{
179
208
  }
180
209
 
181
210
  let html = val ?? ''
182
- if(Array.isArray(this.items)){
183
- for(let item of this.items){
184
- html = html.replaceAll(item.value, `<span class="${this.$style.tag}" contenteditable="false" @click="remove" data-value="${item.value}">${item.text ?? item.value}</span>`, 'gi')
185
- }
211
+
212
+ let customItems = []
213
+ if(typeof this.itemFn === 'function'){
214
+ customItems = this.itemFn(html)
215
+ }
216
+
217
+ const items = [
218
+ ...Array.isArray(this.items) ? this.items : [],
219
+ ...customItems
220
+ ]
221
+
222
+ for(let item of items){
223
+ html = html.replaceAll(item.value, `<span title="${item.value.replaceAll('"', '')}" class="${this.$style.tag}" contenteditable="false" data-value="${item.value}">${item.text ?? item.value}</span>`, 'gi')
186
224
  }
187
225
 
188
226
  this.html = html
@@ -7,6 +7,7 @@
7
7
  @click="">
8
8
  <slot name="item" :item="item" :index="index"></slot>
9
9
  </div>
10
+ <slot name="end"></slot>
10
11
  </div>
11
12
  </div>
12
13
 
@@ -56,6 +56,7 @@
56
56
  <svg class="animate-spin aspect-square w-[16px] h-[16px] text-primary" 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>
57
57
  </div>
58
58
  </div>
59
+ <slot name="end"></slot>
59
60
  </div>
60
61
  </div>
61
62
  <div v-else-if="visibleColumns.length <= 0 && Array.isArray(columns)" class="text-center p-3 flex-1 min-h-[100%] flex items-center justify-center">