@bagelink/vue 1.4.69 → 1.4.71

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": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.4.69",
4
+ "version": "1.4.71",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -121,76 +121,46 @@ const showLoading = computed(() => loading.value)
121
121
  </script>
122
122
 
123
123
  <template>
124
- <div
125
- class="table-list-wrap h-100"
126
- v-bind="containerProps"
127
- :class="{ overflowHiddenLoading: showLoading }"
128
- >
124
+ <div class="table-list-wrap h-100" v-bind="containerProps" :class="{ overflowHiddenLoading: showLoading }">
129
125
  <Loading v-if="showLoading" class="h100p" />
130
126
  <div v-bind="wrapperProps" :class="{ 'pointer-events-none': showLoading }">
131
- <table class="infinite-wrapper">
127
+ <table class="infinite-wrapper" :class="{ selecting: computedSelectedItems.length }">
132
128
  <thead class="row first-row">
133
129
  <th v-if="isSelectable">
134
- <input
135
- ref="allSelectorEl"
136
- type="checkbox"
137
- @click.stop
138
- @change="(e) => toggleSelectAll(e)"
139
- >
130
+ <input ref="allSelectorEl" type="checkbox" @click.stop @change="(e) => toggleSelectAll(e)">
140
131
  <!-- @change="toggleSelectAll" -->
141
132
  </th>
142
133
  <th
143
- v-for="field in computedSchema"
144
- :key="field.id"
145
- class="col"
134
+ v-for="field in computedSchema" :key="field.id" class="col"
146
135
  @click="toggleSort(field?.id || '')"
147
136
  >
148
137
  <div class="flex">
149
138
  {{ field.label || keyToLabel(field?.id) }}
150
- <div
151
- class="list-arrows"
152
- :class="{ sorted: sortField === field?.id }"
153
- >
154
- <Icon
155
- :class="{ desc: sortDirection === 'DESC' }"
156
- icon="keyboard_arrow_up"
157
- />
139
+ <div class="list-arrows" :class="{ sorted: sortField === field?.id }">
140
+ <Icon :class="{ desc: sortDirection === 'DESC' }" icon="keyboard_arrow_up" />
158
141
  </div>
159
142
  </div>
160
143
  </th>
161
144
  </thead>
162
145
  <tbody>
163
146
  <tr
164
- v-for="{ data: row } in list"
165
- :key="row?.id || `row-${Math.random()}`"
147
+ v-for="{ data: row } in list" :key="row?.id || `row-${Math.random()}`"
166
148
  class="row row-item position-relative"
167
149
  :class="{ selected: row?.id && computedSelectedItems.includes(row.id) }"
168
- @click="toggleSelectItem(row)"
150
+ @click="(event) => toggleSelectItem(row, event)"
169
151
  >
170
152
  <td v-if="isSelectable">
171
153
  <div @click.stop>
172
- <input
173
- v-model="selectedItems"
174
- type="checkbox"
175
- :value="row?.id || ''"
176
- >
154
+ <input v-model="selectedItems" type="checkbox" :value="row?.id || ''">
177
155
  </div>
178
156
  </td>
179
157
  <td
180
- v-for="field in computedSchema"
181
- :key="`${field.id}-${row?.id || Math.random()}`"
158
+ v-for="field in computedSchema" :key="`${field.id}-${row?.id || Math.random()}`"
182
159
  class="col"
183
160
  >
184
- <slot
185
- v-if="field.id && slots?.[field.id]"
186
- :name="field.id"
187
- :row="row"
188
- :field="field"
189
- />
161
+ <slot v-if="field.id && slots?.[field.id]" :name="field.id" :row="row" :field="field" />
190
162
  <div v-else>
191
- <component
192
- :is="renderFieldForRow(field, row)"
193
- />
163
+ <component :is="renderFieldForRow(field, row)" />
194
164
  </div>
195
165
  </td>
196
166
  </tr>
@@ -233,13 +203,19 @@ tbody tr.selected:hover {
233
203
  border-radius: 5px;
234
204
  object-fit: cover;
235
205
  }
206
+
236
207
  .col:has(img) {
237
208
  padding-inline-end: 0.5rem;
238
209
  }
239
210
 
240
- .overflowHiddenLoading{
211
+ .selecting .col {
212
+ user-select: none;
213
+ }
214
+
215
+ .overflowHiddenLoading {
241
216
  overflow: hidden !important;
242
217
  }
218
+
243
219
  .list-arrows.sorted .desc {
244
220
  transform: rotate(180deg);
245
221
  display: inline-block;
@@ -313,7 +289,7 @@ th {
313
289
  padding: 0rem 0.25rem;
314
290
  }
315
291
 
316
- .col > div {
292
+ .col>div {
317
293
  display: flex;
318
294
  gap: 0.5rem;
319
295
  }
@@ -9,6 +9,7 @@ export interface UseTableSelectionOptions<T> extends TableSelectionOptions<T> {
9
9
 
10
10
  export function useTableSelection<T extends { [key: string]: any }>(options: UseTableSelectionOptions<T>) {
11
11
  const allSelectorEl = ref<HTMLInputElement>()
12
+ const lastSelectedIndex = ref<number | null>(null)
12
13
  const computedSelectedItems = computed(() => options.selectedItems.value)
13
14
  const isSelectable = computed(() => options.selectable === true && Array.isArray(options.selectedItems.value))
14
15
  const allItems = $computed(() => options.data.value)
@@ -39,7 +40,37 @@ export function useTableSelection<T extends { [key: string]: any }>(options: Use
39
40
  = !allSelected && options.selectedItems.value.length > 0
40
41
  }
41
42
 
42
- function toggleSelectItem(item: T) {
43
+ function toggleSelectItem(item: T, event?: MouseEvent) {
44
+ const currentIndex = allItems.findIndex(i => i.id === item.id)
45
+
46
+ // Handle Shift+click for range selection
47
+ if (event?.shiftKey && lastSelectedIndex.value !== null && currentIndex !== -1) {
48
+ const startIndex = Math.min(lastSelectedIndex.value, currentIndex)
49
+ const endIndex = Math.max(lastSelectedIndex.value, currentIndex)
50
+
51
+ // Get all items in the range
52
+ const rangeItems = allItems.slice(startIndex, endIndex + 1)
53
+ const rangeItemIds = rangeItems.map(i => i.id)
54
+
55
+ // Check if all items in range are currently selected
56
+ const allRangeSelected = rangeItemIds.every(id => options.selectedItems.value.includes(id)
57
+ )
58
+
59
+ if (allRangeSelected) {
60
+ // Deselect all items in range
61
+ options.selectedItems.value = options.selectedItems.value.filter(id => !rangeItemIds.includes(id)
62
+ )
63
+ } else {
64
+ // Select all items in range (add missing ones)
65
+ const newSelections = rangeItemIds.filter(id => !options.selectedItems.value.includes(id)
66
+ )
67
+ options.selectedItems.value.push(...newSelections)
68
+ }
69
+
70
+ return
71
+ }
72
+
73
+ // Regular single item selection logic
43
74
  if (computedSelectedItems.value.length === 0) {
44
75
  // Clean the item if a cleanData function is provided, otherwise use the default cleaning
45
76
  const cleanItem = options.cleanData ? options.cleanData(item) : { ...item }
@@ -54,14 +85,19 @@ export function useTableSelection<T extends { [key: string]: any }>(options: Use
54
85
  }
55
86
 
56
87
  options.onSelect(cleanItem)
88
+ lastSelectedIndex.value = currentIndex
57
89
  return
58
90
  }
91
+
59
92
  const index = computedSelectedItems.value.indexOf(item.id)
60
93
  if (index > -1) {
61
94
  options.selectedItems.value.splice(index, 1)
62
95
  } else {
63
96
  options.selectedItems.value.push(item.id)
64
97
  }
98
+
99
+ // Update last selected index for future range selections
100
+ lastSelectedIndex.value = currentIndex
65
101
  }
66
102
 
67
103
  // Update toggleSelectAll to pass allItems to updateAllSelectorState
@@ -73,6 +109,9 @@ export function useTableSelection<T extends { [key: string]: any }>(options: Use
73
109
  } else {
74
110
  options.selectedItems.value = []
75
111
  }
112
+
113
+ // Reset last selected index when selecting/deselecting all
114
+ lastSelectedIndex.value = null
76
115
  }
77
116
 
78
117
  return {