gp-grid-vue 0.1.6 → 0.2.2
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/README.md +598 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -1819
- package/package.json +63 -55
- package/dist/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,1819 +1 @@
|
|
|
1
|
-
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, h, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, reactive, ref, renderList, resolveDynamicComponent, shallowRef, toDisplayString, unref, vModelText, watch, withDirectives } from "vue";
|
|
2
|
-
import { GridCore, buildCellClasses, buildCellClasses as buildCellClasses$1, calculateColumnPositions, calculateColumnPositions as calculateColumnPositions$1, createClientDataSource, createClientDataSource as createClientDataSource$1, createDataSourceFromArray, createDataSourceFromArray as createDataSourceFromArray$1, createMutableClientDataSource, createServerDataSource, findColumnAtX, getTotalWidth, getTotalWidth as getTotalWidth$1, gridStyles, injectStyles, injectStyles as injectStyles$1, isCellActive, isCellActive as isCellActive$1, isCellEditing, isCellEditing as isCellEditing$1, isCellInFillPreview, isCellInFillPreview as isCellInFillPreview$1, isCellSelected, isCellSelected as isCellSelected$1, isRowVisible } from "gp-grid-core";
|
|
3
|
-
|
|
4
|
-
//#region src/gridState/useGridState.ts
|
|
5
|
-
function createInitialState() {
|
|
6
|
-
return {
|
|
7
|
-
slots: /* @__PURE__ */ new Map(),
|
|
8
|
-
activeCell: null,
|
|
9
|
-
selectionRange: null,
|
|
10
|
-
editingCell: null,
|
|
11
|
-
contentWidth: 0,
|
|
12
|
-
contentHeight: 0,
|
|
13
|
-
headers: /* @__PURE__ */ new Map(),
|
|
14
|
-
filterPopup: null,
|
|
15
|
-
isLoading: false,
|
|
16
|
-
error: null,
|
|
17
|
-
totalRows: 0,
|
|
18
|
-
visibleRowRange: null
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Apply a single instruction to mutable state
|
|
23
|
-
*/
|
|
24
|
-
function applyInstruction(instruction, state) {
|
|
25
|
-
switch (instruction.type) {
|
|
26
|
-
case "CREATE_SLOT":
|
|
27
|
-
state.slots.set(instruction.slotId, {
|
|
28
|
-
slotId: instruction.slotId,
|
|
29
|
-
rowIndex: -1,
|
|
30
|
-
rowData: {},
|
|
31
|
-
translateY: 0
|
|
32
|
-
});
|
|
33
|
-
break;
|
|
34
|
-
case "DESTROY_SLOT":
|
|
35
|
-
state.slots.delete(instruction.slotId);
|
|
36
|
-
break;
|
|
37
|
-
case "ASSIGN_SLOT": {
|
|
38
|
-
const existing = state.slots.get(instruction.slotId);
|
|
39
|
-
if (existing) state.slots.set(instruction.slotId, {
|
|
40
|
-
...existing,
|
|
41
|
-
rowIndex: instruction.rowIndex,
|
|
42
|
-
rowData: instruction.rowData
|
|
43
|
-
});
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
case "MOVE_SLOT": {
|
|
47
|
-
const existing = state.slots.get(instruction.slotId);
|
|
48
|
-
if (existing) state.slots.set(instruction.slotId, {
|
|
49
|
-
...existing,
|
|
50
|
-
translateY: instruction.translateY
|
|
51
|
-
});
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
case "SET_ACTIVE_CELL":
|
|
55
|
-
state.activeCell = instruction.position;
|
|
56
|
-
break;
|
|
57
|
-
case "SET_SELECTION_RANGE":
|
|
58
|
-
state.selectionRange = instruction.range;
|
|
59
|
-
break;
|
|
60
|
-
case "UPDATE_VISIBLE_RANGE":
|
|
61
|
-
state.visibleRowRange = {
|
|
62
|
-
start: instruction.start,
|
|
63
|
-
end: instruction.end
|
|
64
|
-
};
|
|
65
|
-
break;
|
|
66
|
-
case "START_EDIT":
|
|
67
|
-
state.editingCell = {
|
|
68
|
-
row: instruction.row,
|
|
69
|
-
col: instruction.col,
|
|
70
|
-
initialValue: instruction.initialValue
|
|
71
|
-
};
|
|
72
|
-
break;
|
|
73
|
-
case "STOP_EDIT":
|
|
74
|
-
state.editingCell = null;
|
|
75
|
-
break;
|
|
76
|
-
case "SET_CONTENT_SIZE":
|
|
77
|
-
state.contentWidth = instruction.width;
|
|
78
|
-
state.contentHeight = instruction.height;
|
|
79
|
-
break;
|
|
80
|
-
case "UPDATE_HEADER":
|
|
81
|
-
state.headers.set(instruction.colIndex, {
|
|
82
|
-
column: instruction.column,
|
|
83
|
-
sortDirection: instruction.sortDirection,
|
|
84
|
-
sortIndex: instruction.sortIndex,
|
|
85
|
-
sortable: instruction.sortable,
|
|
86
|
-
filterable: instruction.filterable,
|
|
87
|
-
hasFilter: instruction.hasFilter
|
|
88
|
-
});
|
|
89
|
-
break;
|
|
90
|
-
case "OPEN_FILTER_POPUP":
|
|
91
|
-
state.filterPopup = {
|
|
92
|
-
isOpen: true,
|
|
93
|
-
colIndex: instruction.colIndex,
|
|
94
|
-
column: instruction.column,
|
|
95
|
-
anchorRect: instruction.anchorRect,
|
|
96
|
-
distinctValues: instruction.distinctValues,
|
|
97
|
-
currentFilter: instruction.currentFilter
|
|
98
|
-
};
|
|
99
|
-
break;
|
|
100
|
-
case "CLOSE_FILTER_POPUP":
|
|
101
|
-
state.filterPopup = null;
|
|
102
|
-
break;
|
|
103
|
-
case "DATA_LOADING":
|
|
104
|
-
state.isLoading = true;
|
|
105
|
-
state.error = null;
|
|
106
|
-
break;
|
|
107
|
-
case "DATA_LOADED":
|
|
108
|
-
state.isLoading = false;
|
|
109
|
-
state.totalRows = instruction.totalRows;
|
|
110
|
-
break;
|
|
111
|
-
case "DATA_ERROR":
|
|
112
|
-
state.isLoading = false;
|
|
113
|
-
state.error = instruction.error;
|
|
114
|
-
break;
|
|
115
|
-
case "ROWS_ADDED":
|
|
116
|
-
case "ROWS_REMOVED":
|
|
117
|
-
state.totalRows = instruction.totalRows;
|
|
118
|
-
break;
|
|
119
|
-
case "ROWS_UPDATED":
|
|
120
|
-
case "TRANSACTION_PROCESSED": break;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Vue composable for managing grid state
|
|
125
|
-
*/
|
|
126
|
-
function useGridState() {
|
|
127
|
-
const state = reactive(createInitialState());
|
|
128
|
-
/**
|
|
129
|
-
* Apply a batch of instructions to the state
|
|
130
|
-
*/
|
|
131
|
-
function applyInstructions(instructions) {
|
|
132
|
-
for (const instruction of instructions) applyInstruction(instruction, state);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Reset state to initial values
|
|
136
|
-
*/
|
|
137
|
-
function reset() {
|
|
138
|
-
const initial = createInitialState();
|
|
139
|
-
state.slots = initial.slots;
|
|
140
|
-
state.activeCell = initial.activeCell;
|
|
141
|
-
state.selectionRange = initial.selectionRange;
|
|
142
|
-
state.editingCell = initial.editingCell;
|
|
143
|
-
state.contentWidth = initial.contentWidth;
|
|
144
|
-
state.contentHeight = initial.contentHeight;
|
|
145
|
-
state.headers = initial.headers;
|
|
146
|
-
state.filterPopup = initial.filterPopup;
|
|
147
|
-
state.isLoading = initial.isLoading;
|
|
148
|
-
state.error = initial.error;
|
|
149
|
-
state.totalRows = initial.totalRows;
|
|
150
|
-
state.visibleRowRange = initial.visibleRowRange;
|
|
151
|
-
}
|
|
152
|
-
return {
|
|
153
|
-
state,
|
|
154
|
-
applyInstructions,
|
|
155
|
-
reset
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
//#endregion
|
|
160
|
-
//#region src/composables/useAutoScroll.ts
|
|
161
|
-
const AUTO_SCROLL_INTERVAL = 16;
|
|
162
|
-
/**
|
|
163
|
-
* Vue composable for auto-scrolling during drag operations
|
|
164
|
-
*/
|
|
165
|
-
function useAutoScroll(containerRef) {
|
|
166
|
-
const autoScrollInterval = ref(null);
|
|
167
|
-
/**
|
|
168
|
-
* Start auto-scrolling in the given direction
|
|
169
|
-
*/
|
|
170
|
-
function startAutoScroll(dx, dy) {
|
|
171
|
-
if (autoScrollInterval.value) clearInterval(autoScrollInterval.value);
|
|
172
|
-
autoScrollInterval.value = setInterval(() => {
|
|
173
|
-
const container = containerRef.value;
|
|
174
|
-
if (container) {
|
|
175
|
-
container.scrollTop += dy;
|
|
176
|
-
container.scrollLeft += dx;
|
|
177
|
-
}
|
|
178
|
-
}, AUTO_SCROLL_INTERVAL);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Stop auto-scrolling
|
|
182
|
-
*/
|
|
183
|
-
function stopAutoScroll() {
|
|
184
|
-
if (autoScrollInterval.value) {
|
|
185
|
-
clearInterval(autoScrollInterval.value);
|
|
186
|
-
autoScrollInterval.value = null;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
onUnmounted(() => {
|
|
190
|
-
stopAutoScroll();
|
|
191
|
-
});
|
|
192
|
-
return {
|
|
193
|
-
startAutoScroll,
|
|
194
|
-
stopAutoScroll
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
//#endregion
|
|
199
|
-
//#region src/composables/useInputHandler.ts
|
|
200
|
-
/**
|
|
201
|
-
* Find the slot for a given row index
|
|
202
|
-
*/
|
|
203
|
-
function findSlotForRow(slots, rowIndex) {
|
|
204
|
-
for (const slot of slots.values()) if (slot.rowIndex === rowIndex) return slot;
|
|
205
|
-
return null;
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Scroll a cell into view if needed
|
|
209
|
-
*/
|
|
210
|
-
function scrollCellIntoView(core, container, row, rowHeight, headerHeight, slots) {
|
|
211
|
-
const slot = findSlotForRow(slots, row);
|
|
212
|
-
const cellViewportTop = (slot ? slot.translateY : headerHeight + row * rowHeight) - container.scrollTop;
|
|
213
|
-
const cellViewportBottom = cellViewportTop + rowHeight;
|
|
214
|
-
const visibleTop = headerHeight;
|
|
215
|
-
const visibleBottom = container.clientHeight;
|
|
216
|
-
if (cellViewportTop < visibleTop) container.scrollTop = core.getScrollTopForRow(row);
|
|
217
|
-
else if (cellViewportBottom > visibleBottom) {
|
|
218
|
-
const visibleDataHeight = container.clientHeight - headerHeight;
|
|
219
|
-
const rowsInView = Math.floor(visibleDataHeight / rowHeight);
|
|
220
|
-
const targetRow = Math.max(0, row - rowsInView + 1);
|
|
221
|
-
container.scrollTop = core.getScrollTopForRow(targetRow);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Vue composable for handling all input interactions
|
|
226
|
-
*/
|
|
227
|
-
function useInputHandler(coreRef, containerRef, columns, options) {
|
|
228
|
-
const { activeCell, selectionRange, editingCell, filterPopupOpen, rowHeight, headerHeight, columnPositions, slots } = options;
|
|
229
|
-
const { startAutoScroll, stopAutoScroll } = useAutoScroll(containerRef);
|
|
230
|
-
const dragState = ref({
|
|
231
|
-
isDragging: false,
|
|
232
|
-
dragType: null,
|
|
233
|
-
fillSourceRange: null,
|
|
234
|
-
fillTarget: null
|
|
235
|
-
});
|
|
236
|
-
watch([
|
|
237
|
-
() => headerHeight,
|
|
238
|
-
() => rowHeight,
|
|
239
|
-
columnPositions,
|
|
240
|
-
() => columns.value.length
|
|
241
|
-
], () => {
|
|
242
|
-
const core = coreRef.value;
|
|
243
|
-
if (core?.input) core.input.updateDeps({
|
|
244
|
-
getHeaderHeight: () => headerHeight,
|
|
245
|
-
getRowHeight: () => rowHeight,
|
|
246
|
-
getColumnPositions: () => columnPositions.value,
|
|
247
|
-
getColumnCount: () => columns.value.length
|
|
248
|
-
});
|
|
249
|
-
}, { immediate: true });
|
|
250
|
-
function getContainerBounds() {
|
|
251
|
-
const container = containerRef.value;
|
|
252
|
-
if (!container) return null;
|
|
253
|
-
const rect = container.getBoundingClientRect();
|
|
254
|
-
return {
|
|
255
|
-
top: rect.top,
|
|
256
|
-
left: rect.left,
|
|
257
|
-
width: rect.width,
|
|
258
|
-
height: rect.height,
|
|
259
|
-
scrollTop: container.scrollTop,
|
|
260
|
-
scrollLeft: container.scrollLeft
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
function toPointerEventData(e) {
|
|
264
|
-
return {
|
|
265
|
-
clientX: e.clientX,
|
|
266
|
-
clientY: e.clientY,
|
|
267
|
-
button: e.button,
|
|
268
|
-
shiftKey: e.shiftKey,
|
|
269
|
-
ctrlKey: e.ctrlKey,
|
|
270
|
-
metaKey: e.metaKey
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
function startGlobalDragListeners() {
|
|
274
|
-
const handleMouseMove = (e) => {
|
|
275
|
-
const core = coreRef.value;
|
|
276
|
-
const bounds = getContainerBounds();
|
|
277
|
-
if (!core?.input || !bounds) return;
|
|
278
|
-
const result = core.input.handleDragMove(toPointerEventData(e), bounds);
|
|
279
|
-
if (result) {
|
|
280
|
-
if (result.autoScroll) startAutoScroll(result.autoScroll.dx, result.autoScroll.dy);
|
|
281
|
-
else stopAutoScroll();
|
|
282
|
-
dragState.value = core.input.getDragState();
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
|
-
const handleMouseUp = () => {
|
|
286
|
-
const core = coreRef.value;
|
|
287
|
-
if (core?.input) {
|
|
288
|
-
core.input.handleDragEnd();
|
|
289
|
-
dragState.value = core.input.getDragState();
|
|
290
|
-
}
|
|
291
|
-
stopAutoScroll();
|
|
292
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
293
|
-
document.removeEventListener("mouseup", handleMouseUp);
|
|
294
|
-
};
|
|
295
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
296
|
-
document.addEventListener("mouseup", handleMouseUp);
|
|
297
|
-
}
|
|
298
|
-
function handleCellMouseDown(rowIndex, colIndex, e) {
|
|
299
|
-
const core = coreRef.value;
|
|
300
|
-
if (!core?.input) return;
|
|
301
|
-
const result = core.input.handleCellMouseDown(rowIndex, colIndex, toPointerEventData(e));
|
|
302
|
-
if (result.focusContainer) containerRef.value?.focus();
|
|
303
|
-
if (result.startDrag === "selection") {
|
|
304
|
-
core.input.startSelectionDrag();
|
|
305
|
-
dragState.value = core.input.getDragState();
|
|
306
|
-
startGlobalDragListeners();
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
function handleCellDoubleClick(rowIndex, colIndex) {
|
|
310
|
-
const core = coreRef.value;
|
|
311
|
-
if (!core?.input) return;
|
|
312
|
-
core.input.handleCellDoubleClick(rowIndex, colIndex);
|
|
313
|
-
}
|
|
314
|
-
function handleFillHandleMouseDown(e) {
|
|
315
|
-
const core = coreRef.value;
|
|
316
|
-
if (!core?.input) return;
|
|
317
|
-
const result = core.input.handleFillHandleMouseDown(activeCell.value, selectionRange.value, toPointerEventData(e));
|
|
318
|
-
if (result.preventDefault) e.preventDefault();
|
|
319
|
-
if (result.stopPropagation) e.stopPropagation();
|
|
320
|
-
if (result.startDrag === "fill") {
|
|
321
|
-
dragState.value = core.input.getDragState();
|
|
322
|
-
startGlobalDragListeners();
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
function handleHeaderClick(colIndex, e) {
|
|
326
|
-
const core = coreRef.value;
|
|
327
|
-
if (!core?.input) return;
|
|
328
|
-
const column = columns.value[colIndex];
|
|
329
|
-
if (!column) return;
|
|
330
|
-
const colId = column.colId ?? column.field;
|
|
331
|
-
core.input.handleHeaderClick(colId, e.shiftKey);
|
|
332
|
-
}
|
|
333
|
-
function handleKeyDown(e) {
|
|
334
|
-
const core = coreRef.value;
|
|
335
|
-
const container = containerRef.value;
|
|
336
|
-
if (!core?.input) return;
|
|
337
|
-
const result = core.input.handleKeyDown({
|
|
338
|
-
key: e.key,
|
|
339
|
-
shiftKey: e.shiftKey,
|
|
340
|
-
ctrlKey: e.ctrlKey,
|
|
341
|
-
metaKey: e.metaKey
|
|
342
|
-
}, activeCell.value, editingCell.value, filterPopupOpen.value);
|
|
343
|
-
if (result.preventDefault) e.preventDefault();
|
|
344
|
-
if (result.scrollToCell && container) scrollCellIntoView(core, container, result.scrollToCell.row, rowHeight, headerHeight, slots.value);
|
|
345
|
-
}
|
|
346
|
-
function handleWheel(e, wheelDampening) {
|
|
347
|
-
const core = coreRef.value;
|
|
348
|
-
const container = containerRef.value;
|
|
349
|
-
if (!core?.input || !container) return;
|
|
350
|
-
const dampened = core.input.handleWheel(e.deltaY, e.deltaX, wheelDampening);
|
|
351
|
-
if (dampened) {
|
|
352
|
-
e.preventDefault();
|
|
353
|
-
container.scrollTop += dampened.dy;
|
|
354
|
-
container.scrollLeft += dampened.dx;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
onUnmounted(() => {
|
|
358
|
-
stopAutoScroll();
|
|
359
|
-
});
|
|
360
|
-
return {
|
|
361
|
-
handleCellMouseDown,
|
|
362
|
-
handleCellDoubleClick,
|
|
363
|
-
handleFillHandleMouseDown,
|
|
364
|
-
handleHeaderClick,
|
|
365
|
-
handleKeyDown,
|
|
366
|
-
handleWheel,
|
|
367
|
-
dragState
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
//#endregion
|
|
372
|
-
//#region src/composables/useFillHandle.ts
|
|
373
|
-
/**
|
|
374
|
-
* Composable for calculating the fill handle position.
|
|
375
|
-
* The fill handle appears at the bottom-right corner of the selection
|
|
376
|
-
* when all selected columns are editable.
|
|
377
|
-
*/
|
|
378
|
-
function useFillHandle(options) {
|
|
379
|
-
const { activeCell, selectionRange, slots, columns, columnPositions, rowHeight } = options;
|
|
380
|
-
return { fillHandlePosition: computed(() => {
|
|
381
|
-
const active = activeCell.value;
|
|
382
|
-
const selection = selectionRange.value;
|
|
383
|
-
const slotsMap = slots.value;
|
|
384
|
-
if (!active && !selection) return null;
|
|
385
|
-
let row, col;
|
|
386
|
-
let minCol, maxCol;
|
|
387
|
-
if (selection) {
|
|
388
|
-
row = Math.max(selection.startRow, selection.endRow);
|
|
389
|
-
col = Math.max(selection.startCol, selection.endCol);
|
|
390
|
-
minCol = Math.min(selection.startCol, selection.endCol);
|
|
391
|
-
maxCol = Math.max(selection.startCol, selection.endCol);
|
|
392
|
-
} else if (active) {
|
|
393
|
-
row = active.row;
|
|
394
|
-
col = active.col;
|
|
395
|
-
minCol = col;
|
|
396
|
-
maxCol = col;
|
|
397
|
-
} else return null;
|
|
398
|
-
const cols = columns.value;
|
|
399
|
-
for (let c = minCol; c <= maxCol; c++) {
|
|
400
|
-
const column = cols[c];
|
|
401
|
-
if (!column || column.editable !== true) return null;
|
|
402
|
-
}
|
|
403
|
-
let cellTop = null;
|
|
404
|
-
for (const slot of slotsMap.values()) if (slot.rowIndex === row) {
|
|
405
|
-
cellTop = slot.translateY;
|
|
406
|
-
break;
|
|
407
|
-
}
|
|
408
|
-
if (cellTop === null) return null;
|
|
409
|
-
const cellLeft = columnPositions.value[col] ?? 0;
|
|
410
|
-
const cellWidth = cols[col]?.width ?? 0;
|
|
411
|
-
return {
|
|
412
|
-
top: cellTop + rowHeight - 5,
|
|
413
|
-
left: cellLeft + cellWidth - 20
|
|
414
|
-
};
|
|
415
|
-
}) };
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
//#endregion
|
|
419
|
-
//#region src/renderers/cellRenderer.ts
|
|
420
|
-
/**
|
|
421
|
-
* Ensure we always return a VNode, never a plain string
|
|
422
|
-
*/
|
|
423
|
-
function toVNode$2(value) {
|
|
424
|
-
if (value == null || value === "") return createTextVNode("");
|
|
425
|
-
if (typeof value === "string") return createTextVNode(value);
|
|
426
|
-
return value;
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Get cell value from row data, supporting dot-notation for nested fields
|
|
430
|
-
*/
|
|
431
|
-
function getCellValue(rowData, field) {
|
|
432
|
-
const parts = field.split(".");
|
|
433
|
-
let value = rowData;
|
|
434
|
-
for (const part of parts) {
|
|
435
|
-
if (value == null || typeof value !== "object") return null;
|
|
436
|
-
value = value[part];
|
|
437
|
-
}
|
|
438
|
-
return value ?? null;
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* Render cell content based on column configuration and renderer registries
|
|
442
|
-
*/
|
|
443
|
-
function renderCell(options) {
|
|
444
|
-
const { column, rowData, rowIndex, colIndex, isActive, isSelected, isEditing, cellRenderers, globalCellRenderer } = options;
|
|
445
|
-
const value = getCellValue(rowData, column.field);
|
|
446
|
-
const params = {
|
|
447
|
-
value,
|
|
448
|
-
rowData,
|
|
449
|
-
column,
|
|
450
|
-
rowIndex,
|
|
451
|
-
colIndex,
|
|
452
|
-
isActive,
|
|
453
|
-
isSelected,
|
|
454
|
-
isEditing
|
|
455
|
-
};
|
|
456
|
-
if (column.cellRenderer && typeof column.cellRenderer === "string") {
|
|
457
|
-
const renderer = cellRenderers[column.cellRenderer];
|
|
458
|
-
if (renderer) return toVNode$2(renderer(params));
|
|
459
|
-
}
|
|
460
|
-
if (globalCellRenderer) return toVNode$2(globalCellRenderer(params));
|
|
461
|
-
return createTextVNode(value == null ? "" : String(value));
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
//#endregion
|
|
465
|
-
//#region src/renderers/editRenderer.ts
|
|
466
|
-
/**
|
|
467
|
-
* Ensure we always return a VNode, never a plain string
|
|
468
|
-
*/
|
|
469
|
-
function toVNode$1(value) {
|
|
470
|
-
if (value == null || value === "") return createTextVNode("");
|
|
471
|
-
if (typeof value === "string") return createTextVNode(value);
|
|
472
|
-
return value;
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Render edit cell content based on column configuration and renderer registries
|
|
476
|
-
*/
|
|
477
|
-
function renderEditCell(options) {
|
|
478
|
-
const { column, rowData, rowIndex, colIndex, initialValue, core, editRenderers, globalEditRenderer } = options;
|
|
479
|
-
if (!core) return createTextVNode("");
|
|
480
|
-
const params = {
|
|
481
|
-
value: getCellValue(rowData, column.field),
|
|
482
|
-
rowData,
|
|
483
|
-
column,
|
|
484
|
-
rowIndex,
|
|
485
|
-
colIndex,
|
|
486
|
-
isActive: true,
|
|
487
|
-
isSelected: true,
|
|
488
|
-
isEditing: true,
|
|
489
|
-
initialValue,
|
|
490
|
-
onValueChange: (newValue) => core.updateEditValue(newValue),
|
|
491
|
-
onCommit: () => core.commitEdit(),
|
|
492
|
-
onCancel: () => core.cancelEdit()
|
|
493
|
-
};
|
|
494
|
-
if (column.editRenderer && typeof column.editRenderer === "string") {
|
|
495
|
-
const renderer = editRenderers[column.editRenderer];
|
|
496
|
-
if (renderer) return toVNode$1(renderer(params));
|
|
497
|
-
}
|
|
498
|
-
if (globalEditRenderer) return toVNode$1(globalEditRenderer(params));
|
|
499
|
-
return h("input", {
|
|
500
|
-
class: "gp-grid-edit-input",
|
|
501
|
-
type: "text",
|
|
502
|
-
value: initialValue == null ? "" : String(initialValue),
|
|
503
|
-
autofocus: true,
|
|
504
|
-
onFocus: (e) => e.target.select(),
|
|
505
|
-
onInput: (e) => core.updateEditValue(e.target.value),
|
|
506
|
-
onKeydown: (e) => {
|
|
507
|
-
e.stopPropagation();
|
|
508
|
-
if (e.key === "Enter") core.commitEdit();
|
|
509
|
-
else if (e.key === "Escape") core.cancelEdit();
|
|
510
|
-
else if (e.key === "Tab") {
|
|
511
|
-
e.preventDefault();
|
|
512
|
-
core.commitEdit();
|
|
513
|
-
core.selection.moveFocus(e.shiftKey ? "left" : "right", false);
|
|
514
|
-
}
|
|
515
|
-
},
|
|
516
|
-
onBlur: () => core.commitEdit()
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
//#endregion
|
|
521
|
-
//#region src/renderers/headerRenderer.ts
|
|
522
|
-
/**
|
|
523
|
-
* Ensure we always return a VNode, never a plain string
|
|
524
|
-
*/
|
|
525
|
-
function toVNode(value) {
|
|
526
|
-
if (value == null || value === "") return createTextVNode("");
|
|
527
|
-
if (typeof value === "string") return createTextVNode(value);
|
|
528
|
-
return value;
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Render header content based on column configuration and renderer registries
|
|
532
|
-
*/
|
|
533
|
-
function renderHeader(options) {
|
|
534
|
-
const { column, colIndex, sortDirection, sortIndex, sortable, filterable, hasFilter, core, container, headerRenderers, globalHeaderRenderer } = options;
|
|
535
|
-
const params = {
|
|
536
|
-
column,
|
|
537
|
-
colIndex,
|
|
538
|
-
sortDirection,
|
|
539
|
-
sortIndex,
|
|
540
|
-
sortable,
|
|
541
|
-
filterable,
|
|
542
|
-
hasFilter,
|
|
543
|
-
onSort: (direction, addToExisting) => {
|
|
544
|
-
if (core && sortable) core.setSort(column.colId ?? column.field, direction, addToExisting);
|
|
545
|
-
},
|
|
546
|
-
onFilterClick: () => {
|
|
547
|
-
if (core && filterable) {
|
|
548
|
-
const headerCell = container?.querySelector(`[data-col-index="${colIndex}"]`);
|
|
549
|
-
if (headerCell) {
|
|
550
|
-
const rect = headerCell.getBoundingClientRect();
|
|
551
|
-
core.openFilterPopup(colIndex, {
|
|
552
|
-
top: rect.top,
|
|
553
|
-
left: rect.left,
|
|
554
|
-
width: rect.width,
|
|
555
|
-
height: rect.height
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
};
|
|
561
|
-
if (column.headerRenderer && typeof column.headerRenderer === "string") {
|
|
562
|
-
const renderer = headerRenderers[column.headerRenderer];
|
|
563
|
-
if (renderer) return toVNode(renderer(params));
|
|
564
|
-
}
|
|
565
|
-
if (globalHeaderRenderer) return toVNode(globalHeaderRenderer(params));
|
|
566
|
-
const children = [h("span", { class: "gp-grid-header-text" }, column.headerName ?? column.field)];
|
|
567
|
-
const iconsChildren = [];
|
|
568
|
-
if (sortable) {
|
|
569
|
-
const arrowsChildren = [h("span", { class: "gp-grid-sort-arrows-stack" }, [h("svg", {
|
|
570
|
-
class: `gp-grid-sort-arrow-up${sortDirection === "asc" ? " active" : ""}`,
|
|
571
|
-
width: "8",
|
|
572
|
-
height: "6",
|
|
573
|
-
viewBox: "0 0 8 6"
|
|
574
|
-
}, [h("path", {
|
|
575
|
-
d: "M4 0L8 6H0L4 0Z",
|
|
576
|
-
fill: "currentColor"
|
|
577
|
-
})]), h("svg", {
|
|
578
|
-
class: `gp-grid-sort-arrow-down${sortDirection === "desc" ? " active" : ""}`,
|
|
579
|
-
width: "8",
|
|
580
|
-
height: "6",
|
|
581
|
-
viewBox: "0 0 8 6"
|
|
582
|
-
}, [h("path", {
|
|
583
|
-
d: "M4 6L0 0H8L4 6Z",
|
|
584
|
-
fill: "currentColor"
|
|
585
|
-
})])])];
|
|
586
|
-
if (sortIndex !== void 0 && sortIndex > 0) arrowsChildren.push(h("span", { class: "gp-grid-sort-index" }, String(sortIndex)));
|
|
587
|
-
iconsChildren.push(h("span", { class: "gp-grid-sort-arrows" }, arrowsChildren));
|
|
588
|
-
}
|
|
589
|
-
if (filterable) iconsChildren.push(h("span", {
|
|
590
|
-
class: `gp-grid-filter-icon${hasFilter ? " active" : ""}`,
|
|
591
|
-
onMousedown: (e) => {
|
|
592
|
-
e.stopPropagation();
|
|
593
|
-
e.preventDefault();
|
|
594
|
-
params.onFilterClick();
|
|
595
|
-
},
|
|
596
|
-
onClick: (e) => {
|
|
597
|
-
e.stopPropagation();
|
|
598
|
-
}
|
|
599
|
-
}, [h("svg", {
|
|
600
|
-
width: "16",
|
|
601
|
-
height: "16",
|
|
602
|
-
viewBox: "0 0 24 24",
|
|
603
|
-
fill: "currentColor"
|
|
604
|
-
}, [h("path", { d: "M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z" })])]));
|
|
605
|
-
if (iconsChildren.length > 0) children.push(h("span", { class: "gp-grid-header-icons" }, iconsChildren));
|
|
606
|
-
return h(Fragment, children);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
//#endregion
|
|
610
|
-
//#region src/composables/useFilterPopup.ts
|
|
611
|
-
/**
|
|
612
|
-
* Composable for filter popup behavior.
|
|
613
|
-
* Handles click-outside detection and escape key to close the popup.
|
|
614
|
-
*/
|
|
615
|
-
function useFilterPopup(popupRef, options) {
|
|
616
|
-
const { onClose, ignoreSelector = ".gp-grid-filter-icon" } = options;
|
|
617
|
-
let handleClickOutside = null;
|
|
618
|
-
let handleKeyDown = null;
|
|
619
|
-
onMounted(() => {
|
|
620
|
-
handleClickOutside = (e) => {
|
|
621
|
-
const target = e.target;
|
|
622
|
-
if (ignoreSelector && target.closest(ignoreSelector)) return;
|
|
623
|
-
if (popupRef.value && !popupRef.value.contains(target)) onClose();
|
|
624
|
-
};
|
|
625
|
-
handleKeyDown = (e) => {
|
|
626
|
-
if (e.key === "Escape") onClose();
|
|
627
|
-
};
|
|
628
|
-
requestAnimationFrame(() => {
|
|
629
|
-
if (handleClickOutside) document.addEventListener("mousedown", handleClickOutside);
|
|
630
|
-
if (handleKeyDown) document.addEventListener("keydown", handleKeyDown);
|
|
631
|
-
});
|
|
632
|
-
});
|
|
633
|
-
onUnmounted(() => {
|
|
634
|
-
if (handleClickOutside) document.removeEventListener("mousedown", handleClickOutside);
|
|
635
|
-
if (handleKeyDown) document.removeEventListener("keydown", handleKeyDown);
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
//#endregion
|
|
640
|
-
//#region src/composables/useFilterConditions.ts
|
|
641
|
-
/**
|
|
642
|
-
* Composable for managing filter conditions.
|
|
643
|
-
* Used by NumberFilterContent, DateFilterContent, and TextFilterContent (condition mode).
|
|
644
|
-
*/
|
|
645
|
-
function useFilterConditions(initialConditions, initialCombination = "and") {
|
|
646
|
-
const conditions = ref([...initialConditions]);
|
|
647
|
-
const combination = ref(initialCombination);
|
|
648
|
-
const updateCondition = (index, updates) => {
|
|
649
|
-
const next = [...conditions.value];
|
|
650
|
-
next[index] = {
|
|
651
|
-
...next[index],
|
|
652
|
-
...updates
|
|
653
|
-
};
|
|
654
|
-
conditions.value = next;
|
|
655
|
-
};
|
|
656
|
-
const addCondition = (defaultOperator) => {
|
|
657
|
-
conditions.value = [...conditions.value, {
|
|
658
|
-
operator: defaultOperator,
|
|
659
|
-
value: "",
|
|
660
|
-
valueTo: "",
|
|
661
|
-
nextOperator: "and"
|
|
662
|
-
}];
|
|
663
|
-
};
|
|
664
|
-
const removeCondition = (index) => {
|
|
665
|
-
conditions.value = conditions.value.filter((_, i) => i !== index);
|
|
666
|
-
};
|
|
667
|
-
return {
|
|
668
|
-
conditions,
|
|
669
|
-
combination,
|
|
670
|
-
updateCondition,
|
|
671
|
-
addCondition,
|
|
672
|
-
removeCondition
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
//#endregion
|
|
677
|
-
//#region src/components/TextFilterContent.vue
|
|
678
|
-
const _hoisted_1$4 = { class: "gp-grid-filter-content gp-grid-filter-text" };
|
|
679
|
-
const _hoisted_2$3 = {
|
|
680
|
-
key: 0,
|
|
681
|
-
class: "gp-grid-filter-mode-toggle"
|
|
682
|
-
};
|
|
683
|
-
const _hoisted_3$3 = {
|
|
684
|
-
key: 1,
|
|
685
|
-
class: "gp-grid-filter-info"
|
|
686
|
-
};
|
|
687
|
-
const _hoisted_4$3 = { class: "gp-grid-filter-actions" };
|
|
688
|
-
const _hoisted_5$3 = ["disabled"];
|
|
689
|
-
const _hoisted_6$2 = { class: "gp-grid-filter-list" };
|
|
690
|
-
const _hoisted_7$2 = {
|
|
691
|
-
key: 0,
|
|
692
|
-
class: "gp-grid-filter-option"
|
|
693
|
-
};
|
|
694
|
-
const _hoisted_8$2 = ["checked"];
|
|
695
|
-
const _hoisted_9$2 = ["checked", "onChange"];
|
|
696
|
-
const _hoisted_10$2 = {
|
|
697
|
-
key: 0,
|
|
698
|
-
class: "gp-grid-filter-combination"
|
|
699
|
-
};
|
|
700
|
-
const _hoisted_11 = ["onClick"];
|
|
701
|
-
const _hoisted_12 = ["onClick"];
|
|
702
|
-
const _hoisted_13 = { class: "gp-grid-filter-row" };
|
|
703
|
-
const _hoisted_14 = [
|
|
704
|
-
"value",
|
|
705
|
-
"autofocus",
|
|
706
|
-
"onChange"
|
|
707
|
-
];
|
|
708
|
-
const _hoisted_15 = ["value"];
|
|
709
|
-
const _hoisted_16 = ["value", "onInput"];
|
|
710
|
-
const _hoisted_17 = ["onClick"];
|
|
711
|
-
const MAX_VALUES_FOR_LIST = 100;
|
|
712
|
-
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
713
|
-
__name: "TextFilterContent",
|
|
714
|
-
props: {
|
|
715
|
-
distinctValues: {},
|
|
716
|
-
currentFilter: {}
|
|
717
|
-
},
|
|
718
|
-
emits: ["apply", "close"],
|
|
719
|
-
setup(__props, { emit: __emit }) {
|
|
720
|
-
const OPERATORS = [
|
|
721
|
-
{
|
|
722
|
-
value: "contains",
|
|
723
|
-
label: "Contains"
|
|
724
|
-
},
|
|
725
|
-
{
|
|
726
|
-
value: "notContains",
|
|
727
|
-
label: "Does not contain"
|
|
728
|
-
},
|
|
729
|
-
{
|
|
730
|
-
value: "equals",
|
|
731
|
-
label: "Equals"
|
|
732
|
-
},
|
|
733
|
-
{
|
|
734
|
-
value: "notEquals",
|
|
735
|
-
label: "Does not equal"
|
|
736
|
-
},
|
|
737
|
-
{
|
|
738
|
-
value: "startsWith",
|
|
739
|
-
label: "Starts with"
|
|
740
|
-
},
|
|
741
|
-
{
|
|
742
|
-
value: "endsWith",
|
|
743
|
-
label: "Ends with"
|
|
744
|
-
},
|
|
745
|
-
{
|
|
746
|
-
value: "blank",
|
|
747
|
-
label: "Is blank"
|
|
748
|
-
},
|
|
749
|
-
{
|
|
750
|
-
value: "notBlank",
|
|
751
|
-
label: "Is not blank"
|
|
752
|
-
}
|
|
753
|
-
];
|
|
754
|
-
const props = __props;
|
|
755
|
-
const emit = __emit;
|
|
756
|
-
function valueToString(v) {
|
|
757
|
-
if (Array.isArray(v)) return v.join(", ");
|
|
758
|
-
return String(v ?? "");
|
|
759
|
-
}
|
|
760
|
-
const uniqueValues = computed(() => {
|
|
761
|
-
const values = props.distinctValues.filter((v) => v != null && v !== "" && !(Array.isArray(v) && v.length === 0)).map((v) => valueToString(v));
|
|
762
|
-
return Array.from(new Set(values)).sort((a, b) => {
|
|
763
|
-
const numA = parseFloat(a);
|
|
764
|
-
const numB = parseFloat(b);
|
|
765
|
-
if (!isNaN(numA) && !isNaN(numB)) return numA - numB;
|
|
766
|
-
return a.localeCompare(b, void 0, {
|
|
767
|
-
numeric: true,
|
|
768
|
-
sensitivity: "base"
|
|
769
|
-
});
|
|
770
|
-
});
|
|
771
|
-
});
|
|
772
|
-
const hasTooManyValues = computed(() => uniqueValues.value.length > MAX_VALUES_FOR_LIST);
|
|
773
|
-
const mode = ref(computed(() => {
|
|
774
|
-
if (!props.currentFilter?.conditions[0]) return hasTooManyValues.value ? "condition" : "values";
|
|
775
|
-
const cond = props.currentFilter.conditions[0];
|
|
776
|
-
if (cond.selectedValues && cond.selectedValues.size > 0) return "values";
|
|
777
|
-
return "condition";
|
|
778
|
-
}).value);
|
|
779
|
-
const initialSelected = computed(() => {
|
|
780
|
-
if (!props.currentFilter?.conditions[0]) return /* @__PURE__ */ new Set();
|
|
781
|
-
return props.currentFilter.conditions[0].selectedValues ?? /* @__PURE__ */ new Set();
|
|
782
|
-
});
|
|
783
|
-
const initialIncludeBlanks = computed(() => {
|
|
784
|
-
if (!props.currentFilter?.conditions[0]) return true;
|
|
785
|
-
return props.currentFilter.conditions[0].includeBlank ?? true;
|
|
786
|
-
});
|
|
787
|
-
const searchText = ref("");
|
|
788
|
-
const selectedValues = ref(new Set(initialSelected.value));
|
|
789
|
-
const includeBlanks = ref(initialIncludeBlanks.value);
|
|
790
|
-
const { conditions, combination, updateCondition, addCondition, removeCondition } = useFilterConditions(computed(() => {
|
|
791
|
-
if (!props.currentFilter?.conditions.length) return [{
|
|
792
|
-
operator: "contains",
|
|
793
|
-
value: "",
|
|
794
|
-
valueTo: "",
|
|
795
|
-
nextOperator: "and"
|
|
796
|
-
}];
|
|
797
|
-
const cond = props.currentFilter.conditions[0];
|
|
798
|
-
if (cond.selectedValues && cond.selectedValues.size > 0) return [{
|
|
799
|
-
operator: "contains",
|
|
800
|
-
value: "",
|
|
801
|
-
valueTo: "",
|
|
802
|
-
nextOperator: "and"
|
|
803
|
-
}];
|
|
804
|
-
const defaultCombination = props.currentFilter.combination ?? "and";
|
|
805
|
-
return props.currentFilter.conditions.map((c) => {
|
|
806
|
-
const tc = c;
|
|
807
|
-
return {
|
|
808
|
-
operator: tc.operator,
|
|
809
|
-
value: tc.value ?? "",
|
|
810
|
-
valueTo: "",
|
|
811
|
-
nextOperator: tc.nextOperator ?? defaultCombination
|
|
812
|
-
};
|
|
813
|
-
});
|
|
814
|
-
}).value, props.currentFilter?.combination ?? "and");
|
|
815
|
-
const displayValues = computed(() => {
|
|
816
|
-
if (!searchText.value) return uniqueValues.value;
|
|
817
|
-
const lower = searchText.value.toLowerCase();
|
|
818
|
-
return uniqueValues.value.filter((v) => v.toLowerCase().includes(lower));
|
|
819
|
-
});
|
|
820
|
-
const hasBlanks = computed(() => {
|
|
821
|
-
return props.distinctValues.some((v) => v == null || v === "");
|
|
822
|
-
});
|
|
823
|
-
const allSelected = computed(() => {
|
|
824
|
-
return displayValues.value.every((v) => selectedValues.value.has(v)) && (!hasBlanks.value || includeBlanks.value);
|
|
825
|
-
});
|
|
826
|
-
function handleSelectAll() {
|
|
827
|
-
selectedValues.value = new Set(displayValues.value);
|
|
828
|
-
if (hasBlanks.value) includeBlanks.value = true;
|
|
829
|
-
}
|
|
830
|
-
function handleDeselectAll() {
|
|
831
|
-
selectedValues.value = /* @__PURE__ */ new Set();
|
|
832
|
-
includeBlanks.value = false;
|
|
833
|
-
}
|
|
834
|
-
function handleValueToggle(value) {
|
|
835
|
-
const next = new Set(selectedValues.value);
|
|
836
|
-
if (next.has(value)) next.delete(value);
|
|
837
|
-
else next.add(value);
|
|
838
|
-
selectedValues.value = next;
|
|
839
|
-
}
|
|
840
|
-
function handleApply() {
|
|
841
|
-
if (mode.value === "values") {
|
|
842
|
-
if (uniqueValues.value.every((v) => selectedValues.value.has(v)) && (!hasBlanks.value || includeBlanks.value)) {
|
|
843
|
-
emit("apply", null);
|
|
844
|
-
return;
|
|
845
|
-
}
|
|
846
|
-
emit("apply", {
|
|
847
|
-
conditions: [{
|
|
848
|
-
type: "text",
|
|
849
|
-
operator: "equals",
|
|
850
|
-
selectedValues: selectedValues.value,
|
|
851
|
-
includeBlank: includeBlanks.value
|
|
852
|
-
}],
|
|
853
|
-
combination: "and"
|
|
854
|
-
});
|
|
855
|
-
} else {
|
|
856
|
-
const validConditions = conditions.value.filter((c) => {
|
|
857
|
-
if (c.operator === "blank" || c.operator === "notBlank") return true;
|
|
858
|
-
return c.value.trim() !== "";
|
|
859
|
-
});
|
|
860
|
-
if (validConditions.length === 0) {
|
|
861
|
-
emit("apply", null);
|
|
862
|
-
return;
|
|
863
|
-
}
|
|
864
|
-
emit("apply", {
|
|
865
|
-
conditions: validConditions.map((c) => ({
|
|
866
|
-
type: "text",
|
|
867
|
-
operator: c.operator,
|
|
868
|
-
value: c.value,
|
|
869
|
-
nextOperator: c.nextOperator
|
|
870
|
-
})),
|
|
871
|
-
combination: "and"
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
function handleClear() {
|
|
876
|
-
emit("apply", null);
|
|
877
|
-
}
|
|
878
|
-
return (_ctx, _cache) => {
|
|
879
|
-
return openBlock(), createElementBlock("div", _hoisted_1$4, [
|
|
880
|
-
createCommentVNode(" Mode toggle - only show if not too many values "),
|
|
881
|
-
!hasTooManyValues.value ? (openBlock(), createElementBlock("div", _hoisted_2$3, [createElementVNode("button", {
|
|
882
|
-
type: "button",
|
|
883
|
-
class: normalizeClass({ active: mode.value === "values" }),
|
|
884
|
-
onClick: _cache[0] || (_cache[0] = ($event) => mode.value = "values")
|
|
885
|
-
}, " Values ", 2), createElementVNode("button", {
|
|
886
|
-
type: "button",
|
|
887
|
-
class: normalizeClass({ active: mode.value === "condition" }),
|
|
888
|
-
onClick: _cache[1] || (_cache[1] = ($event) => mode.value = "condition")
|
|
889
|
-
}, " Condition ", 2)])) : createCommentVNode("v-if", true),
|
|
890
|
-
createCommentVNode(" Too many values message "),
|
|
891
|
-
hasTooManyValues.value && mode.value === "condition" ? (openBlock(), createElementBlock("div", _hoisted_3$3, " Too many unique values (" + toDisplayString(uniqueValues.value.length) + "). Use conditions to filter. ", 1)) : createCommentVNode("v-if", true),
|
|
892
|
-
createCommentVNode(" VALUES MODE "),
|
|
893
|
-
mode.value === "values" ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
894
|
-
createCommentVNode(" Search input "),
|
|
895
|
-
withDirectives(createElementVNode("input", {
|
|
896
|
-
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => searchText.value = $event),
|
|
897
|
-
class: "gp-grid-filter-search",
|
|
898
|
-
type: "text",
|
|
899
|
-
placeholder: "Search...",
|
|
900
|
-
autofocus: ""
|
|
901
|
-
}, null, 512), [[vModelText, searchText.value]]),
|
|
902
|
-
createCommentVNode(" Select all / Deselect all "),
|
|
903
|
-
createElementVNode("div", _hoisted_4$3, [createElementVNode("button", {
|
|
904
|
-
type: "button",
|
|
905
|
-
disabled: allSelected.value,
|
|
906
|
-
onClick: handleSelectAll
|
|
907
|
-
}, " Select All ", 8, _hoisted_5$3), createElementVNode("button", {
|
|
908
|
-
type: "button",
|
|
909
|
-
onClick: handleDeselectAll
|
|
910
|
-
}, " Deselect All ")]),
|
|
911
|
-
createCommentVNode(" Checkbox list "),
|
|
912
|
-
createElementVNode("div", _hoisted_6$2, [
|
|
913
|
-
createCommentVNode(" Blanks option "),
|
|
914
|
-
hasBlanks.value ? (openBlock(), createElementBlock("label", _hoisted_7$2, [createElementVNode("input", {
|
|
915
|
-
type: "checkbox",
|
|
916
|
-
checked: includeBlanks.value,
|
|
917
|
-
onChange: _cache[3] || (_cache[3] = ($event) => includeBlanks.value = !includeBlanks.value)
|
|
918
|
-
}, null, 40, _hoisted_8$2), _cache[5] || (_cache[5] = createElementVNode("span", { class: "gp-grid-filter-blank" }, "(Blanks)", -1))])) : createCommentVNode("v-if", true),
|
|
919
|
-
createCommentVNode(" Values "),
|
|
920
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(displayValues.value, (value) => {
|
|
921
|
-
return openBlock(), createElementBlock("label", {
|
|
922
|
-
key: value,
|
|
923
|
-
class: "gp-grid-filter-option"
|
|
924
|
-
}, [createElementVNode("input", {
|
|
925
|
-
type: "checkbox",
|
|
926
|
-
checked: selectedValues.value.has(value),
|
|
927
|
-
onChange: ($event) => handleValueToggle(value)
|
|
928
|
-
}, null, 40, _hoisted_9$2), createElementVNode("span", null, toDisplayString(value), 1)]);
|
|
929
|
-
}), 128))
|
|
930
|
-
])
|
|
931
|
-
], 64)) : createCommentVNode("v-if", true),
|
|
932
|
-
createCommentVNode(" CONDITION MODE "),
|
|
933
|
-
mode.value === "condition" ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [
|
|
934
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(conditions), (cond, index) => {
|
|
935
|
-
return openBlock(), createElementBlock("div", {
|
|
936
|
-
key: index,
|
|
937
|
-
class: "gp-grid-filter-condition"
|
|
938
|
-
}, [
|
|
939
|
-
createCommentVNode(" Combination toggle (AND/OR) for conditions after the first "),
|
|
940
|
-
index > 0 ? (openBlock(), createElementBlock("div", _hoisted_10$2, [createElementVNode("button", {
|
|
941
|
-
type: "button",
|
|
942
|
-
class: normalizeClass({ active: unref(conditions)[index - 1]?.nextOperator === "and" }),
|
|
943
|
-
onClick: ($event) => unref(updateCondition)(index - 1, { nextOperator: "and" })
|
|
944
|
-
}, " AND ", 10, _hoisted_11), createElementVNode("button", {
|
|
945
|
-
type: "button",
|
|
946
|
-
class: normalizeClass({ active: unref(conditions)[index - 1]?.nextOperator === "or" }),
|
|
947
|
-
onClick: ($event) => unref(updateCondition)(index - 1, { nextOperator: "or" })
|
|
948
|
-
}, " OR ", 10, _hoisted_12)])) : createCommentVNode("v-if", true),
|
|
949
|
-
createElementVNode("div", _hoisted_13, [
|
|
950
|
-
createCommentVNode(" Operator select "),
|
|
951
|
-
createElementVNode("select", {
|
|
952
|
-
value: cond.operator,
|
|
953
|
-
autofocus: index === 0,
|
|
954
|
-
onChange: ($event) => unref(updateCondition)(index, { operator: $event.target.value })
|
|
955
|
-
}, [(openBlock(), createElementBlock(Fragment, null, renderList(OPERATORS, (op) => {
|
|
956
|
-
return createElementVNode("option", {
|
|
957
|
-
key: op.value,
|
|
958
|
-
value: op.value
|
|
959
|
-
}, toDisplayString(op.label), 9, _hoisted_15);
|
|
960
|
-
}), 64))], 40, _hoisted_14),
|
|
961
|
-
createCommentVNode(" Text input (hidden for blank/notBlank) "),
|
|
962
|
-
cond.operator !== "blank" && cond.operator !== "notBlank" ? (openBlock(), createElementBlock("input", {
|
|
963
|
-
key: 0,
|
|
964
|
-
type: "text",
|
|
965
|
-
value: cond.value,
|
|
966
|
-
placeholder: "Value",
|
|
967
|
-
class: "gp-grid-filter-text-input",
|
|
968
|
-
onInput: ($event) => unref(updateCondition)(index, { value: $event.target.value })
|
|
969
|
-
}, null, 40, _hoisted_16)) : createCommentVNode("v-if", true),
|
|
970
|
-
createCommentVNode(" Remove button (only if more than one condition) "),
|
|
971
|
-
unref(conditions).length > 1 ? (openBlock(), createElementBlock("button", {
|
|
972
|
-
key: 1,
|
|
973
|
-
type: "button",
|
|
974
|
-
class: "gp-grid-filter-remove",
|
|
975
|
-
onClick: ($event) => unref(removeCondition)(index)
|
|
976
|
-
}, " × ", 8, _hoisted_17)) : createCommentVNode("v-if", true)
|
|
977
|
-
])
|
|
978
|
-
]);
|
|
979
|
-
}), 128)),
|
|
980
|
-
createCommentVNode(" Add condition button "),
|
|
981
|
-
createElementVNode("button", {
|
|
982
|
-
type: "button",
|
|
983
|
-
class: "gp-grid-filter-add",
|
|
984
|
-
onClick: _cache[4] || (_cache[4] = ($event) => unref(addCondition)("contains"))
|
|
985
|
-
}, " + Add condition ")
|
|
986
|
-
], 64)) : createCommentVNode("v-if", true),
|
|
987
|
-
createCommentVNode(" Apply/Clear buttons "),
|
|
988
|
-
createElementVNode("div", { class: "gp-grid-filter-buttons" }, [createElementVNode("button", {
|
|
989
|
-
type: "button",
|
|
990
|
-
class: "gp-grid-filter-btn-clear",
|
|
991
|
-
onClick: handleClear
|
|
992
|
-
}, " Clear "), createElementVNode("button", {
|
|
993
|
-
type: "button",
|
|
994
|
-
class: "gp-grid-filter-btn-apply",
|
|
995
|
-
onClick: handleApply
|
|
996
|
-
}, " Apply ")])
|
|
997
|
-
]);
|
|
998
|
-
};
|
|
999
|
-
}
|
|
1000
|
-
});
|
|
1001
|
-
var TextFilterContent_default = _sfc_main$4;
|
|
1002
|
-
|
|
1003
|
-
//#endregion
|
|
1004
|
-
//#region src/components/NumberFilterContent.vue
|
|
1005
|
-
const _hoisted_1$3 = { class: "gp-grid-filter-content gp-grid-filter-number" };
|
|
1006
|
-
const _hoisted_2$2 = {
|
|
1007
|
-
key: 0,
|
|
1008
|
-
class: "gp-grid-filter-combination"
|
|
1009
|
-
};
|
|
1010
|
-
const _hoisted_3$2 = ["onClick"];
|
|
1011
|
-
const _hoisted_4$2 = ["onClick"];
|
|
1012
|
-
const _hoisted_5$2 = { class: "gp-grid-filter-row" };
|
|
1013
|
-
const _hoisted_6$1 = ["value", "onChange"];
|
|
1014
|
-
const _hoisted_7$1 = ["value"];
|
|
1015
|
-
const _hoisted_8$1 = ["value", "onInput"];
|
|
1016
|
-
const _hoisted_9$1 = ["value", "onInput"];
|
|
1017
|
-
const _hoisted_10$1 = ["onClick"];
|
|
1018
|
-
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
1019
|
-
__name: "NumberFilterContent",
|
|
1020
|
-
props: { currentFilter: {} },
|
|
1021
|
-
emits: ["apply", "close"],
|
|
1022
|
-
setup(__props, { emit: __emit }) {
|
|
1023
|
-
const OPERATORS = [
|
|
1024
|
-
{
|
|
1025
|
-
value: "=",
|
|
1026
|
-
label: "="
|
|
1027
|
-
},
|
|
1028
|
-
{
|
|
1029
|
-
value: "!=",
|
|
1030
|
-
label: "≠"
|
|
1031
|
-
},
|
|
1032
|
-
{
|
|
1033
|
-
value: ">",
|
|
1034
|
-
label: ">"
|
|
1035
|
-
},
|
|
1036
|
-
{
|
|
1037
|
-
value: "<",
|
|
1038
|
-
label: "<"
|
|
1039
|
-
},
|
|
1040
|
-
{
|
|
1041
|
-
value: ">=",
|
|
1042
|
-
label: "≥"
|
|
1043
|
-
},
|
|
1044
|
-
{
|
|
1045
|
-
value: "<=",
|
|
1046
|
-
label: "≤"
|
|
1047
|
-
},
|
|
1048
|
-
{
|
|
1049
|
-
value: "between",
|
|
1050
|
-
label: "↔"
|
|
1051
|
-
},
|
|
1052
|
-
{
|
|
1053
|
-
value: "blank",
|
|
1054
|
-
label: "Is blank"
|
|
1055
|
-
},
|
|
1056
|
-
{
|
|
1057
|
-
value: "notBlank",
|
|
1058
|
-
label: "Not blank"
|
|
1059
|
-
}
|
|
1060
|
-
];
|
|
1061
|
-
const props = __props;
|
|
1062
|
-
const emit = __emit;
|
|
1063
|
-
const { conditions, combination, updateCondition, addCondition, removeCondition } = useFilterConditions(computed(() => {
|
|
1064
|
-
if (!props.currentFilter?.conditions.length) return [{
|
|
1065
|
-
operator: "=",
|
|
1066
|
-
value: "",
|
|
1067
|
-
valueTo: "",
|
|
1068
|
-
nextOperator: "and"
|
|
1069
|
-
}];
|
|
1070
|
-
const defaultCombination = props.currentFilter.combination ?? "and";
|
|
1071
|
-
return props.currentFilter.conditions.map((c) => {
|
|
1072
|
-
const cond = c;
|
|
1073
|
-
return {
|
|
1074
|
-
operator: cond.operator,
|
|
1075
|
-
value: cond.value != null ? String(cond.value) : "",
|
|
1076
|
-
valueTo: cond.valueTo != null ? String(cond.valueTo) : "",
|
|
1077
|
-
nextOperator: cond.nextOperator ?? defaultCombination
|
|
1078
|
-
};
|
|
1079
|
-
});
|
|
1080
|
-
}).value, props.currentFilter?.combination ?? "and");
|
|
1081
|
-
function handleApply() {
|
|
1082
|
-
const validConditions = conditions.value.filter((c) => {
|
|
1083
|
-
if (c.operator === "blank" || c.operator === "notBlank") return true;
|
|
1084
|
-
if (c.operator === "between") return c.value !== "" && c.valueTo !== "";
|
|
1085
|
-
return c.value !== "";
|
|
1086
|
-
});
|
|
1087
|
-
if (validConditions.length === 0) {
|
|
1088
|
-
emit("apply", null);
|
|
1089
|
-
return;
|
|
1090
|
-
}
|
|
1091
|
-
emit("apply", {
|
|
1092
|
-
conditions: validConditions.map((c) => ({
|
|
1093
|
-
type: "number",
|
|
1094
|
-
operator: c.operator,
|
|
1095
|
-
value: c.value ? parseFloat(c.value) : void 0,
|
|
1096
|
-
valueTo: c.valueTo ? parseFloat(c.valueTo) : void 0,
|
|
1097
|
-
nextOperator: c.nextOperator
|
|
1098
|
-
})),
|
|
1099
|
-
combination: "and"
|
|
1100
|
-
});
|
|
1101
|
-
}
|
|
1102
|
-
function handleClear() {
|
|
1103
|
-
emit("apply", null);
|
|
1104
|
-
}
|
|
1105
|
-
return (_ctx, _cache) => {
|
|
1106
|
-
return openBlock(), createElementBlock("div", _hoisted_1$3, [
|
|
1107
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(conditions), (cond, index) => {
|
|
1108
|
-
return openBlock(), createElementBlock("div", {
|
|
1109
|
-
key: index,
|
|
1110
|
-
class: "gp-grid-filter-condition"
|
|
1111
|
-
}, [
|
|
1112
|
-
createCommentVNode(" Combination toggle (AND/OR) for conditions after the first "),
|
|
1113
|
-
index > 0 ? (openBlock(), createElementBlock("div", _hoisted_2$2, [createElementVNode("button", {
|
|
1114
|
-
type: "button",
|
|
1115
|
-
class: normalizeClass({ active: unref(conditions)[index - 1]?.nextOperator === "and" }),
|
|
1116
|
-
onClick: ($event) => unref(updateCondition)(index - 1, { nextOperator: "and" })
|
|
1117
|
-
}, " AND ", 10, _hoisted_3$2), createElementVNode("button", {
|
|
1118
|
-
type: "button",
|
|
1119
|
-
class: normalizeClass({ active: unref(conditions)[index - 1]?.nextOperator === "or" }),
|
|
1120
|
-
onClick: ($event) => unref(updateCondition)(index - 1, { nextOperator: "or" })
|
|
1121
|
-
}, " OR ", 10, _hoisted_4$2)])) : createCommentVNode("v-if", true),
|
|
1122
|
-
createElementVNode("div", _hoisted_5$2, [
|
|
1123
|
-
createCommentVNode(" Operator select "),
|
|
1124
|
-
createElementVNode("select", {
|
|
1125
|
-
value: cond.operator,
|
|
1126
|
-
onChange: ($event) => unref(updateCondition)(index, { operator: $event.target.value })
|
|
1127
|
-
}, [(openBlock(), createElementBlock(Fragment, null, renderList(OPERATORS, (op) => {
|
|
1128
|
-
return createElementVNode("option", {
|
|
1129
|
-
key: op.value,
|
|
1130
|
-
value: op.value
|
|
1131
|
-
}, toDisplayString(op.label), 9, _hoisted_7$1);
|
|
1132
|
-
}), 64))], 40, _hoisted_6$1),
|
|
1133
|
-
createCommentVNode(" Number input (hidden for blank/notBlank) "),
|
|
1134
|
-
cond.operator !== "blank" && cond.operator !== "notBlank" ? (openBlock(), createElementBlock("input", {
|
|
1135
|
-
key: 0,
|
|
1136
|
-
type: "number",
|
|
1137
|
-
value: cond.value,
|
|
1138
|
-
placeholder: "Value",
|
|
1139
|
-
onInput: ($event) => unref(updateCondition)(index, { value: $event.target.value })
|
|
1140
|
-
}, null, 40, _hoisted_8$1)) : createCommentVNode("v-if", true),
|
|
1141
|
-
createCommentVNode(" Second number input for \"between\" "),
|
|
1142
|
-
cond.operator === "between" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [_cache[1] || (_cache[1] = createElementVNode("span", { class: "gp-grid-filter-to" }, "to", -1)), createElementVNode("input", {
|
|
1143
|
-
type: "number",
|
|
1144
|
-
value: cond.valueTo,
|
|
1145
|
-
placeholder: "Value",
|
|
1146
|
-
onInput: ($event) => unref(updateCondition)(index, { valueTo: $event.target.value })
|
|
1147
|
-
}, null, 40, _hoisted_9$1)], 64)) : createCommentVNode("v-if", true),
|
|
1148
|
-
createCommentVNode(" Remove button (only if more than one condition) "),
|
|
1149
|
-
unref(conditions).length > 1 ? (openBlock(), createElementBlock("button", {
|
|
1150
|
-
key: 2,
|
|
1151
|
-
type: "button",
|
|
1152
|
-
class: "gp-grid-filter-remove",
|
|
1153
|
-
onClick: ($event) => unref(removeCondition)(index)
|
|
1154
|
-
}, " × ", 8, _hoisted_10$1)) : createCommentVNode("v-if", true)
|
|
1155
|
-
])
|
|
1156
|
-
]);
|
|
1157
|
-
}), 128)),
|
|
1158
|
-
createCommentVNode(" Add condition button "),
|
|
1159
|
-
createElementVNode("button", {
|
|
1160
|
-
type: "button",
|
|
1161
|
-
class: "gp-grid-filter-add",
|
|
1162
|
-
onClick: _cache[0] || (_cache[0] = ($event) => unref(addCondition)("="))
|
|
1163
|
-
}, " + Add condition "),
|
|
1164
|
-
createCommentVNode(" Apply/Clear buttons "),
|
|
1165
|
-
createElementVNode("div", { class: "gp-grid-filter-buttons" }, [createElementVNode("button", {
|
|
1166
|
-
type: "button",
|
|
1167
|
-
class: "gp-grid-filter-btn-clear",
|
|
1168
|
-
onClick: handleClear
|
|
1169
|
-
}, " Clear "), createElementVNode("button", {
|
|
1170
|
-
type: "button",
|
|
1171
|
-
class: "gp-grid-filter-btn-apply",
|
|
1172
|
-
onClick: handleApply
|
|
1173
|
-
}, " Apply ")])
|
|
1174
|
-
]);
|
|
1175
|
-
};
|
|
1176
|
-
}
|
|
1177
|
-
});
|
|
1178
|
-
var NumberFilterContent_default = _sfc_main$3;
|
|
1179
|
-
|
|
1180
|
-
//#endregion
|
|
1181
|
-
//#region src/components/DateFilterContent.vue
|
|
1182
|
-
const _hoisted_1$2 = { class: "gp-grid-filter-content gp-grid-filter-date" };
|
|
1183
|
-
const _hoisted_2$1 = {
|
|
1184
|
-
key: 0,
|
|
1185
|
-
class: "gp-grid-filter-combination"
|
|
1186
|
-
};
|
|
1187
|
-
const _hoisted_3$1 = ["onClick"];
|
|
1188
|
-
const _hoisted_4$1 = ["onClick"];
|
|
1189
|
-
const _hoisted_5$1 = { class: "gp-grid-filter-row" };
|
|
1190
|
-
const _hoisted_6 = ["value", "onChange"];
|
|
1191
|
-
const _hoisted_7 = ["value"];
|
|
1192
|
-
const _hoisted_8 = ["value", "onInput"];
|
|
1193
|
-
const _hoisted_9 = ["value", "onInput"];
|
|
1194
|
-
const _hoisted_10 = ["onClick"];
|
|
1195
|
-
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
1196
|
-
__name: "DateFilterContent",
|
|
1197
|
-
props: { currentFilter: {} },
|
|
1198
|
-
emits: ["apply", "close"],
|
|
1199
|
-
setup(__props, { emit: __emit }) {
|
|
1200
|
-
const OPERATORS = [
|
|
1201
|
-
{
|
|
1202
|
-
value: "=",
|
|
1203
|
-
label: "="
|
|
1204
|
-
},
|
|
1205
|
-
{
|
|
1206
|
-
value: "!=",
|
|
1207
|
-
label: "≠"
|
|
1208
|
-
},
|
|
1209
|
-
{
|
|
1210
|
-
value: ">",
|
|
1211
|
-
label: ">"
|
|
1212
|
-
},
|
|
1213
|
-
{
|
|
1214
|
-
value: "<",
|
|
1215
|
-
label: "<"
|
|
1216
|
-
},
|
|
1217
|
-
{
|
|
1218
|
-
value: "between",
|
|
1219
|
-
label: "↔"
|
|
1220
|
-
},
|
|
1221
|
-
{
|
|
1222
|
-
value: "blank",
|
|
1223
|
-
label: "Is blank"
|
|
1224
|
-
},
|
|
1225
|
-
{
|
|
1226
|
-
value: "notBlank",
|
|
1227
|
-
label: "Not blank"
|
|
1228
|
-
}
|
|
1229
|
-
];
|
|
1230
|
-
const props = __props;
|
|
1231
|
-
const emit = __emit;
|
|
1232
|
-
function formatDateForInput(date) {
|
|
1233
|
-
if (!date) return "";
|
|
1234
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
1235
|
-
if (isNaN(d.getTime())) return "";
|
|
1236
|
-
return d.toISOString().split("T")[0];
|
|
1237
|
-
}
|
|
1238
|
-
const { conditions, combination, updateCondition, addCondition, removeCondition } = useFilterConditions(computed(() => {
|
|
1239
|
-
if (!props.currentFilter?.conditions.length) return [{
|
|
1240
|
-
operator: "=",
|
|
1241
|
-
value: "",
|
|
1242
|
-
valueTo: "",
|
|
1243
|
-
nextOperator: "and"
|
|
1244
|
-
}];
|
|
1245
|
-
const defaultCombination = props.currentFilter.combination ?? "and";
|
|
1246
|
-
return props.currentFilter.conditions.map((c) => {
|
|
1247
|
-
const cond = c;
|
|
1248
|
-
return {
|
|
1249
|
-
operator: cond.operator,
|
|
1250
|
-
value: formatDateForInput(cond.value),
|
|
1251
|
-
valueTo: formatDateForInput(cond.valueTo),
|
|
1252
|
-
nextOperator: cond.nextOperator ?? defaultCombination
|
|
1253
|
-
};
|
|
1254
|
-
});
|
|
1255
|
-
}).value, props.currentFilter?.combination ?? "and");
|
|
1256
|
-
function handleApply() {
|
|
1257
|
-
const validConditions = conditions.value.filter((c) => {
|
|
1258
|
-
if (c.operator === "blank" || c.operator === "notBlank") return true;
|
|
1259
|
-
if (c.operator === "between") return c.value !== "" && c.valueTo !== "";
|
|
1260
|
-
return c.value !== "";
|
|
1261
|
-
});
|
|
1262
|
-
if (validConditions.length === 0) {
|
|
1263
|
-
emit("apply", null);
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
|
-
emit("apply", {
|
|
1267
|
-
conditions: validConditions.map((c) => ({
|
|
1268
|
-
type: "date",
|
|
1269
|
-
operator: c.operator,
|
|
1270
|
-
value: c.value || void 0,
|
|
1271
|
-
valueTo: c.valueTo || void 0,
|
|
1272
|
-
nextOperator: c.nextOperator
|
|
1273
|
-
})),
|
|
1274
|
-
combination: "and"
|
|
1275
|
-
});
|
|
1276
|
-
}
|
|
1277
|
-
function handleClear() {
|
|
1278
|
-
emit("apply", null);
|
|
1279
|
-
}
|
|
1280
|
-
return (_ctx, _cache) => {
|
|
1281
|
-
return openBlock(), createElementBlock("div", _hoisted_1$2, [
|
|
1282
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(conditions), (cond, index) => {
|
|
1283
|
-
return openBlock(), createElementBlock("div", {
|
|
1284
|
-
key: index,
|
|
1285
|
-
class: "gp-grid-filter-condition"
|
|
1286
|
-
}, [
|
|
1287
|
-
createCommentVNode(" Combination toggle (AND/OR) for conditions after the first "),
|
|
1288
|
-
index > 0 ? (openBlock(), createElementBlock("div", _hoisted_2$1, [createElementVNode("button", {
|
|
1289
|
-
type: "button",
|
|
1290
|
-
class: normalizeClass({ active: unref(conditions)[index - 1]?.nextOperator === "and" }),
|
|
1291
|
-
onClick: ($event) => unref(updateCondition)(index - 1, { nextOperator: "and" })
|
|
1292
|
-
}, " AND ", 10, _hoisted_3$1), createElementVNode("button", {
|
|
1293
|
-
type: "button",
|
|
1294
|
-
class: normalizeClass({ active: unref(conditions)[index - 1]?.nextOperator === "or" }),
|
|
1295
|
-
onClick: ($event) => unref(updateCondition)(index - 1, { nextOperator: "or" })
|
|
1296
|
-
}, " OR ", 10, _hoisted_4$1)])) : createCommentVNode("v-if", true),
|
|
1297
|
-
createElementVNode("div", _hoisted_5$1, [
|
|
1298
|
-
createCommentVNode(" Operator select "),
|
|
1299
|
-
createElementVNode("select", {
|
|
1300
|
-
value: cond.operator,
|
|
1301
|
-
onChange: ($event) => unref(updateCondition)(index, { operator: $event.target.value })
|
|
1302
|
-
}, [(openBlock(), createElementBlock(Fragment, null, renderList(OPERATORS, (op) => {
|
|
1303
|
-
return createElementVNode("option", {
|
|
1304
|
-
key: op.value,
|
|
1305
|
-
value: op.value
|
|
1306
|
-
}, toDisplayString(op.label), 9, _hoisted_7);
|
|
1307
|
-
}), 64))], 40, _hoisted_6),
|
|
1308
|
-
createCommentVNode(" Date input (hidden for blank/notBlank) "),
|
|
1309
|
-
cond.operator !== "blank" && cond.operator !== "notBlank" ? (openBlock(), createElementBlock("input", {
|
|
1310
|
-
key: 0,
|
|
1311
|
-
type: "date",
|
|
1312
|
-
value: cond.value,
|
|
1313
|
-
onInput: ($event) => unref(updateCondition)(index, { value: $event.target.value })
|
|
1314
|
-
}, null, 40, _hoisted_8)) : createCommentVNode("v-if", true),
|
|
1315
|
-
createCommentVNode(" Second date input for \"between\" "),
|
|
1316
|
-
cond.operator === "between" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [_cache[1] || (_cache[1] = createElementVNode("span", { class: "gp-grid-filter-to" }, "to", -1)), createElementVNode("input", {
|
|
1317
|
-
type: "date",
|
|
1318
|
-
value: cond.valueTo,
|
|
1319
|
-
onInput: ($event) => unref(updateCondition)(index, { valueTo: $event.target.value })
|
|
1320
|
-
}, null, 40, _hoisted_9)], 64)) : createCommentVNode("v-if", true),
|
|
1321
|
-
createCommentVNode(" Remove button (only if more than one condition) "),
|
|
1322
|
-
unref(conditions).length > 1 ? (openBlock(), createElementBlock("button", {
|
|
1323
|
-
key: 2,
|
|
1324
|
-
type: "button",
|
|
1325
|
-
class: "gp-grid-filter-remove",
|
|
1326
|
-
onClick: ($event) => unref(removeCondition)(index)
|
|
1327
|
-
}, " × ", 8, _hoisted_10)) : createCommentVNode("v-if", true)
|
|
1328
|
-
])
|
|
1329
|
-
]);
|
|
1330
|
-
}), 128)),
|
|
1331
|
-
createCommentVNode(" Add condition button "),
|
|
1332
|
-
createElementVNode("button", {
|
|
1333
|
-
type: "button",
|
|
1334
|
-
class: "gp-grid-filter-add",
|
|
1335
|
-
onClick: _cache[0] || (_cache[0] = ($event) => unref(addCondition)("="))
|
|
1336
|
-
}, " + Add condition "),
|
|
1337
|
-
createCommentVNode(" Apply/Clear buttons "),
|
|
1338
|
-
createElementVNode("div", { class: "gp-grid-filter-buttons" }, [createElementVNode("button", {
|
|
1339
|
-
type: "button",
|
|
1340
|
-
class: "gp-grid-filter-btn-clear",
|
|
1341
|
-
onClick: handleClear
|
|
1342
|
-
}, " Clear "), createElementVNode("button", {
|
|
1343
|
-
type: "button",
|
|
1344
|
-
class: "gp-grid-filter-btn-apply",
|
|
1345
|
-
onClick: handleApply
|
|
1346
|
-
}, " Apply ")])
|
|
1347
|
-
]);
|
|
1348
|
-
};
|
|
1349
|
-
}
|
|
1350
|
-
});
|
|
1351
|
-
var DateFilterContent_default = _sfc_main$2;
|
|
1352
|
-
|
|
1353
|
-
//#endregion
|
|
1354
|
-
//#region src/components/FilterPopup.vue
|
|
1355
|
-
const _hoisted_1$1 = { class: "gp-grid-filter-header" };
|
|
1356
|
-
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
1357
|
-
__name: "FilterPopup",
|
|
1358
|
-
props: {
|
|
1359
|
-
column: {},
|
|
1360
|
-
colIndex: {},
|
|
1361
|
-
anchorRect: {},
|
|
1362
|
-
distinctValues: {},
|
|
1363
|
-
currentFilter: {}
|
|
1364
|
-
},
|
|
1365
|
-
emits: ["apply", "close"],
|
|
1366
|
-
setup(__props, { emit: __emit }) {
|
|
1367
|
-
const props = __props;
|
|
1368
|
-
const emit = __emit;
|
|
1369
|
-
const popupRef = ref(null);
|
|
1370
|
-
useFilterPopup(popupRef, {
|
|
1371
|
-
onClose: () => emit("close"),
|
|
1372
|
-
ignoreSelector: ".gp-grid-filter-icon"
|
|
1373
|
-
});
|
|
1374
|
-
const colId = computed(() => props.column.colId ?? props.column.field);
|
|
1375
|
-
function handleApply(filter) {
|
|
1376
|
-
emit("apply", colId.value, filter);
|
|
1377
|
-
emit("close");
|
|
1378
|
-
}
|
|
1379
|
-
function handleClose() {
|
|
1380
|
-
emit("close");
|
|
1381
|
-
}
|
|
1382
|
-
const dataType = computed(() => props.column.cellDataType);
|
|
1383
|
-
computed(() => dataType.value === "text" || dataType.value === "object");
|
|
1384
|
-
const isNumberType = computed(() => dataType.value === "number");
|
|
1385
|
-
const isDateType = computed(() => dataType.value === "date" || dataType.value === "dateString" || dataType.value === "dateTime" || dataType.value === "dateTimeString");
|
|
1386
|
-
const popupStyle = computed(() => ({
|
|
1387
|
-
position: "fixed",
|
|
1388
|
-
top: `${props.anchorRect.top + props.anchorRect.height + 4}px`,
|
|
1389
|
-
left: `${props.anchorRect.left}px`,
|
|
1390
|
-
minWidth: `${Math.max(200, props.anchorRect.width)}px`,
|
|
1391
|
-
zIndex: 1e4
|
|
1392
|
-
}));
|
|
1393
|
-
return (_ctx, _cache) => {
|
|
1394
|
-
return openBlock(), createElementBlock("div", {
|
|
1395
|
-
ref_key: "popupRef",
|
|
1396
|
-
ref: popupRef,
|
|
1397
|
-
class: "gp-grid-filter-popup",
|
|
1398
|
-
style: normalizeStyle(popupStyle.value)
|
|
1399
|
-
}, [
|
|
1400
|
-
createElementVNode("div", _hoisted_1$1, " Filter: " + toDisplayString(__props.column.headerName ?? __props.column.field), 1),
|
|
1401
|
-
createCommentVNode(" Number filter "),
|
|
1402
|
-
isNumberType.value ? (openBlock(), createBlock(NumberFilterContent_default, {
|
|
1403
|
-
key: 0,
|
|
1404
|
-
"current-filter": __props.currentFilter,
|
|
1405
|
-
onApply: handleApply,
|
|
1406
|
-
onClose: handleClose
|
|
1407
|
-
}, null, 8, ["current-filter"])) : isDateType.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Date filter "), createVNode(DateFilterContent_default, {
|
|
1408
|
-
"current-filter": __props.currentFilter,
|
|
1409
|
-
onApply: handleApply,
|
|
1410
|
-
onClose: handleClose
|
|
1411
|
-
}, null, 8, ["current-filter"])], 2112)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [createCommentVNode(" Text filter (default) "), createVNode(TextFilterContent_default, {
|
|
1412
|
-
"distinct-values": __props.distinctValues,
|
|
1413
|
-
"current-filter": __props.currentFilter,
|
|
1414
|
-
onApply: handleApply,
|
|
1415
|
-
onClose: handleClose
|
|
1416
|
-
}, null, 8, ["distinct-values", "current-filter"])], 2112))
|
|
1417
|
-
], 4);
|
|
1418
|
-
};
|
|
1419
|
-
}
|
|
1420
|
-
});
|
|
1421
|
-
var FilterPopup_default = _sfc_main$1;
|
|
1422
|
-
|
|
1423
|
-
//#endregion
|
|
1424
|
-
//#region src/GpGrid.vue
|
|
1425
|
-
const _hoisted_1 = ["data-col-index", "onClick"];
|
|
1426
|
-
const _hoisted_2 = ["onMousedown", "onDblclick"];
|
|
1427
|
-
const _hoisted_3 = {
|
|
1428
|
-
key: 1,
|
|
1429
|
-
class: "gp-grid-loading"
|
|
1430
|
-
};
|
|
1431
|
-
const _hoisted_4 = {
|
|
1432
|
-
key: 2,
|
|
1433
|
-
class: "gp-grid-error"
|
|
1434
|
-
};
|
|
1435
|
-
const _hoisted_5 = {
|
|
1436
|
-
key: 3,
|
|
1437
|
-
class: "gp-grid-empty"
|
|
1438
|
-
};
|
|
1439
|
-
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
1440
|
-
__name: "GpGrid",
|
|
1441
|
-
props: {
|
|
1442
|
-
columns: {},
|
|
1443
|
-
dataSource: {},
|
|
1444
|
-
rowData: {},
|
|
1445
|
-
rowHeight: {},
|
|
1446
|
-
headerHeight: {},
|
|
1447
|
-
overscan: { default: 3 },
|
|
1448
|
-
sortingEnabled: {
|
|
1449
|
-
type: Boolean,
|
|
1450
|
-
default: true
|
|
1451
|
-
},
|
|
1452
|
-
darkMode: {
|
|
1453
|
-
type: Boolean,
|
|
1454
|
-
default: false
|
|
1455
|
-
},
|
|
1456
|
-
wheelDampening: { default: .1 },
|
|
1457
|
-
cellRenderers: { default: () => ({}) },
|
|
1458
|
-
editRenderers: { default: () => ({}) },
|
|
1459
|
-
headerRenderers: { default: () => ({}) },
|
|
1460
|
-
cellRenderer: {},
|
|
1461
|
-
editRenderer: {},
|
|
1462
|
-
headerRenderer: {}
|
|
1463
|
-
},
|
|
1464
|
-
setup(__props) {
|
|
1465
|
-
injectStyles$1();
|
|
1466
|
-
const props = __props;
|
|
1467
|
-
const containerRef = ref(null);
|
|
1468
|
-
const coreRef = shallowRef(null);
|
|
1469
|
-
const { state, applyInstructions } = useGridState();
|
|
1470
|
-
const totalHeaderHeight = computed(() => props.headerHeight ?? props.rowHeight);
|
|
1471
|
-
const columnPositions = computed(() => calculateColumnPositions$1(props.columns));
|
|
1472
|
-
const totalWidth = computed(() => getTotalWidth$1(columnPositions.value));
|
|
1473
|
-
const slotsArray = computed(() => Array.from(state.slots.values()));
|
|
1474
|
-
const { handleCellMouseDown, handleCellDoubleClick, handleFillHandleMouseDown, handleHeaderClick, handleKeyDown, handleWheel, dragState } = useInputHandler(coreRef, containerRef, computed(() => props.columns), {
|
|
1475
|
-
activeCell: computed(() => state.activeCell),
|
|
1476
|
-
selectionRange: computed(() => state.selectionRange),
|
|
1477
|
-
editingCell: computed(() => state.editingCell),
|
|
1478
|
-
filterPopupOpen: computed(() => state.filterPopup?.isOpen ?? false),
|
|
1479
|
-
rowHeight: props.rowHeight,
|
|
1480
|
-
headerHeight: totalHeaderHeight.value,
|
|
1481
|
-
columnPositions,
|
|
1482
|
-
slots: computed(() => state.slots)
|
|
1483
|
-
});
|
|
1484
|
-
const { fillHandlePosition } = useFillHandle({
|
|
1485
|
-
activeCell: computed(() => state.activeCell),
|
|
1486
|
-
selectionRange: computed(() => state.selectionRange),
|
|
1487
|
-
slots: computed(() => state.slots),
|
|
1488
|
-
columns: computed(() => props.columns),
|
|
1489
|
-
columnPositions,
|
|
1490
|
-
rowHeight: props.rowHeight
|
|
1491
|
-
});
|
|
1492
|
-
function handleScroll() {
|
|
1493
|
-
const container = containerRef.value;
|
|
1494
|
-
const core = coreRef.value;
|
|
1495
|
-
if (!container || !core) return;
|
|
1496
|
-
core.setViewport(container.scrollTop, container.scrollLeft, container.clientWidth, container.clientHeight);
|
|
1497
|
-
}
|
|
1498
|
-
function handleFilterApply(colId, filter) {
|
|
1499
|
-
const core = coreRef.value;
|
|
1500
|
-
if (core) core.setFilter(colId, filter);
|
|
1501
|
-
}
|
|
1502
|
-
function handleFilterPopupClose() {
|
|
1503
|
-
const core = coreRef.value;
|
|
1504
|
-
if (core) core.closeFilterPopup();
|
|
1505
|
-
}
|
|
1506
|
-
function getCellClasses(rowIndex, colIndex) {
|
|
1507
|
-
const isEditing = isCellEditing$1(rowIndex, colIndex, state.editingCell);
|
|
1508
|
-
return buildCellClasses$1(isCellActive$1(rowIndex, colIndex, state.activeCell), isCellSelected$1(rowIndex, colIndex, state.selectionRange), isEditing, isCellInFillPreview$1(rowIndex, colIndex, dragState.value.dragType === "fill", dragState.value.fillSourceRange, dragState.value.fillTarget));
|
|
1509
|
-
}
|
|
1510
|
-
onMounted(() => {
|
|
1511
|
-
const dataSource = props.dataSource ?? (props.rowData ? createDataSourceFromArray$1(props.rowData) : createClientDataSource$1([]));
|
|
1512
|
-
const core = new GridCore({
|
|
1513
|
-
columns: props.columns,
|
|
1514
|
-
dataSource,
|
|
1515
|
-
rowHeight: props.rowHeight,
|
|
1516
|
-
headerHeight: totalHeaderHeight.value,
|
|
1517
|
-
overscan: props.overscan,
|
|
1518
|
-
sortingEnabled: props.sortingEnabled
|
|
1519
|
-
});
|
|
1520
|
-
coreRef.value = core;
|
|
1521
|
-
const unsubscribe = core.onBatchInstruction((instructions) => {
|
|
1522
|
-
applyInstructions(instructions);
|
|
1523
|
-
});
|
|
1524
|
-
core.initialize();
|
|
1525
|
-
const container = containerRef.value;
|
|
1526
|
-
if (container) {
|
|
1527
|
-
core.setViewport(container.scrollTop, container.scrollLeft, container.clientWidth, container.clientHeight);
|
|
1528
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
1529
|
-
core.setViewport(container.scrollTop, container.scrollLeft, container.clientWidth, container.clientHeight);
|
|
1530
|
-
});
|
|
1531
|
-
resizeObserver.observe(container);
|
|
1532
|
-
onUnmounted(() => {
|
|
1533
|
-
resizeObserver.disconnect();
|
|
1534
|
-
unsubscribe();
|
|
1535
|
-
coreRef.value = null;
|
|
1536
|
-
});
|
|
1537
|
-
}
|
|
1538
|
-
});
|
|
1539
|
-
watch(() => props.dataSource, (dataSource) => {
|
|
1540
|
-
if (dataSource) {
|
|
1541
|
-
const mutableDataSource = dataSource;
|
|
1542
|
-
if (mutableDataSource.subscribe) {
|
|
1543
|
-
const unsubscribe = mutableDataSource.subscribe(() => {
|
|
1544
|
-
coreRef.value?.refresh();
|
|
1545
|
-
});
|
|
1546
|
-
onUnmounted(() => unsubscribe());
|
|
1547
|
-
}
|
|
1548
|
-
}
|
|
1549
|
-
}, { immediate: true });
|
|
1550
|
-
return (_ctx, _cache) => {
|
|
1551
|
-
return openBlock(), createElementBlock("div", {
|
|
1552
|
-
ref_key: "containerRef",
|
|
1553
|
-
ref: containerRef,
|
|
1554
|
-
class: normalizeClass(["gp-grid-container", { "gp-grid-container--dark": __props.darkMode }]),
|
|
1555
|
-
style: {
|
|
1556
|
-
"width": "100%",
|
|
1557
|
-
"height": "100%",
|
|
1558
|
-
"overflow": "auto",
|
|
1559
|
-
"position": "relative"
|
|
1560
|
-
},
|
|
1561
|
-
tabindex: "0",
|
|
1562
|
-
onScroll: handleScroll,
|
|
1563
|
-
onWheel: _cache[1] || (_cache[1] = (e) => unref(handleWheel)(e, __props.wheelDampening)),
|
|
1564
|
-
onKeydown: _cache[2] || (_cache[2] = (...args) => unref(handleKeyDown) && unref(handleKeyDown)(...args))
|
|
1565
|
-
}, [
|
|
1566
|
-
createCommentVNode(" Content sizer "),
|
|
1567
|
-
createElementVNode("div", { style: normalizeStyle({
|
|
1568
|
-
width: `${Math.max(unref(state).contentWidth, totalWidth.value)}px`,
|
|
1569
|
-
height: `${Math.max(unref(state).contentHeight, totalHeaderHeight.value)}px`,
|
|
1570
|
-
position: "relative",
|
|
1571
|
-
minWidth: "100%"
|
|
1572
|
-
}) }, [
|
|
1573
|
-
createCommentVNode(" Headers "),
|
|
1574
|
-
createElementVNode("div", {
|
|
1575
|
-
class: "gp-grid-header",
|
|
1576
|
-
style: normalizeStyle({
|
|
1577
|
-
position: "sticky",
|
|
1578
|
-
top: 0,
|
|
1579
|
-
left: 0,
|
|
1580
|
-
height: `${totalHeaderHeight.value}px`,
|
|
1581
|
-
width: `${Math.max(unref(state).contentWidth, totalWidth.value)}px`,
|
|
1582
|
-
minWidth: "100%",
|
|
1583
|
-
zIndex: 100
|
|
1584
|
-
})
|
|
1585
|
-
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column, colIndex) => {
|
|
1586
|
-
return openBlock(), createElementBlock("div", {
|
|
1587
|
-
key: column.colId ?? column.field,
|
|
1588
|
-
class: "gp-grid-header-cell",
|
|
1589
|
-
"data-col-index": colIndex,
|
|
1590
|
-
style: normalizeStyle({
|
|
1591
|
-
position: "absolute",
|
|
1592
|
-
left: `${columnPositions.value[colIndex]}px`,
|
|
1593
|
-
top: 0,
|
|
1594
|
-
width: `${column.width}px`,
|
|
1595
|
-
height: `${totalHeaderHeight.value}px`,
|
|
1596
|
-
background: "transparent"
|
|
1597
|
-
}),
|
|
1598
|
-
onClick: (e) => unref(handleHeaderClick)(colIndex, e)
|
|
1599
|
-
}, [(openBlock(), createBlock(resolveDynamicComponent(unref(renderHeader)({
|
|
1600
|
-
column,
|
|
1601
|
-
colIndex,
|
|
1602
|
-
sortDirection: unref(state).headers.get(colIndex)?.sortDirection,
|
|
1603
|
-
sortIndex: unref(state).headers.get(colIndex)?.sortIndex,
|
|
1604
|
-
sortable: unref(state).headers.get(colIndex)?.sortable ?? true,
|
|
1605
|
-
filterable: unref(state).headers.get(colIndex)?.filterable ?? true,
|
|
1606
|
-
hasFilter: unref(state).headers.get(colIndex)?.hasFilter ?? false,
|
|
1607
|
-
core: coreRef.value,
|
|
1608
|
-
container: containerRef.value,
|
|
1609
|
-
headerRenderers: __props.headerRenderers ?? {},
|
|
1610
|
-
globalHeaderRenderer: __props.headerRenderer
|
|
1611
|
-
}))))], 12, _hoisted_1);
|
|
1612
|
-
}), 128))], 4),
|
|
1613
|
-
createCommentVNode(" Row slots "),
|
|
1614
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(slotsArray.value.filter((s) => s.rowIndex >= 0), (slot) => {
|
|
1615
|
-
return openBlock(), createElementBlock("div", {
|
|
1616
|
-
key: slot.slotId,
|
|
1617
|
-
class: normalizeClass(["gp-grid-row", { "gp-grid-row--even": slot.rowIndex % 2 === 0 }]),
|
|
1618
|
-
style: normalizeStyle({
|
|
1619
|
-
position: "absolute",
|
|
1620
|
-
top: 0,
|
|
1621
|
-
left: 0,
|
|
1622
|
-
transform: `translateY(${slot.translateY}px)`,
|
|
1623
|
-
width: `${Math.max(unref(state).contentWidth, totalWidth.value)}px`,
|
|
1624
|
-
height: `${__props.rowHeight}px`
|
|
1625
|
-
})
|
|
1626
|
-
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.columns, (column, colIndex) => {
|
|
1627
|
-
return openBlock(), createElementBlock("div", {
|
|
1628
|
-
key: `${slot.slotId}-${colIndex}`,
|
|
1629
|
-
class: normalizeClass(getCellClasses(slot.rowIndex, colIndex)),
|
|
1630
|
-
style: normalizeStyle({
|
|
1631
|
-
position: "absolute",
|
|
1632
|
-
left: `${columnPositions.value[colIndex]}px`,
|
|
1633
|
-
top: 0,
|
|
1634
|
-
width: `${column.width}px`,
|
|
1635
|
-
height: `${__props.rowHeight}px`
|
|
1636
|
-
}),
|
|
1637
|
-
onMousedown: (e) => unref(handleCellMouseDown)(slot.rowIndex, colIndex, e),
|
|
1638
|
-
onDblclick: () => unref(handleCellDoubleClick)(slot.rowIndex, colIndex)
|
|
1639
|
-
}, [createCommentVNode(" Edit mode "), unref(isCellEditing$1)(slot.rowIndex, colIndex, unref(state).editingCell) && unref(state).editingCell ? (openBlock(), createBlock(resolveDynamicComponent(unref(renderEditCell)({
|
|
1640
|
-
column,
|
|
1641
|
-
rowData: slot.rowData,
|
|
1642
|
-
rowIndex: slot.rowIndex,
|
|
1643
|
-
colIndex,
|
|
1644
|
-
initialValue: unref(state).editingCell.initialValue,
|
|
1645
|
-
core: coreRef.value,
|
|
1646
|
-
editRenderers: __props.editRenderers ?? {},
|
|
1647
|
-
globalEditRenderer: __props.editRenderer
|
|
1648
|
-
})), { key: 0 })) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" View mode "), (openBlock(), createBlock(resolveDynamicComponent(unref(renderCell)({
|
|
1649
|
-
column,
|
|
1650
|
-
rowData: slot.rowData,
|
|
1651
|
-
rowIndex: slot.rowIndex,
|
|
1652
|
-
colIndex,
|
|
1653
|
-
isActive: unref(isCellActive$1)(slot.rowIndex, colIndex, unref(state).activeCell),
|
|
1654
|
-
isSelected: unref(isCellSelected$1)(slot.rowIndex, colIndex, unref(state).selectionRange),
|
|
1655
|
-
isEditing: false,
|
|
1656
|
-
cellRenderers: __props.cellRenderers ?? {},
|
|
1657
|
-
globalCellRenderer: __props.cellRenderer
|
|
1658
|
-
}))))], 64))], 46, _hoisted_2);
|
|
1659
|
-
}), 128))], 6);
|
|
1660
|
-
}), 128)),
|
|
1661
|
-
createCommentVNode(" Fill handle "),
|
|
1662
|
-
unref(fillHandlePosition) && !unref(state).editingCell ? (openBlock(), createElementBlock("div", {
|
|
1663
|
-
key: 0,
|
|
1664
|
-
class: "gp-grid-fill-handle",
|
|
1665
|
-
style: normalizeStyle({
|
|
1666
|
-
position: "absolute",
|
|
1667
|
-
top: `${unref(fillHandlePosition).top}px`,
|
|
1668
|
-
left: `${unref(fillHandlePosition).left}px`,
|
|
1669
|
-
zIndex: 200
|
|
1670
|
-
}),
|
|
1671
|
-
onMousedown: _cache[0] || (_cache[0] = (...args) => unref(handleFillHandleMouseDown) && unref(handleFillHandleMouseDown)(...args))
|
|
1672
|
-
}, null, 36)) : createCommentVNode("v-if", true),
|
|
1673
|
-
createCommentVNode(" Loading indicator "),
|
|
1674
|
-
unref(state).isLoading ? (openBlock(), createElementBlock("div", _hoisted_3, [..._cache[3] || (_cache[3] = [createElementVNode("div", { class: "gp-grid-loading-spinner" }, null, -1), createTextVNode(" Loading... ", -1)])])) : createCommentVNode("v-if", true),
|
|
1675
|
-
createCommentVNode(" Error message "),
|
|
1676
|
-
unref(state).error ? (openBlock(), createElementBlock("div", _hoisted_4, " Error: " + toDisplayString(unref(state).error), 1)) : createCommentVNode("v-if", true),
|
|
1677
|
-
createCommentVNode(" Empty state "),
|
|
1678
|
-
!unref(state).isLoading && !unref(state).error && unref(state).totalRows === 0 ? (openBlock(), createElementBlock("div", _hoisted_5, " No data to display ")) : createCommentVNode("v-if", true)
|
|
1679
|
-
], 4),
|
|
1680
|
-
createCommentVNode(" Filter Popup "),
|
|
1681
|
-
unref(state).filterPopup?.isOpen && unref(state).filterPopup.column && unref(state).filterPopup.anchorRect ? (openBlock(), createBlock(FilterPopup_default, {
|
|
1682
|
-
key: 0,
|
|
1683
|
-
column: unref(state).filterPopup.column,
|
|
1684
|
-
"col-index": unref(state).filterPopup.colIndex,
|
|
1685
|
-
"anchor-rect": unref(state).filterPopup.anchorRect,
|
|
1686
|
-
"distinct-values": unref(state).filterPopup.distinctValues,
|
|
1687
|
-
"current-filter": unref(state).filterPopup.currentFilter,
|
|
1688
|
-
onApply: handleFilterApply,
|
|
1689
|
-
onClose: handleFilterPopupClose
|
|
1690
|
-
}, null, 8, [
|
|
1691
|
-
"column",
|
|
1692
|
-
"col-index",
|
|
1693
|
-
"anchor-rect",
|
|
1694
|
-
"distinct-values",
|
|
1695
|
-
"current-filter"
|
|
1696
|
-
])) : createCommentVNode("v-if", true)
|
|
1697
|
-
], 34);
|
|
1698
|
-
};
|
|
1699
|
-
}
|
|
1700
|
-
});
|
|
1701
|
-
var GpGrid_default = _sfc_main;
|
|
1702
|
-
|
|
1703
|
-
//#endregion
|
|
1704
|
-
//#region src/composables/useGpGrid.ts
|
|
1705
|
-
/**
|
|
1706
|
-
* Nuxt-friendly composable for using gp-grid.
|
|
1707
|
-
* Returns all the pieces needed to build a custom grid component.
|
|
1708
|
-
*/
|
|
1709
|
-
function useGpGrid(options) {
|
|
1710
|
-
injectStyles$1();
|
|
1711
|
-
const containerRef = ref(null);
|
|
1712
|
-
const coreRef = ref(null);
|
|
1713
|
-
const { state, applyInstructions } = useGridState();
|
|
1714
|
-
const totalHeaderHeight = computed(() => options.headerHeight ?? options.rowHeight);
|
|
1715
|
-
const columnPositions = computed(() => calculateColumnPositions$1(options.columns));
|
|
1716
|
-
const totalWidth = computed(() => getTotalWidth$1(columnPositions.value));
|
|
1717
|
-
const slotsArray = computed(() => Array.from(state.slots.values()));
|
|
1718
|
-
const { handleCellMouseDown, handleCellDoubleClick, handleFillHandleMouseDown, handleHeaderClick, handleKeyDown, handleWheel, dragState } = useInputHandler(coreRef, containerRef, computed(() => options.columns), {
|
|
1719
|
-
activeCell: computed(() => state.activeCell),
|
|
1720
|
-
selectionRange: computed(() => state.selectionRange),
|
|
1721
|
-
editingCell: computed(() => state.editingCell),
|
|
1722
|
-
filterPopupOpen: computed(() => state.filterPopup?.isOpen ?? false),
|
|
1723
|
-
rowHeight: options.rowHeight,
|
|
1724
|
-
headerHeight: totalHeaderHeight.value,
|
|
1725
|
-
columnPositions,
|
|
1726
|
-
slots: computed(() => state.slots)
|
|
1727
|
-
});
|
|
1728
|
-
const handleScroll = () => {
|
|
1729
|
-
const container = containerRef.value;
|
|
1730
|
-
const core = coreRef.value;
|
|
1731
|
-
if (!container || !core) return;
|
|
1732
|
-
core.setViewport(container.scrollTop, container.scrollLeft, container.clientWidth, container.clientHeight);
|
|
1733
|
-
};
|
|
1734
|
-
const handleFilterApply = (colId, filter) => {
|
|
1735
|
-
const core = coreRef.value;
|
|
1736
|
-
if (core) core.setFilter(colId, filter);
|
|
1737
|
-
};
|
|
1738
|
-
const handleFilterPopupClose = () => {
|
|
1739
|
-
const core = coreRef.value;
|
|
1740
|
-
if (core) core.closeFilterPopup();
|
|
1741
|
-
};
|
|
1742
|
-
onMounted(() => {
|
|
1743
|
-
const dataSource = options.dataSource ?? (options.rowData ? createDataSourceFromArray$1(options.rowData) : createClientDataSource$1([]));
|
|
1744
|
-
const core = new GridCore({
|
|
1745
|
-
columns: options.columns,
|
|
1746
|
-
dataSource,
|
|
1747
|
-
rowHeight: options.rowHeight,
|
|
1748
|
-
headerHeight: totalHeaderHeight.value,
|
|
1749
|
-
overscan: options.overscan ?? 3,
|
|
1750
|
-
sortingEnabled: options.sortingEnabled ?? true
|
|
1751
|
-
});
|
|
1752
|
-
coreRef.value = core;
|
|
1753
|
-
const unsubscribe = core.onBatchInstruction((instructions) => {
|
|
1754
|
-
applyInstructions(instructions);
|
|
1755
|
-
});
|
|
1756
|
-
core.initialize();
|
|
1757
|
-
const container = containerRef.value;
|
|
1758
|
-
if (container) {
|
|
1759
|
-
core.setViewport(container.scrollTop, container.scrollLeft, container.clientWidth, container.clientHeight);
|
|
1760
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
1761
|
-
core.setViewport(container.scrollTop, container.scrollLeft, container.clientWidth, container.clientHeight);
|
|
1762
|
-
});
|
|
1763
|
-
resizeObserver.observe(container);
|
|
1764
|
-
onUnmounted(() => {
|
|
1765
|
-
resizeObserver.disconnect();
|
|
1766
|
-
unsubscribe();
|
|
1767
|
-
coreRef.value = null;
|
|
1768
|
-
});
|
|
1769
|
-
}
|
|
1770
|
-
});
|
|
1771
|
-
watch(() => options.dataSource, (dataSource) => {
|
|
1772
|
-
if (dataSource) {
|
|
1773
|
-
const mutableDataSource = dataSource;
|
|
1774
|
-
if (mutableDataSource.subscribe) {
|
|
1775
|
-
const unsubscribe = mutableDataSource.subscribe(() => {
|
|
1776
|
-
coreRef.value?.refresh();
|
|
1777
|
-
});
|
|
1778
|
-
onUnmounted(() => unsubscribe());
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
}, { immediate: true });
|
|
1782
|
-
const { fillHandlePosition } = useFillHandle({
|
|
1783
|
-
activeCell: computed(() => state.activeCell),
|
|
1784
|
-
selectionRange: computed(() => state.selectionRange),
|
|
1785
|
-
slots: computed(() => state.slots),
|
|
1786
|
-
columns: computed(() => options.columns),
|
|
1787
|
-
columnPositions,
|
|
1788
|
-
rowHeight: options.rowHeight
|
|
1789
|
-
});
|
|
1790
|
-
return {
|
|
1791
|
-
containerRef,
|
|
1792
|
-
coreRef,
|
|
1793
|
-
state,
|
|
1794
|
-
slotsArray,
|
|
1795
|
-
totalHeaderHeight,
|
|
1796
|
-
columnPositions,
|
|
1797
|
-
totalWidth,
|
|
1798
|
-
fillHandlePosition,
|
|
1799
|
-
handleScroll,
|
|
1800
|
-
handleCellMouseDown,
|
|
1801
|
-
handleCellDoubleClick,
|
|
1802
|
-
handleFillHandleMouseDown,
|
|
1803
|
-
handleHeaderClick,
|
|
1804
|
-
handleKeyDown,
|
|
1805
|
-
handleWheel,
|
|
1806
|
-
handleFilterApply,
|
|
1807
|
-
handleFilterPopupClose,
|
|
1808
|
-
dragState,
|
|
1809
|
-
isCellSelected: isCellSelected$1,
|
|
1810
|
-
isCellActive: isCellActive$1,
|
|
1811
|
-
isCellEditing: isCellEditing$1,
|
|
1812
|
-
isCellInFillPreview: isCellInFillPreview$1,
|
|
1813
|
-
buildCellClasses: buildCellClasses$1
|
|
1814
|
-
};
|
|
1815
|
-
}
|
|
1816
|
-
|
|
1817
|
-
//#endregion
|
|
1818
|
-
export { GpGrid_default as GpGrid, GpGrid_default as default, buildCellClasses, calculateColumnPositions, createClientDataSource, createDataSourceFromArray, createInitialState, createMutableClientDataSource, createServerDataSource, findColumnAtX, getCellValue, getTotalWidth, gridStyles, injectStyles, isCellActive, isCellEditing, isCellInFillPreview, isCellSelected, isRowVisible, renderCell, renderEditCell, renderHeader, useAutoScroll, useFillHandle, useFilterConditions, useFilterPopup, useGpGrid, useGridState, useInputHandler };
|
|
1819
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import{Fragment as e,computed as t,createBlock as n,createCommentVNode as r,createElementBlock as i,createElementVNode as a,createTextVNode as o,createVNode as s,defineComponent as c,h as l,normalizeClass as u,normalizeStyle as d,onMounted as f,onUnmounted as p,openBlock as m,reactive as h,ref as g,renderList as _,resolveDynamicComponent as v,shallowRef as y,toDisplayString as b,unref as x,vModelText as S,watch as C,withDirectives as w}from"vue";import{GridCore as T,buildCellClasses as E,buildCellClasses as D,calculateColumnPositions as O,calculateColumnPositions as k,createClientDataSource as A,createClientDataSource as j,createDataSourceFromArray as M,createDataSourceFromArray as N,createMutableClientDataSource as P,createServerDataSource as F,findColumnAtX as I,getTotalWidth as L,getTotalWidth as R,gridStyles as z,injectStyles as ee,injectStyles as te,isCellActive as B,isCellActive as V,isCellEditing as H,isCellEditing as U,isCellInFillPreview as W,isCellInFillPreview as ne,isCellSelected as re,isCellSelected as G,isRowVisible as ie}from"gp-grid-core";function K(){return{slots:new Map,activeCell:null,selectionRange:null,editingCell:null,contentWidth:0,contentHeight:0,headers:new Map,filterPopup:null,isLoading:!1,error:null,totalRows:0,visibleRowRange:null}}function ae(e,t){switch(e.type){case`CREATE_SLOT`:t.slots.set(e.slotId,{slotId:e.slotId,rowIndex:-1,rowData:{},translateY:0});break;case`DESTROY_SLOT`:t.slots.delete(e.slotId);break;case`ASSIGN_SLOT`:{let n=t.slots.get(e.slotId);n&&t.slots.set(e.slotId,{...n,rowIndex:e.rowIndex,rowData:e.rowData});break}case`MOVE_SLOT`:{let n=t.slots.get(e.slotId);n&&t.slots.set(e.slotId,{...n,translateY:e.translateY});break}case`SET_ACTIVE_CELL`:t.activeCell=e.position;break;case`SET_SELECTION_RANGE`:t.selectionRange=e.range;break;case`UPDATE_VISIBLE_RANGE`:t.visibleRowRange={start:e.start,end:e.end};break;case`START_EDIT`:t.editingCell={row:e.row,col:e.col,initialValue:e.initialValue};break;case`STOP_EDIT`:t.editingCell=null;break;case`SET_CONTENT_SIZE`:t.contentWidth=e.width,t.contentHeight=e.height;break;case`UPDATE_HEADER`:t.headers.set(e.colIndex,{column:e.column,sortDirection:e.sortDirection,sortIndex:e.sortIndex,sortable:e.sortable,filterable:e.filterable,hasFilter:e.hasFilter});break;case`OPEN_FILTER_POPUP`:t.filterPopup={isOpen:!0,colIndex:e.colIndex,column:e.column,anchorRect:e.anchorRect,distinctValues:e.distinctValues,currentFilter:e.currentFilter};break;case`CLOSE_FILTER_POPUP`:t.filterPopup=null;break;case`DATA_LOADING`:t.isLoading=!0,t.error=null;break;case`DATA_LOADED`:t.isLoading=!1,t.totalRows=e.totalRows;break;case`DATA_ERROR`:t.isLoading=!1,t.error=e.error;break;case`ROWS_ADDED`:case`ROWS_REMOVED`:t.totalRows=e.totalRows;break;case`ROWS_UPDATED`:case`TRANSACTION_PROCESSED`:break}}function q(){let e=h(K());function t(t){for(let n of t)ae(n,e)}function n(){let t=K();e.slots=t.slots,e.activeCell=t.activeCell,e.selectionRange=t.selectionRange,e.editingCell=t.editingCell,e.contentWidth=t.contentWidth,e.contentHeight=t.contentHeight,e.headers=t.headers,e.filterPopup=t.filterPopup,e.isLoading=t.isLoading,e.error=t.error,e.totalRows=t.totalRows,e.visibleRowRange=t.visibleRowRange}return{state:e,applyInstructions:t,reset:n}}function J(e){let t=g(null);function n(n,r){t.value&&clearInterval(t.value),t.value=setInterval(()=>{let t=e.value;t&&(t.scrollTop+=r,t.scrollLeft+=n)},16)}function r(){t.value&&=(clearInterval(t.value),null)}return p(()=>{r()}),{startAutoScroll:n,stopAutoScroll:r}}function oe(e,t){for(let n of e.values())if(n.rowIndex===t)return n;return null}function se(e,t,n,r,i,a){let o=oe(a,n),s=(o?o.translateY:i+n*r)-t.scrollTop,c=s+r,l=i,u=t.clientHeight;if(s<l)t.scrollTop=e.getScrollTopForRow(n);else if(c>u){let a=t.clientHeight-i,o=Math.floor(a/r),s=Math.max(0,n-o+1);t.scrollTop=e.getScrollTopForRow(s)}}function Y(e,t,n,r){let{activeCell:i,selectionRange:a,editingCell:o,filterPopupOpen:s,rowHeight:c,headerHeight:l,columnPositions:u,slots:d}=r,{startAutoScroll:f,stopAutoScroll:m}=J(t),h=g({isDragging:!1,dragType:null,fillSourceRange:null,fillTarget:null});C([()=>l,()=>c,u,()=>n.value.length],()=>{let t=e.value;t?.input&&t.input.updateDeps({getHeaderHeight:()=>l,getRowHeight:()=>c,getColumnPositions:()=>u.value,getColumnCount:()=>n.value.length})},{immediate:!0});function _(){let e=t.value;if(!e)return null;let n=e.getBoundingClientRect();return{top:n.top,left:n.left,width:n.width,height:n.height,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft}}function v(e){return{clientX:e.clientX,clientY:e.clientY,button:e.button,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey}}function y(){let t=t=>{let n=e.value,r=_();if(!n?.input||!r)return;let i=n.input.handleDragMove(v(t),r);i&&(i.autoScroll?f(i.autoScroll.dx,i.autoScroll.dy):m(),h.value=n.input.getDragState())},n=()=>{let r=e.value;r?.input&&(r.input.handleDragEnd(),h.value=r.input.getDragState()),m(),document.removeEventListener(`mousemove`,t),document.removeEventListener(`mouseup`,n)};document.addEventListener(`mousemove`,t),document.addEventListener(`mouseup`,n)}function b(n,r,i){let a=e.value;if(!a?.input)return;let o=a.input.handleCellMouseDown(n,r,v(i));o.focusContainer&&t.value?.focus(),o.startDrag===`selection`&&(a.input.startSelectionDrag(),h.value=a.input.getDragState(),y())}function x(t,n){let r=e.value;r?.input&&r.input.handleCellDoubleClick(t,n)}function S(t){let n=e.value;if(!n?.input)return;let r=n.input.handleFillHandleMouseDown(i.value,a.value,v(t));r.preventDefault&&t.preventDefault(),r.stopPropagation&&t.stopPropagation(),r.startDrag===`fill`&&(h.value=n.input.getDragState(),y())}function w(t,r){let i=e.value;if(!i?.input)return;let a=n.value[t];if(!a)return;let o=a.colId??a.field;i.input.handleHeaderClick(o,r.shiftKey)}function T(n){let r=e.value,a=t.value;if(!r?.input)return;let u=r.input.handleKeyDown({key:n.key,shiftKey:n.shiftKey,ctrlKey:n.ctrlKey,metaKey:n.metaKey},i.value,o.value,s.value);u.preventDefault&&n.preventDefault(),u.scrollToCell&&a&&se(r,a,u.scrollToCell.row,c,l,d.value)}function E(n,r){let i=e.value,a=t.value;if(!i?.input||!a)return;let o=i.input.handleWheel(n.deltaY,n.deltaX,r);o&&(n.preventDefault(),a.scrollTop+=o.dy,a.scrollLeft+=o.dx)}return p(()=>{m()}),{handleCellMouseDown:b,handleCellDoubleClick:x,handleFillHandleMouseDown:S,handleHeaderClick:w,handleKeyDown:T,handleWheel:E,dragState:h}}function X(e){let{activeCell:n,selectionRange:r,slots:i,columns:a,columnPositions:o,rowHeight:s}=e;return{fillHandlePosition:t(()=>{let e=n.value,t=r.value,c=i.value;if(!e&&!t)return null;let l,u,d,f;if(t)l=Math.max(t.startRow,t.endRow),u=Math.max(t.startCol,t.endCol),d=Math.min(t.startCol,t.endCol),f=Math.max(t.startCol,t.endCol);else if(e)l=e.row,u=e.col,d=u,f=u;else return null;let p=a.value;for(let e=d;e<=f;e++){let t=p[e];if(!t||t.editable!==!0)return null}let m=null;for(let e of c.values())if(e.rowIndex===l){m=e.translateY;break}if(m===null)return null;let h=o.value[u]??0,g=p[u]?.width??0;return{top:m+s-5,left:h+g-20}})}}function ce(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function Z(e,t){let n=t.split(`.`),r=e;for(let e of n){if(typeof r!=`object`||!r)return null;r=r[e]}return r??null}function le(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,isActive:a,isSelected:s,isEditing:c,cellRenderers:l,globalCellRenderer:u}=e,d=Z(n,t.field),f={value:d,rowData:n,column:t,rowIndex:r,colIndex:i,isActive:a,isSelected:s,isEditing:c};if(t.cellRenderer&&typeof t.cellRenderer==`string`){let e=l[t.cellRenderer];if(e)return ce(e(f))}return u?ce(u(f)):o(d==null?``:String(d))}function ue(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function Q(e){let{column:t,rowData:n,rowIndex:r,colIndex:i,initialValue:a,core:s,editRenderers:c,globalEditRenderer:u}=e;if(!s)return o(``);let d={value:Z(n,t.field),rowData:n,column:t,rowIndex:r,colIndex:i,isActive:!0,isSelected:!0,isEditing:!0,initialValue:a,onValueChange:e=>s.updateEditValue(e),onCommit:()=>s.commitEdit(),onCancel:()=>s.cancelEdit()};if(t.editRenderer&&typeof t.editRenderer==`string`){let e=c[t.editRenderer];if(e)return ue(e(d))}return u?ue(u(d)):l(`input`,{class:`gp-grid-edit-input`,type:`text`,value:a==null?``:String(a),autofocus:!0,onFocus:e=>e.target.select(),onInput:e=>s.updateEditValue(e.target.value),onKeydown:e=>{e.stopPropagation(),e.key===`Enter`?s.commitEdit():e.key===`Escape`?s.cancelEdit():e.key===`Tab`&&(e.preventDefault(),s.commitEdit(),s.selection.moveFocus(e.shiftKey?`left`:`right`,!1))},onBlur:()=>s.commitEdit()})}function de(e){return e==null||e===``?o(``):typeof e==`string`?o(e):e}function fe(t){let{column:n,colIndex:r,sortDirection:i,sortIndex:a,sortable:o,filterable:s,hasFilter:c,core:u,container:d,headerRenderers:f,globalHeaderRenderer:p}=t,m={column:n,colIndex:r,sortDirection:i,sortIndex:a,sortable:o,filterable:s,hasFilter:c,onSort:(e,t)=>{u&&o&&u.setSort(n.colId??n.field,e,t)},onFilterClick:()=>{if(u&&s){let e=d?.querySelector(`[data-col-index="${r}"]`);if(e){let t=e.getBoundingClientRect();u.openFilterPopup(r,{top:t.top,left:t.left,width:t.width,height:t.height})}}}};if(n.headerRenderer&&typeof n.headerRenderer==`string`){let e=f[n.headerRenderer];if(e)return de(e(m))}if(p)return de(p(m));let h=[l(`span`,{class:`gp-grid-header-text`},n.headerName??n.field)],g=[];if(o){let e=[l(`span`,{class:`gp-grid-sort-arrows-stack`},[l(`svg`,{class:`gp-grid-sort-arrow-up${i===`asc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`},[l(`path`,{d:`M4 0L8 6H0L4 0Z`,fill:`currentColor`})]),l(`svg`,{class:`gp-grid-sort-arrow-down${i===`desc`?` active`:``}`,width:`8`,height:`6`,viewBox:`0 0 8 6`},[l(`path`,{d:`M4 6L0 0H8L4 6Z`,fill:`currentColor`})])])];a!==void 0&&a>0&&e.push(l(`span`,{class:`gp-grid-sort-index`},String(a))),g.push(l(`span`,{class:`gp-grid-sort-arrows`},e))}return s&&g.push(l(`span`,{class:`gp-grid-filter-icon${c?` active`:``}`,onMousedown:e=>{e.stopPropagation(),e.preventDefault(),m.onFilterClick()},onClick:e=>{e.stopPropagation()}},[l(`svg`,{width:`16`,height:`16`,viewBox:`0 0 24 24`,fill:`currentColor`},[l(`path`,{d:`M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z`})])])),g.length>0&&h.push(l(`span`,{class:`gp-grid-header-icons`},g)),l(e,h)}function pe(e,t){let{onClose:n,ignoreSelector:r=`.gp-grid-filter-icon`}=t,i=null,a=null;f(()=>{i=t=>{let i=t.target;r&&i.closest(r)||e.value&&!e.value.contains(i)&&n()},a=e=>{e.key===`Escape`&&n()},requestAnimationFrame(()=>{i&&document.addEventListener(`mousedown`,i),a&&document.addEventListener(`keydown`,a)})}),p(()=>{i&&document.removeEventListener(`mousedown`,i),a&&document.removeEventListener(`keydown`,a)})}function $(e,t=`and`){let n=g([...e]);return{conditions:n,combination:g(t),updateCondition:(e,t)=>{let r=[...n.value];r[e]={...r[e],...t},n.value=r},addCondition:e=>{n.value=[...n.value,{operator:e,value:``,valueTo:``,nextOperator:`and`}]},removeCondition:e=>{n.value=n.value.filter((t,n)=>n!==e)}}}const me={class:`gp-grid-filter-content gp-grid-filter-text`},he={key:0,class:`gp-grid-filter-mode-toggle`},ge={key:1,class:`gp-grid-filter-info`},_e={class:`gp-grid-filter-actions`},ve=[`disabled`],ye={class:`gp-grid-filter-list`},be={key:0,class:`gp-grid-filter-option`},xe=[`checked`],Se=[`checked`,`onChange`],Ce={key:0,class:`gp-grid-filter-combination`},we=[`onClick`],Te=[`onClick`],Ee={class:`gp-grid-filter-row`},De=[`value`,`autofocus`,`onChange`],Oe=[`value`],ke=[`value`,`onInput`],Ae=[`onClick`];var je=c({__name:`TextFilterContent`,props:{distinctValues:{},currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{value:`contains`,label:`Contains`},{value:`notContains`,label:`Does not contain`},{value:`equals`,label:`Equals`},{value:`notEquals`,label:`Does not equal`},{value:`startsWith`,label:`Starts with`},{value:`endsWith`,label:`Ends with`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Is not blank`}],c=n,l=o;function d(e){return Array.isArray(e)?e.join(`, `):String(e??``)}let f=t(()=>{let e=c.distinctValues.filter(e=>e!=null&&e!==``&&!(Array.isArray(e)&&e.length===0)).map(e=>d(e));return Array.from(new Set(e)).sort((e,t)=>{let n=parseFloat(e),r=parseFloat(t);return!isNaN(n)&&!isNaN(r)?n-r:e.localeCompare(t,void 0,{numeric:!0,sensitivity:`base`})})}),p=t(()=>f.value.length>100),h=g(t(()=>{if(!c.currentFilter?.conditions[0])return p.value?`condition`:`values`;let e=c.currentFilter.conditions[0];return e.selectedValues&&e.selectedValues.size>0?`values`:`condition`}).value),v=t(()=>c.currentFilter?.conditions[0]?c.currentFilter.conditions[0].selectedValues??new Set:new Set),y=t(()=>c.currentFilter?.conditions[0]?c.currentFilter.conditions[0].includeBlank??!0:!0),C=g(``),T=g(new Set(v.value)),E=g(y.value),{conditions:D,combination:O,updateCondition:k,addCondition:A,removeCondition:j}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`contains`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.conditions[0];if(e.selectedValues&&e.selectedValues.size>0)return[{operator:`contains`,value:``,valueTo:``,nextOperator:`and`}];let t=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(e=>{let n=e;return{operator:n.operator,value:n.value??``,valueTo:``,nextOperator:n.nextOperator??t}})}).value,c.currentFilter?.combination??`and`),M=t(()=>{if(!C.value)return f.value;let e=C.value.toLowerCase();return f.value.filter(t=>t.toLowerCase().includes(e))}),N=t(()=>c.distinctValues.some(e=>e==null||e===``)),P=t(()=>M.value.every(e=>T.value.has(e))&&(!N.value||E.value));function F(){T.value=new Set(M.value),N.value&&(E.value=!0)}function I(){T.value=new Set,E.value=!1}function L(e){let t=new Set(T.value);t.has(e)?t.delete(e):t.add(e),T.value=t}function R(){if(h.value===`values`){if(f.value.every(e=>T.value.has(e))&&(!N.value||E.value)){l(`apply`,null);return}l(`apply`,{conditions:[{type:`text`,operator:`equals`,selectedValues:T.value,includeBlank:E.value}],combination:`and`})}else{let e=D.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.value.trim()!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{conditions:e.map(e=>({type:`text`,operator:e.operator,value:e.value,nextOperator:e.nextOperator})),combination:`and`})}}function z(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,me,[r(` Mode toggle - only show if not too many values `),p.value?r(`v-if`,!0):(m(),i(`div`,he,[a(`button`,{type:`button`,class:u({active:h.value===`values`}),onClick:n[0]||=e=>h.value=`values`},` Values `,2),a(`button`,{type:`button`,class:u({active:h.value===`condition`}),onClick:n[1]||=e=>h.value=`condition`},` Condition `,2)])),r(` Too many values message `),p.value&&h.value===`condition`?(m(),i(`div`,ge,` Too many unique values (`+b(f.value.length)+`). Use conditions to filter. `,1)):r(`v-if`,!0),r(` VALUES MODE `),h.value===`values`?(m(),i(e,{key:2},[r(` Search input `),w(a(`input`,{"onUpdate:modelValue":n[2]||=e=>C.value=e,class:`gp-grid-filter-search`,type:`text`,placeholder:`Search...`,autofocus:``},null,512),[[S,C.value]]),r(` Select all / Deselect all `),a(`div`,_e,[a(`button`,{type:`button`,disabled:P.value,onClick:F},` Select All `,8,ve),a(`button`,{type:`button`,onClick:I},` Deselect All `)]),r(` Checkbox list `),a(`div`,ye,[r(` Blanks option `),N.value?(m(),i(`label`,be,[a(`input`,{type:`checkbox`,checked:E.value,onChange:n[3]||=e=>E.value=!E.value},null,40,xe),n[5]||=a(`span`,{class:`gp-grid-filter-blank`},`(Blanks)`,-1)])):r(`v-if`,!0),r(` Values `),(m(!0),i(e,null,_(M.value,e=>(m(),i(`label`,{key:e,class:`gp-grid-filter-option`},[a(`input`,{type:`checkbox`,checked:T.value.has(e),onChange:t=>L(e)},null,40,Se),a(`span`,null,b(e),1)]))),128))])],64)):r(`v-if`,!0),r(` CONDITION MODE `),h.value===`condition`?(m(),i(e,{key:3},[(m(!0),i(e,null,_(x(D),(t,n)=>(m(),i(`div`,{key:n,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),n>0?(m(),i(`div`,Ce,[a(`button`,{type:`button`,class:u({active:x(D)[n-1]?.nextOperator===`and`}),onClick:e=>x(k)(n-1,{nextOperator:`and`})},` AND `,10,we),a(`button`,{type:`button`,class:u({active:x(D)[n-1]?.nextOperator===`or`}),onClick:e=>x(k)(n-1,{nextOperator:`or`})},` OR `,10,Te)])):r(`v-if`,!0),a(`div`,Ee,[r(` Operator select `),a(`select`,{value:t.operator,autofocus:n===0,onChange:e=>x(k)(n,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,Oe)),64))],40,De),r(` Text input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`text`,value:t.value,placeholder:`Value`,class:`gp-grid-filter-text-input`,onInput:e=>x(k)(n,{value:e.target.value})},null,40,ke)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(D).length>1?(m(),i(`button`,{key:1,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(j)(n)},` × `,8,Ae)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[4]||=e=>x(A)(`contains`)},` + Add condition `)],64)):r(`v-if`,!0),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:z},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:R},` Apply `)])]))}});const Me={class:`gp-grid-filter-content gp-grid-filter-number`},Ne={key:0,class:`gp-grid-filter-combination`},Pe=[`onClick`],Fe=[`onClick`],Ie={class:`gp-grid-filter-row`},Le=[`value`,`onChange`],Re=[`value`],ze=[`value`,`onInput`],Be=[`value`,`onInput`],Ve=[`onClick`];var He=c({__name:`NumberFilterContent`,props:{currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`>=`,label:`≥`},{value:`<=`,label:`≤`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}],c=n,l=o,{conditions:d,combination:f,updateCondition:p,addCondition:h,removeCondition:g}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(t=>{let n=t;return{operator:n.operator,value:n.value==null?``:String(n.value),valueTo:n.valueTo==null?``:String(n.valueTo),nextOperator:n.nextOperator??e}})}).value,c.currentFilter?.combination??`and`);function v(){let e=d.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{conditions:e.map(e=>({type:`number`,operator:e.operator,value:e.value?parseFloat(e.value):void 0,valueTo:e.valueTo?parseFloat(e.valueTo):void 0,nextOperator:e.nextOperator})),combination:`and`})}function y(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,Me,[(m(!0),i(e,null,_(x(d),(t,o)=>(m(),i(`div`,{key:o,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),o>0?(m(),i(`div`,Ne,[a(`button`,{type:`button`,class:u({active:x(d)[o-1]?.nextOperator===`and`}),onClick:e=>x(p)(o-1,{nextOperator:`and`})},` AND `,10,Pe),a(`button`,{type:`button`,class:u({active:x(d)[o-1]?.nextOperator===`or`}),onClick:e=>x(p)(o-1,{nextOperator:`or`})},` OR `,10,Fe)])):r(`v-if`,!0),a(`div`,Ie,[r(` Operator select `),a(`select`,{value:t.operator,onChange:e=>x(p)(o,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,Re)),64))],40,Le),r(` Number input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`number`,value:t.value,placeholder:`Value`,onInput:e=>x(p)(o,{value:e.target.value})},null,40,ze)):r(`v-if`,!0),r(` Second number input for "between" `),t.operator===`between`?(m(),i(e,{key:1},[n[1]||=a(`span`,{class:`gp-grid-filter-to`},`to`,-1),a(`input`,{type:`number`,value:t.valueTo,placeholder:`Value`,onInput:e=>x(p)(o,{valueTo:e.target.value})},null,40,Be)],64)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(d).length>1?(m(),i(`button`,{key:2,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(g)(o)},` × `,8,Ve)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[0]||=e=>x(h)(`=`)},` + Add condition `),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:y},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:v},` Apply `)])]))}});const Ue={class:`gp-grid-filter-content gp-grid-filter-date`},We={key:0,class:`gp-grid-filter-combination`},Ge=[`onClick`],Ke=[`onClick`],qe={class:`gp-grid-filter-row`},Je=[`value`,`onChange`],Ye=[`value`],Xe=[`value`,`onInput`],Ze=[`value`,`onInput`],Qe=[`onClick`];var $e=c({__name:`DateFilterContent`,props:{currentFilter:{}},emits:[`apply`,`close`],setup(n,{emit:o}){let s=[{value:`=`,label:`=`},{value:`!=`,label:`≠`},{value:`>`,label:`>`},{value:`<`,label:`<`},{value:`between`,label:`↔`},{value:`blank`,label:`Is blank`},{value:`notBlank`,label:`Not blank`}],c=n,l=o;function d(e){if(!e)return``;let t=typeof e==`string`?new Date(e):e;return isNaN(t.getTime())?``:t.toISOString().split(`T`)[0]}let{conditions:f,combination:p,updateCondition:h,addCondition:g,removeCondition:v}=$(t(()=>{if(!c.currentFilter?.conditions.length)return[{operator:`=`,value:``,valueTo:``,nextOperator:`and`}];let e=c.currentFilter.combination??`and`;return c.currentFilter.conditions.map(t=>{let n=t;return{operator:n.operator,value:d(n.value),valueTo:d(n.valueTo),nextOperator:n.nextOperator??e}})}).value,c.currentFilter?.combination??`and`);function y(){let e=f.value.filter(e=>e.operator===`blank`||e.operator===`notBlank`?!0:e.operator===`between`?e.value!==``&&e.valueTo!==``:e.value!==``);if(e.length===0){l(`apply`,null);return}l(`apply`,{conditions:e.map(e=>({type:`date`,operator:e.operator,value:e.value||void 0,valueTo:e.valueTo||void 0,nextOperator:e.nextOperator})),combination:`and`})}function S(){l(`apply`,null)}return(t,n)=>(m(),i(`div`,Ue,[(m(!0),i(e,null,_(x(f),(t,o)=>(m(),i(`div`,{key:o,class:`gp-grid-filter-condition`},[r(` Combination toggle (AND/OR) for conditions after the first `),o>0?(m(),i(`div`,We,[a(`button`,{type:`button`,class:u({active:x(f)[o-1]?.nextOperator===`and`}),onClick:e=>x(h)(o-1,{nextOperator:`and`})},` AND `,10,Ge),a(`button`,{type:`button`,class:u({active:x(f)[o-1]?.nextOperator===`or`}),onClick:e=>x(h)(o-1,{nextOperator:`or`})},` OR `,10,Ke)])):r(`v-if`,!0),a(`div`,qe,[r(` Operator select `),a(`select`,{value:t.operator,onChange:e=>x(h)(o,{operator:e.target.value})},[(m(),i(e,null,_(s,e=>a(`option`,{key:e.value,value:e.value},b(e.label),9,Ye)),64))],40,Je),r(` Date input (hidden for blank/notBlank) `),t.operator!==`blank`&&t.operator!==`notBlank`?(m(),i(`input`,{key:0,type:`date`,value:t.value,onInput:e=>x(h)(o,{value:e.target.value})},null,40,Xe)):r(`v-if`,!0),r(` Second date input for "between" `),t.operator===`between`?(m(),i(e,{key:1},[n[1]||=a(`span`,{class:`gp-grid-filter-to`},`to`,-1),a(`input`,{type:`date`,value:t.valueTo,onInput:e=>x(h)(o,{valueTo:e.target.value})},null,40,Ze)],64)):r(`v-if`,!0),r(` Remove button (only if more than one condition) `),x(f).length>1?(m(),i(`button`,{key:2,type:`button`,class:`gp-grid-filter-remove`,onClick:e=>x(v)(o)},` × `,8,Qe)):r(`v-if`,!0)])]))),128)),r(` Add condition button `),a(`button`,{type:`button`,class:`gp-grid-filter-add`,onClick:n[0]||=e=>x(g)(`=`)},` + Add condition `),r(` Apply/Clear buttons `),a(`div`,{class:`gp-grid-filter-buttons`},[a(`button`,{type:`button`,class:`gp-grid-filter-btn-clear`,onClick:S},` Clear `),a(`button`,{type:`button`,class:`gp-grid-filter-btn-apply`,onClick:y},` Apply `)])]))}});const et={class:`gp-grid-filter-header`};var tt=c({__name:`FilterPopup`,props:{column:{},colIndex:{},anchorRect:{},distinctValues:{},currentFilter:{}},emits:[`apply`,`close`],setup(o,{emit:c}){let l=o,u=c,f=g(null);pe(f,{onClose:()=>u(`close`),ignoreSelector:`.gp-grid-filter-icon`});let p=t(()=>l.column.colId??l.column.field);function h(e){u(`apply`,p.value,e),u(`close`)}function _(){u(`close`)}let v=t(()=>l.column.cellDataType);t(()=>v.value===`text`||v.value===`object`);let y=t(()=>v.value===`number`),x=t(()=>v.value===`date`||v.value===`dateString`||v.value===`dateTime`||v.value===`dateTimeString`),S=t(()=>({position:`fixed`,top:`${l.anchorRect.top+l.anchorRect.height+4}px`,left:`${l.anchorRect.left}px`,minWidth:`${Math.max(200,l.anchorRect.width)}px`,zIndex:1e4}));return(t,c)=>(m(),i(`div`,{ref_key:`popupRef`,ref:f,class:`gp-grid-filter-popup`,style:d(S.value)},[a(`div`,et,` Filter: `+b(o.column.headerName??o.column.field),1),r(` Number filter `),y.value?(m(),n(He,{key:0,"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`current-filter`])):x.value?(m(),i(e,{key:1},[r(` Date filter `),s($e,{"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`current-filter`])],2112)):(m(),i(e,{key:2},[r(` Text filter (default) `),s(je,{"distinct-values":o.distinctValues,"current-filter":o.currentFilter,onApply:h,onClose:_},null,8,[`distinct-values`,`current-filter`])],2112))],4))}});const nt=[`data-col-index`,`onClick`],rt=[`onMousedown`,`onDblclick`],it={key:1,class:`gp-grid-loading`},at={key:2,class:`gp-grid-error`},ot={key:3,class:`gp-grid-empty`};var st=c({__name:`GpGrid`,props:{columns:{},dataSource:{},rowData:{},rowHeight:{},headerHeight:{},overscan:{default:3},sortingEnabled:{type:Boolean,default:!0},darkMode:{type:Boolean,default:!1},wheelDampening:{default:.1},cellRenderers:{default:()=>({})},editRenderers:{default:()=>({})},headerRenderers:{default:()=>({})},cellRenderer:{},editRenderer:{},headerRenderer:{}},setup(s){te();let c=s,l=g(null),h=y(null),{state:S,applyInstructions:w}=q(),E=t(()=>c.headerHeight??c.rowHeight),O=t(()=>k(c.columns)),A=t(()=>R(O.value)),M=t(()=>Array.from(S.slots.values())),{handleCellMouseDown:P,handleCellDoubleClick:F,handleFillHandleMouseDown:I,handleHeaderClick:L,handleKeyDown:z,handleWheel:ee,dragState:B}=Y(h,l,t(()=>c.columns),{activeCell:t(()=>S.activeCell),selectionRange:t(()=>S.selectionRange),editingCell:t(()=>S.editingCell),filterPopupOpen:t(()=>S.filterPopup?.isOpen??!1),rowHeight:c.rowHeight,headerHeight:E.value,columnPositions:O,slots:t(()=>S.slots)}),{fillHandlePosition:H}=X({activeCell:t(()=>S.activeCell),selectionRange:t(()=>S.selectionRange),slots:t(()=>S.slots),columns:t(()=>c.columns),columnPositions:O,rowHeight:c.rowHeight});function W(){let e=l.value,t=h.value;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)}function re(e,t){let n=h.value;n&&n.setFilter(e,t)}function ie(){let e=h.value;e&&e.closeFilterPopup()}function K(e,t){let n=U(e,t,S.editingCell);return D(V(e,t,S.activeCell),G(e,t,S.selectionRange),n,ne(e,t,B.value.dragType===`fill`,B.value.fillSourceRange,B.value.fillTarget))}return f(()=>{let e=c.dataSource??(c.rowData?N(c.rowData):j([])),t=new T({columns:c.columns,dataSource:e,rowHeight:c.rowHeight,headerHeight:E.value,overscan:c.overscan,sortingEnabled:c.sortingEnabled});h.value=t;let n=t.onBatchInstruction(e=>{w(e)});t.initialize();let r=l.value;if(r){t.setViewport(r.scrollTop,r.scrollLeft,r.clientWidth,r.clientHeight);let e=new ResizeObserver(()=>{t.setViewport(r.scrollTop,r.scrollLeft,r.clientWidth,r.clientHeight)});e.observe(r),p(()=>{e.disconnect(),n(),h.value=null})}}),C(()=>c.dataSource,e=>{if(e){let t=e;if(t.subscribe){let e=t.subscribe(()=>{h.value?.refresh()});p(()=>e())}}},{immediate:!0}),(t,c)=>(m(),i(`div`,{ref_key:`containerRef`,ref:l,class:u([`gp-grid-container`,{"gp-grid-container--dark":s.darkMode}]),style:{width:`100%`,height:`100%`,overflow:`auto`,position:`relative`},tabindex:`0`,onScroll:W,onWheel:c[1]||=e=>x(ee)(e,s.wheelDampening),onKeydown:c[2]||=(...e)=>x(z)&&x(z)(...e)},[r(` Content sizer `),a(`div`,{style:d({width:`${Math.max(x(S).contentWidth,A.value)}px`,height:`${Math.max(x(S).contentHeight,E.value)}px`,position:`relative`,minWidth:`100%`})},[r(` Headers `),a(`div`,{class:`gp-grid-header`,style:d({position:`sticky`,top:0,left:0,height:`${E.value}px`,width:`${Math.max(x(S).contentWidth,A.value)}px`,minWidth:`100%`,zIndex:100})},[(m(!0),i(e,null,_(s.columns,(e,t)=>(m(),i(`div`,{key:e.colId??e.field,class:`gp-grid-header-cell`,"data-col-index":t,style:d({position:`absolute`,left:`${O.value[t]}px`,top:0,width:`${e.width}px`,height:`${E.value}px`,background:`transparent`}),onClick:e=>x(L)(t,e)},[(m(),n(v(x(fe)({column:e,colIndex:t,sortDirection:x(S).headers.get(t)?.sortDirection,sortIndex:x(S).headers.get(t)?.sortIndex,sortable:x(S).headers.get(t)?.sortable??!0,filterable:x(S).headers.get(t)?.filterable??!0,hasFilter:x(S).headers.get(t)?.hasFilter??!1,core:h.value,container:l.value,headerRenderers:s.headerRenderers??{},globalHeaderRenderer:s.headerRenderer}))))],12,nt))),128))],4),r(` Row slots `),(m(!0),i(e,null,_(M.value.filter(e=>e.rowIndex>=0),t=>(m(),i(`div`,{key:t.slotId,class:u([`gp-grid-row`,{"gp-grid-row--even":t.rowIndex%2==0}]),style:d({position:`absolute`,top:0,left:0,transform:`translateY(${t.translateY}px)`,width:`${Math.max(x(S).contentWidth,A.value)}px`,height:`${s.rowHeight}px`})},[(m(!0),i(e,null,_(s.columns,(a,o)=>(m(),i(`div`,{key:`${t.slotId}-${o}`,class:u(K(t.rowIndex,o)),style:d({position:`absolute`,left:`${O.value[o]}px`,top:0,width:`${a.width}px`,height:`${s.rowHeight}px`}),onMousedown:e=>x(P)(t.rowIndex,o,e),onDblclick:()=>x(F)(t.rowIndex,o)},[r(` Edit mode `),x(U)(t.rowIndex,o,x(S).editingCell)&&x(S).editingCell?(m(),n(v(x(Q)({column:a,rowData:t.rowData,rowIndex:t.rowIndex,colIndex:o,initialValue:x(S).editingCell.initialValue,core:h.value,editRenderers:s.editRenderers??{},globalEditRenderer:s.editRenderer})),{key:0})):(m(),i(e,{key:1},[r(` View mode `),(m(),n(v(x(le)({column:a,rowData:t.rowData,rowIndex:t.rowIndex,colIndex:o,isActive:x(V)(t.rowIndex,o,x(S).activeCell),isSelected:x(G)(t.rowIndex,o,x(S).selectionRange),isEditing:!1,cellRenderers:s.cellRenderers??{},globalCellRenderer:s.cellRenderer}))))],64))],46,rt))),128))],6))),128)),r(` Fill handle `),x(H)&&!x(S).editingCell?(m(),i(`div`,{key:0,class:`gp-grid-fill-handle`,style:d({position:`absolute`,top:`${x(H).top}px`,left:`${x(H).left}px`,zIndex:200}),onMousedown:c[0]||=(...e)=>x(I)&&x(I)(...e)},null,36)):r(`v-if`,!0),r(` Loading indicator `),x(S).isLoading?(m(),i(`div`,it,[...c[3]||=[a(`div`,{class:`gp-grid-loading-spinner`},null,-1),o(` Loading... `,-1)]])):r(`v-if`,!0),r(` Error message `),x(S).error?(m(),i(`div`,at,` Error: `+b(x(S).error),1)):r(`v-if`,!0),r(` Empty state `),!x(S).isLoading&&!x(S).error&&x(S).totalRows===0?(m(),i(`div`,ot,` No data to display `)):r(`v-if`,!0)],4),r(` Filter Popup `),x(S).filterPopup?.isOpen&&x(S).filterPopup.column&&x(S).filterPopup.anchorRect?(m(),n(tt,{key:0,column:x(S).filterPopup.column,"col-index":x(S).filterPopup.colIndex,"anchor-rect":x(S).filterPopup.anchorRect,"distinct-values":x(S).filterPopup.distinctValues,"current-filter":x(S).filterPopup.currentFilter,onApply:re,onClose:ie},null,8,[`column`,`col-index`,`anchor-rect`,`distinct-values`,`current-filter`])):r(`v-if`,!0)],34))}});function ct(e){te();let n=g(null),r=g(null),{state:i,applyInstructions:a}=q(),o=t(()=>e.headerHeight??e.rowHeight),s=t(()=>k(e.columns)),c=t(()=>R(s.value)),l=t(()=>Array.from(i.slots.values())),{handleCellMouseDown:u,handleCellDoubleClick:d,handleFillHandleMouseDown:m,handleHeaderClick:h,handleKeyDown:_,handleWheel:v,dragState:y}=Y(r,n,t(()=>e.columns),{activeCell:t(()=>i.activeCell),selectionRange:t(()=>i.selectionRange),editingCell:t(()=>i.editingCell),filterPopupOpen:t(()=>i.filterPopup?.isOpen??!1),rowHeight:e.rowHeight,headerHeight:o.value,columnPositions:s,slots:t(()=>i.slots)}),b=()=>{let e=n.value,t=r.value;!e||!t||t.setViewport(e.scrollTop,e.scrollLeft,e.clientWidth,e.clientHeight)},x=(e,t)=>{let n=r.value;n&&n.setFilter(e,t)},S=()=>{let e=r.value;e&&e.closeFilterPopup()};f(()=>{let t=e.dataSource??(e.rowData?N(e.rowData):j([])),i=new T({columns:e.columns,dataSource:t,rowHeight:e.rowHeight,headerHeight:o.value,overscan:e.overscan??3,sortingEnabled:e.sortingEnabled??!0});r.value=i;let s=i.onBatchInstruction(e=>{a(e)});i.initialize();let c=n.value;if(c){i.setViewport(c.scrollTop,c.scrollLeft,c.clientWidth,c.clientHeight);let e=new ResizeObserver(()=>{i.setViewport(c.scrollTop,c.scrollLeft,c.clientWidth,c.clientHeight)});e.observe(c),p(()=>{e.disconnect(),s(),r.value=null})}}),C(()=>e.dataSource,e=>{if(e){let t=e;if(t.subscribe){let e=t.subscribe(()=>{r.value?.refresh()});p(()=>e())}}},{immediate:!0});let{fillHandlePosition:w}=X({activeCell:t(()=>i.activeCell),selectionRange:t(()=>i.selectionRange),slots:t(()=>i.slots),columns:t(()=>e.columns),columnPositions:s,rowHeight:e.rowHeight});return{containerRef:n,coreRef:r,state:i,slotsArray:l,totalHeaderHeight:o,columnPositions:s,totalWidth:c,fillHandlePosition:w,handleScroll:b,handleCellMouseDown:u,handleCellDoubleClick:d,handleFillHandleMouseDown:m,handleHeaderClick:h,handleKeyDown:_,handleWheel:v,handleFilterApply:x,handleFilterPopupClose:S,dragState:y,isCellSelected:G,isCellActive:V,isCellEditing:U,isCellInFillPreview:ne,buildCellClasses:D}}export{st as GpGrid,st as default,E as buildCellClasses,O as calculateColumnPositions,A as createClientDataSource,M as createDataSourceFromArray,K as createInitialState,P as createMutableClientDataSource,F as createServerDataSource,I as findColumnAtX,Z as getCellValue,L as getTotalWidth,z as gridStyles,ee as injectStyles,B as isCellActive,H as isCellEditing,W as isCellInFillPreview,re as isCellSelected,ie as isRowVisible,le as renderCell,Q as renderEditCell,fe as renderHeader,J as useAutoScroll,X as useFillHandle,$ as useFilterConditions,pe as useFilterPopup,ct as useGpGrid,q as useGridState,Y as useInputHandler};
|