@g1cloud/open-bluesea-grid 1.0.0-alpha.1

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.
@@ -0,0 +1,3310 @@
1
+ import { markRaw, reactive, ref, nextTick, defineComponent, createElementBlock, openBlock, withDirectives, createElementVNode, normalizeStyle, unref, vShow, computed, useSlots, withModifiers, normalizeClass, renderSlot, createVNode, createCommentVNode, toDisplayString, watch, createTextVNode, createBlock, Fragment, renderList, createSlots, withCtx, watchEffect, onBeforeUnmount, onMounted, mergeProps, toHandlers, defineAsyncComponent, withKeys, vModelText, resolveComponent } from "vue";
2
+ import dayjs from "dayjs";
3
+ import { notNull, formatUtil, waitDuring, useContextMenu, vTooltip, componentUtil, provideSavePoint, provideFieldContext, emptyKeyProvider, useSavePoint, cancelProvidedSavePoint, BSLoadingIcon, BSPageNavigation, useModalHandle, BSModalFrame, BSButton, BSNumberInput, BSCheckbox, useModal, BSSelect, useBlueseaConfig, BSRadioButtonGroup, BSDateRange } from "@g1cloud/open-bluesea-core";
4
+ class AbstractFilter {
5
+ type;
6
+ constructor(type) {
7
+ this.type = type;
8
+ }
9
+ serialize() {
10
+ return void 0;
11
+ }
12
+ isEmpty() {
13
+ return true;
14
+ }
15
+ }
16
+ class AndFilter extends AbstractFilter {
17
+ filters;
18
+ constructor(filters) {
19
+ super("AND");
20
+ this.filters = filters;
21
+ }
22
+ toString() {
23
+ return this.filters.map((filter) => `(${filter.toString()})`).join(" AND ");
24
+ }
25
+ serialize() {
26
+ const values = this.filters.map((f) => f.serialize()).filter(notNull);
27
+ return ["AN", null, ...values];
28
+ }
29
+ isEmpty() {
30
+ return this.filters.length === 0 || !this.filters.find((child) => !child.isEmpty());
31
+ }
32
+ }
33
+ class OrFilter extends AbstractFilter {
34
+ filters;
35
+ constructor(filters) {
36
+ super("OR");
37
+ this.filters = filters;
38
+ }
39
+ toString() {
40
+ return this.filters.map((filter) => `(${filter.toString()})`).join(" OR ");
41
+ }
42
+ serialize() {
43
+ const values = this.filters.map((f) => f.serialize()).filter(notNull);
44
+ return ["OR", null, ...values];
45
+ }
46
+ isEmpty() {
47
+ return this.filters.length === 0 || !this.filters.find((child) => !child.isEmpty());
48
+ }
49
+ }
50
+ class NotFilter extends AbstractFilter {
51
+ filter;
52
+ constructor(filter) {
53
+ super("NOT");
54
+ this.filter = filter;
55
+ }
56
+ toString() {
57
+ return `NOT(${this.filter.toString()})`;
58
+ }
59
+ serialize() {
60
+ return ["NT", this.filter.serialize()];
61
+ }
62
+ isEmpty() {
63
+ return this.filter.isEmpty();
64
+ }
65
+ }
66
+ class InFilter extends AbstractFilter {
67
+ names;
68
+ values;
69
+ ignoreCase;
70
+ constructor(names, values, ignoreCase) {
71
+ super("IN");
72
+ this.names = names;
73
+ this.values = values;
74
+ this.ignoreCase = ignoreCase;
75
+ }
76
+ toString() {
77
+ const names = this.names.join(",");
78
+ const values = this.values.join(",");
79
+ return `${names} IN (${values})`;
80
+ }
81
+ serialize() {
82
+ if (this.names.length === 1) {
83
+ return ["IN", this.names, ...this.values];
84
+ } else if (this.names.length > 1) {
85
+ const filters = this.names.map((name) => inFilter([name], this.values, this.ignoreCase));
86
+ return orFilter(filters).serialize();
87
+ }
88
+ }
89
+ getFilterValueString() {
90
+ return this.values.map((value) => String(value));
91
+ }
92
+ isEmpty() {
93
+ return this.names.length === 0 || this.values.length === 0;
94
+ }
95
+ }
96
+ class LikeFilter extends AbstractFilter {
97
+ names;
98
+ value;
99
+ prefix;
100
+ suffix;
101
+ ignoreCase;
102
+ constructor(names, value, prefix, suffix, ignoreCase = true) {
103
+ super("LIKE");
104
+ this.names = names;
105
+ this.value = value;
106
+ this.prefix = prefix;
107
+ this.suffix = suffix;
108
+ this.ignoreCase = ignoreCase;
109
+ }
110
+ toString() {
111
+ const names = this.names.join(",");
112
+ return `${names} LIKE ${this.value}`;
113
+ }
114
+ serialize() {
115
+ if (this.names.length === 1) {
116
+ const result = ["LI", this.names[0], this.value, this.prefix ? 1 : 0, this.suffix ? 1 : 0];
117
+ if (!this.ignoreCase)
118
+ result.push(0);
119
+ return result;
120
+ } else if (this.names.length > 1) {
121
+ const filters = this.names.map((name) => likeFilter([name], this.value, this.prefix, this.suffix, this.ignoreCase));
122
+ return orFilter(filters).serialize();
123
+ }
124
+ }
125
+ getFilterValueString() {
126
+ return this.value;
127
+ }
128
+ isEmpty() {
129
+ return this.names.length === 0 || !this.value;
130
+ }
131
+ }
132
+ class EqualFilter extends AbstractFilter {
133
+ names;
134
+ value;
135
+ ignoreCase;
136
+ constructor(names, value, ignoreCase) {
137
+ super("EQ");
138
+ this.names = names;
139
+ this.value = value;
140
+ this.ignoreCase = ignoreCase;
141
+ }
142
+ toString() {
143
+ const names = this.names.join(",");
144
+ return `${names} = ${this.value}`;
145
+ }
146
+ serialize() {
147
+ if (this.names.length === 1) {
148
+ const result = ["EQ", this.names[0], this.value];
149
+ if (this.ignoreCase)
150
+ result.push(1);
151
+ return result;
152
+ } else if (this.names.length > 1) {
153
+ const filters = this.names.map((name) => equalFilter([name], this.value, this.ignoreCase));
154
+ return orFilter(filters).serialize();
155
+ }
156
+ }
157
+ getFilterValueString() {
158
+ return String(this.value);
159
+ }
160
+ isEmpty() {
161
+ return this.names.length === 0 || this.value === void 0 || this.value === "";
162
+ }
163
+ }
164
+ class BetweenFilter extends AbstractFilter {
165
+ name;
166
+ fromValue;
167
+ toValue;
168
+ constructor(name, fromValue, toValue) {
169
+ super("BT_V");
170
+ this.name = name;
171
+ this.fromValue = fromValue;
172
+ this.toValue = toValue;
173
+ }
174
+ toString() {
175
+ return `${this.name} BETWEEN ${this.fromValue} AND ${this.toValue}`;
176
+ }
177
+ serialize() {
178
+ return ["BT", this.name, this.fromValue, this.toValue];
179
+ }
180
+ isEmpty() {
181
+ return !this.name || (this.fromValue === void 0 || this.fromValue === "") && (this.toValue === void 0 || this.toValue === "");
182
+ }
183
+ }
184
+ class BetweenDateFilter extends AbstractFilter {
185
+ name;
186
+ fromValue;
187
+ toValue;
188
+ constructor(name, fromValue, toValue) {
189
+ super("BT_D");
190
+ this.name = name;
191
+ this.fromValue = fromValue;
192
+ this.toValue = toValue;
193
+ }
194
+ toString() {
195
+ const from = this.fromValue ? dayjs(this.fromValue).toISOString() : "undefined";
196
+ const to = this.toValue ? dayjs(this.toValue).toISOString() : "undefined";
197
+ return `${this.name} BETWEEN ${from} AND ${to}`;
198
+ }
199
+ serialize() {
200
+ const from = this.fromValue ? dayjs(this.fromValue).toISOString() : null;
201
+ const to = this.toValue ? dayjs(this.toValue).toISOString() : null;
202
+ return ["BT", this.name, from, to];
203
+ }
204
+ isEmpty() {
205
+ return !this.name || (this.fromValue === void 0 || this.fromValue === "") && (this.toValue === void 0 || this.toValue === "");
206
+ }
207
+ }
208
+ class IsNullFilter extends AbstractFilter {
209
+ names;
210
+ constructor(names) {
211
+ super("NU");
212
+ this.names = names;
213
+ }
214
+ toString() {
215
+ const names = this.names.join(",");
216
+ return `${names} IS NULL`;
217
+ }
218
+ serialize() {
219
+ if (this.names.length === 1) {
220
+ return ["NU", this.names[0]];
221
+ } else if (this.names.length > 1) {
222
+ const filters = this.names.map((name) => isNullFilter([name]));
223
+ return orFilter(filters).serialize();
224
+ }
225
+ }
226
+ getFilterValueString() {
227
+ return String();
228
+ }
229
+ isEmpty() {
230
+ return this.names.length === 0;
231
+ }
232
+ }
233
+ class IsNotNullFilter extends AbstractFilter {
234
+ names;
235
+ constructor(names) {
236
+ super("NN");
237
+ this.names = names;
238
+ }
239
+ toString() {
240
+ const names = this.names.join(",");
241
+ return `${names} IS NOT NULL`;
242
+ }
243
+ serialize() {
244
+ if (this.names.length === 1) {
245
+ return ["NN", this.names[0]];
246
+ } else if (this.names.length > 1) {
247
+ const filters = this.names.map((name) => isNotNullFilter([name]));
248
+ return orFilter(filters).serialize();
249
+ }
250
+ }
251
+ getFilterValueString() {
252
+ return String();
253
+ }
254
+ isEmpty() {
255
+ return this.names.length === 0;
256
+ }
257
+ }
258
+ const andFilter = (filters) => {
259
+ return new AndFilter(filters);
260
+ };
261
+ const orFilter = (filters) => {
262
+ return new OrFilter(filters);
263
+ };
264
+ const notFilter = (filter) => {
265
+ return new NotFilter(filter);
266
+ };
267
+ const inFilter = (names, values, ignoreCase) => {
268
+ return new InFilter(names, values, ignoreCase);
269
+ };
270
+ const likeFilter = (names, value, prefix, suffix, ignoreCase) => {
271
+ return new LikeFilter(names, value, prefix, suffix, ignoreCase);
272
+ };
273
+ const equalFilter = (names, value, ignoreCase) => {
274
+ return new EqualFilter(names, value, ignoreCase);
275
+ };
276
+ const betweenFilter = (name, fromValue, toValue) => {
277
+ return new BetweenFilter(name, fromValue, toValue);
278
+ };
279
+ const betweenDateFilter = (name, fromValue, toValue) => {
280
+ return new BetweenDateFilter(name, fromValue, toValue);
281
+ };
282
+ const isNullFilter = (names) => {
283
+ return new IsNullFilter(names);
284
+ };
285
+ const isNotNullFilter = (names) => {
286
+ return new IsNotNullFilter(names);
287
+ };
288
+ const acceptFilter = (filter, visit) => {
289
+ const result = visit(filter);
290
+ if (result === void 0 || result) {
291
+ if ("filters" in filter) {
292
+ const children = filter.filters;
293
+ if (children && Array.isArray(children)) {
294
+ children.forEach((child) => acceptFilter(child, visit));
295
+ }
296
+ }
297
+ }
298
+ };
299
+ const valueToFilter = (filters) => {
300
+ return Object.keys(filters).map((filterName) => {
301
+ const filter = filters[filterName];
302
+ if (filter instanceof AbstractFilter) {
303
+ return filter;
304
+ } else if (["string", "number", "boolean"].includes(typeof filter)) {
305
+ return equalFilter([filterName], filter);
306
+ } else if (Array.isArray(filter)) {
307
+ return inFilter([filterName], filter);
308
+ } else {
309
+ if (filter !== void 0)
310
+ console.warn("Unsupported filter value: " + filter);
311
+ return void 0;
312
+ }
313
+ }).filter(notNull);
314
+ };
315
+ const serializeFilter = (filters) => {
316
+ if (filters.length === 0)
317
+ return void 0;
318
+ else if (filters.length === 1)
319
+ return JSON.stringify(filters[0].serialize());
320
+ else
321
+ return JSON.stringify(andFilter(filters).serialize());
322
+ };
323
+ const serializeSort = (sorts) => {
324
+ if (sorts && sorts.length > 0) {
325
+ return sorts.map((sort) => {
326
+ const dir = sort.ascending ? "" : "-";
327
+ const propertyId = encodeURIComponent(sort.propertyId);
328
+ const nulls = sort.nullHandling || "";
329
+ return `${dir}${propertyId}${nulls ? ` ${nulls}` : ""}`;
330
+ }).join(",");
331
+ }
332
+ };
333
+ class SearchParam {
334
+ offset;
335
+ limit;
336
+ gridFilter = {};
337
+ lookupFilter = [];
338
+ defaultFilter = [];
339
+ sorts;
340
+ toQueryMap() {
341
+ const filters = [...this.defaultFilter, ...this.lookupFilter, ...valueToFilter(this.gridFilter)];
342
+ return {
343
+ filter: serializeFilter(filters),
344
+ sort: serializeSort(this.sorts),
345
+ offset: this.offset,
346
+ limit: this.limit
347
+ };
348
+ }
349
+ }
350
+ class PaginatedList {
351
+ data = [];
352
+ totalCount = 0;
353
+ offset = 0;
354
+ limit = 0;
355
+ static of(data = [], totalCount = void 0, offset = 0, limit = void 0) {
356
+ const paginatedList = new PaginatedList();
357
+ paginatedList.data = data ? data.slice() : [];
358
+ paginatedList.totalCount = Math.max(0, totalCount || paginatedList.data.length);
359
+ paginatedList.offset = Math.max(0, offset);
360
+ paginatedList.limit = Math.max(0, limit || paginatedList.data.length);
361
+ return paginatedList;
362
+ }
363
+ /**
364
+ * `AxiosResponse` 등의 http response 로부터 `PaginatedList` 를 생성한다.
365
+ * @param response
366
+ * @param converter
367
+ */
368
+ static fromAxiosResponse(response, converter) {
369
+ return PaginatedList.fromAxiosHeader(response.headers, response.data, converter);
370
+ }
371
+ /**
372
+ * Axios Header 와 response data 로부터 `PaginatedList` 를 생성한다.
373
+ * @param headers
374
+ * @param data
375
+ * @param converter
376
+ */
377
+ static fromAxiosHeader(headers, data, converter) {
378
+ const actualConverter = converter ? converter : ((item) => item);
379
+ const convertedData = data && data.length ? data.map((item) => actualConverter(item)) : [];
380
+ return PaginatedList.of(convertedData, Number(headers["x-total-count"]) || void 0, Number(headers["x-offset"]) || 0, Number(headers["x-limit"] || void 0));
381
+ }
382
+ /**
383
+ * @return 로딩된 데이터가 비어있으면 true
384
+ */
385
+ isEmpty() {
386
+ return this.data.length === 0;
387
+ }
388
+ }
389
+ const DEFAULT_GRID_COLUMN_WIDTH = 100;
390
+ const nameFilterCreator = (maxIndex = 4) => {
391
+ return (propertyId, keyword) => {
392
+ const names = Array.from({ length: Math.max(1, Math.min(maxIndex, 4)) }).map((_, index) => `${propertyId}.name${index + 1}`);
393
+ return [likeFilter(names, keyword)];
394
+ };
395
+ };
396
+ class EditingRows {
397
+ keyProvider;
398
+ rows = [];
399
+ constructor(keyProvider) {
400
+ this.keyProvider = keyProvider;
401
+ }
402
+ addEditingRow(row) {
403
+ this.rows.push(row);
404
+ }
405
+ addRow(row) {
406
+ this.rows.push({ row });
407
+ }
408
+ rowEquals(a, b) {
409
+ return a === b || !!(this.keyProvider && this.keyProvider(a) === this.keyProvider(b));
410
+ }
411
+ removeRow(row) {
412
+ const index = this.rows.findIndex((editing) => this.rowEquals(editing.row, row));
413
+ if (index >= 0)
414
+ this.rows.splice(index, 1);
415
+ }
416
+ clear() {
417
+ this.rows.splice(0, this.rows.length);
418
+ }
419
+ getEditingRow(row) {
420
+ return this.rows.find((editing) => this.rowEquals(editing.row, row));
421
+ }
422
+ isEditingRow(row) {
423
+ return !!this.getEditingRow(row);
424
+ }
425
+ getRows() {
426
+ return this.rows;
427
+ }
428
+ getModifiedRows() {
429
+ return this.rows.filter((row) => row.savePoint?.isModified());
430
+ }
431
+ }
432
+ const createPageGridHandler = (option) => {
433
+ const handler = option.editable ? new EditablePageGridHandlerImpl(option) : new PageGridHandlerImpl(option);
434
+ handler.loadPreference();
435
+ return handler;
436
+ };
437
+ class PageGridHandlerImpl {
438
+ option;
439
+ searchParam = markRaw(new SearchParam());
440
+ selectDeleteSupport;
441
+ grid;
442
+ gridEventListener;
443
+ control;
444
+ controlEventListener;
445
+ lookup;
446
+ lookupEventListener;
447
+ preferenceLoader;
448
+ constructor(option) {
449
+ this.option = markRaw(option);
450
+ this.searchParam.offset = 0;
451
+ this.searchParam.limit = option.limit || option.limitItems?.[0] || 100;
452
+ this.searchParam.defaultFilter = option.defaultFilter || [];
453
+ this.searchParam.sorts = [...option.defaultSorts || []];
454
+ this.grid = reactive({
455
+ gridId: option.gridId,
456
+ pageInfo: {
457
+ offset: 0,
458
+ limit: this.searchParam.limit,
459
+ totalCount: 0
460
+ },
461
+ sorts: this.searchParam.sorts,
462
+ data: [],
463
+ loading: false,
464
+ keyProvider: (row) => option.getRowKey(row),
465
+ editable: false
466
+ });
467
+ if (option.isRowSelectable) {
468
+ this.grid.rowSelectPolicy = (row) => option.isRowSelectable?.(row) || false;
469
+ }
470
+ this.gridEventListener = {
471
+ "offsetChanged": async (offset, _pageInfo) => {
472
+ this.searchParam.offset = offset;
473
+ await this.loadGridData();
474
+ },
475
+ "update:sorts": async (sorts) => {
476
+ if (this.option.defaultSorts && this.option.defaultSorts.length > 0) {
477
+ this.searchParam.sorts = [...sorts, ...this.option.defaultSorts];
478
+ }
479
+ await this.loadGridData(0);
480
+ },
481
+ settingChanged: async (columnSettings, fixedColumnCount) => {
482
+ await gridColumnSettingChanged(this.grid, this.control, option.gridId, columnSettings, fixedColumnCount);
483
+ }
484
+ };
485
+ this.control = reactive({
486
+ gridId: option.gridId,
487
+ limit: this.searchParam.limit,
488
+ limitItems: option.limitItems || [100, 300, 500],
489
+ totalCount: 0
490
+ });
491
+ this.controlEventListener = {
492
+ "update:limit": async (limit) => {
493
+ this.searchParam.limit = limit;
494
+ if (this.grid.pageInfo)
495
+ this.grid.pageInfo.limit = limit;
496
+ await this.loadGridData(0);
497
+ },
498
+ refresh: async () => {
499
+ await this.loadGridData();
500
+ },
501
+ clearFilter: async () => {
502
+ this.searchParam.gridFilter = {};
503
+ await this.loadGridData(0);
504
+ },
505
+ settingChanged: (columnSettings, fixedColumnCount) => {
506
+ gridColumnSettingChanged(this.grid, this.control, option.gridId, columnSettings, fixedColumnCount);
507
+ }
508
+ };
509
+ this.lookup = reactive({
510
+ gridId: option.gridId,
511
+ modelValue: []
512
+ });
513
+ this.lookupEventListener = {
514
+ "update:modelValue": (filters) => {
515
+ this.lookup.modelValue = this.searchParam.lookupFilter = filters;
516
+ },
517
+ search: async () => {
518
+ this.searchParam.gridFilter = {};
519
+ await this.loadGridData(0);
520
+ }
521
+ };
522
+ this.selectDeleteSupport = new GridHandlerSelectDeleteSupport(this.grid, this.control, this.controlEventListener, option.removeRowHandler, () => this.updateCounts());
523
+ }
524
+ get preferenceLoaded() {
525
+ return this.preferenceLoader?.preferenceLoaded.value ?? true;
526
+ }
527
+ getSelectedRows() {
528
+ return this.selectDeleteSupport.selectedRows;
529
+ }
530
+ getEditingRows() {
531
+ return this.grid.editingRows;
532
+ }
533
+ getAddedRows() {
534
+ return [];
535
+ }
536
+ getModifiedRows() {
537
+ return [];
538
+ }
539
+ getDeletedRows() {
540
+ return this.selectDeleteSupport.deletedRows;
541
+ }
542
+ isAddedRow(_row) {
543
+ return false;
544
+ }
545
+ addNewRow(_newRow) {
546
+ return -1;
547
+ }
548
+ isGridModified() {
549
+ return this.getAddedRows().length > 0 || this.getModifiedRows().length > 0 || this.getDeletedRows().length > 0;
550
+ }
551
+ /**
552
+ *
553
+ * @param offset
554
+ */
555
+ async loadGridData(offset) {
556
+ await this.preferenceLoader?.waitForLoaded();
557
+ this.grid.loading = true;
558
+ if (offset !== void 0)
559
+ this.searchParam.offset = offset;
560
+ const result = await this.option.getGridData(this.searchParam);
561
+ this.doSetSearchResult(result);
562
+ this.grid.loading = false;
563
+ }
564
+ loadPreference() {
565
+ if (this.option.gridId) {
566
+ this.preferenceLoader = new GridPreferenceLoader(this.option.gridId, this);
567
+ this.preferenceLoader.loadGridPreference();
568
+ }
569
+ }
570
+ doSetSearchResult(result) {
571
+ this.selectDeleteSupport.clear();
572
+ if (this.grid.pageInfo)
573
+ this.grid.pageInfo.offset = result.offset;
574
+ if (this.grid.pageInfo)
575
+ this.grid.pageInfo.totalCount = result.totalCount;
576
+ this.grid.data = result.data;
577
+ this.control.totalCount = result.totalCount;
578
+ }
579
+ updateCounts() {
580
+ this.control.totalCount = this.grid.data.length;
581
+ }
582
+ }
583
+ class EditablePageGridHandlerImpl extends PageGridHandlerImpl {
584
+ editableSupport;
585
+ constructor(option) {
586
+ super(option);
587
+ this.grid.rowEditPolicy = option.isRowEditable;
588
+ this.editableSupport = new GridHandlerEditableSupport(this.grid, this.gridEventListener, this.controlEventListener, option.getRowKey, option.newRowCreator, option.addRowToLast, () => this.updateCounts());
589
+ this.selectDeleteSupport.isAddedRow = (row) => this.editableSupport.isAddedRow(row);
590
+ this.selectDeleteSupport.removeIfAddedRow = (row) => this.editableSupport.removeIfAddedRow(row);
591
+ }
592
+ getModifiedRows() {
593
+ return this.editableSupport.getModifiedRows();
594
+ }
595
+ getAddedRows() {
596
+ return this.editableSupport.getAddedRows();
597
+ }
598
+ isAddedRow(row) {
599
+ return this.editableSupport.isAddedRow(row);
600
+ }
601
+ addNewRow(newRow) {
602
+ return this.editableSupport.addNewRow(newRow);
603
+ }
604
+ doSetSearchResult(result) {
605
+ super.doSetSearchResult(result);
606
+ this.editableSupport.clearAddedRows();
607
+ }
608
+ }
609
+ const createInputGridHandler = (option) => {
610
+ const handler = option.editable ? new EditableInputGridHandlerImpl(option) : new InputGridHandlerImpl(option);
611
+ handler.loadPreference();
612
+ return handler;
613
+ };
614
+ class InputGridHandlerImpl {
615
+ option;
616
+ selectDeleteSupport;
617
+ grid;
618
+ gridEventListener;
619
+ control;
620
+ controlEventListener;
621
+ gridFilter = reactive({});
622
+ preferenceLoader;
623
+ constructor(option) {
624
+ this.option = markRaw(option);
625
+ this.grid = reactive({
626
+ gridId: option.gridId,
627
+ data: [],
628
+ keyProvider: (row) => option.getRowKey(row),
629
+ editable: false,
630
+ rowDisplayPolicy: (row) => this.applyGridFilter(row)
631
+ });
632
+ if (option.isRowSelectable) {
633
+ this.grid.rowSelectPolicy = (row) => option.isRowSelectable?.(row) || false;
634
+ }
635
+ this.gridEventListener = {
636
+ settingChanged: async (columnSettings, fixedColumnCount) => {
637
+ await gridColumnSettingChanged(this.grid, this.control, option.gridId, columnSettings, fixedColumnCount);
638
+ }
639
+ };
640
+ this.control = reactive({
641
+ gridId: option.gridId,
642
+ totalCount: 0
643
+ });
644
+ this.controlEventListener = {
645
+ clearFilter: () => {
646
+ Object.keys(this.gridFilter).forEach((key) => delete this.gridFilter[key]);
647
+ },
648
+ settingChanged: async (columnSettings, fixedColumnCount) => {
649
+ await gridColumnSettingChanged(this.grid, this.control, option.gridId, columnSettings, fixedColumnCount);
650
+ }
651
+ };
652
+ this.selectDeleteSupport = new GridHandlerSelectDeleteSupport(this.grid, this.control, this.controlEventListener, option.removeRowHandler, () => this.updateCounts());
653
+ }
654
+ get preferenceLoaded() {
655
+ return this.preferenceLoader?.preferenceLoaded.value ?? true;
656
+ }
657
+ setGridData(data) {
658
+ this.grid.loading = data === void 0;
659
+ this.grid.data = data ?? [];
660
+ this.control.totalCount = data?.length ?? 0;
661
+ this.selectDeleteSupport.clear();
662
+ }
663
+ getSelectedRows() {
664
+ return this.selectDeleteSupport.selectedRows;
665
+ }
666
+ getEditingRows() {
667
+ return this.grid.editingRows;
668
+ }
669
+ getDeletedRows() {
670
+ return this.selectDeleteSupport.deletedRows;
671
+ }
672
+ getAddedRows() {
673
+ return [];
674
+ }
675
+ getModifiedRows() {
676
+ return [];
677
+ }
678
+ isAddedRow(_row) {
679
+ return false;
680
+ }
681
+ addNewRow(_newRow) {
682
+ return -1;
683
+ }
684
+ isGridModified() {
685
+ return this.getAddedRows().length > 0 || this.getModifiedRows().length > 0 || this.getDeletedRows().length > 0;
686
+ }
687
+ loadPreference() {
688
+ if (this.option.gridId) {
689
+ this.preferenceLoader = new GridPreferenceLoader(this.option.gridId, this);
690
+ this.preferenceLoader.loadGridPreference();
691
+ }
692
+ }
693
+ updateCounts() {
694
+ this.control.totalCount = this.grid.data.length;
695
+ }
696
+ applyGridFilter(row) {
697
+ const mismatch = Object.keys(this.gridFilter).filter((key) => this.gridFilter[key] !== void 0).find((key) => {
698
+ const filter = this.gridFilter[key];
699
+ if (typeof filter === "function") {
700
+ return !filter(row);
701
+ } else if (Array.isArray(filter)) {
702
+ return filter.length > 0 && !filter.find((item) => row[key] === item);
703
+ } else {
704
+ return row[key] !== filter;
705
+ }
706
+ });
707
+ return !mismatch;
708
+ }
709
+ }
710
+ class EditableInputGridHandlerImpl extends InputGridHandlerImpl {
711
+ editableSupport;
712
+ constructor(option) {
713
+ super(option);
714
+ this.grid.rowEditPolicy = option.isRowEditable;
715
+ this.editableSupport = new GridHandlerEditableSupport(this.grid, this.gridEventListener, this.controlEventListener, option.getRowKey, option.newRowCreator, option.addRowToLast, () => this.updateCounts());
716
+ this.selectDeleteSupport.isAddedRow = (row) => this.editableSupport.isAddedRow(row);
717
+ this.selectDeleteSupport.removeIfAddedRow = (row) => this.editableSupport.removeIfAddedRow(row);
718
+ }
719
+ setGridData(data) {
720
+ GridHandlerEditableSupport.cleanUpData(data);
721
+ super.setGridData(data);
722
+ this.editableSupport.clearAddedRows();
723
+ }
724
+ getModifiedRows() {
725
+ return this.editableSupport.getModifiedRows();
726
+ }
727
+ getAddedRows() {
728
+ return this.editableSupport.getAddedRows();
729
+ }
730
+ isAddedRow(row) {
731
+ return this.editableSupport.isAddedRow(row);
732
+ }
733
+ addNewRow(newRow) {
734
+ return this.editableSupport.addNewRow(newRow);
735
+ }
736
+ }
737
+ class GridHandlerSelectDeleteSupport {
738
+ grid;
739
+ control;
740
+ controlEventListener;
741
+ removeRowHandler;
742
+ listener;
743
+ selectedRows = reactive(/* @__PURE__ */ new Set());
744
+ deletedRows = [];
745
+ isAddedRow;
746
+ removeIfAddedRow;
747
+ constructor(grid, control, controlEventListener, removeRowHandler, listener) {
748
+ this.grid = grid;
749
+ this.control = control;
750
+ this.controlEventListener = controlEventListener;
751
+ this.removeRowHandler = removeRowHandler;
752
+ this.listener = listener;
753
+ grid.selectedRows = this.selectedRows;
754
+ control.selectedRows = this.selectedRows;
755
+ controlEventListener["clickRemove"] = () => this.removeSelectedRows();
756
+ }
757
+ removeSelectedRows() {
758
+ if (this.selectedRows.size > 0) {
759
+ if (!this.removeRowHandler || !this.removeRowHandler(this.selectedRows)) {
760
+ const keyProvider = this.grid.keyProvider;
761
+ this.selectedRows.forEach((row) => {
762
+ const index = this.grid.data.findIndex((item) => keyProvider(item) === keyProvider(row));
763
+ if (index >= 0) {
764
+ const item = this.grid.data[index];
765
+ this.grid.editingRows?.removeRow(item);
766
+ if (this.isAddedRow?.(item))
767
+ this.removeIfAddedRow?.(item);
768
+ else {
769
+ const deleted = this.grid.data.splice(index, 1);
770
+ this.deletedRows.push(deleted[0]);
771
+ }
772
+ }
773
+ });
774
+ this.selectedRows.clear();
775
+ this.listener?.("selectedRowsChanged");
776
+ }
777
+ }
778
+ }
779
+ clear() {
780
+ this.selectedRows.clear();
781
+ this.listener?.("selectedRowsChanged");
782
+ this.deletedRows.splice(0, this.deletedRows.length);
783
+ }
784
+ }
785
+ let lastAddedRowIndex = 0;
786
+ const GRID_NEW_ROW_KEY = "_new_row_key_";
787
+ class GridHandlerEditableSupport {
788
+ grid;
789
+ gridEventListener;
790
+ controlEventListener;
791
+ newRowCreator;
792
+ addRowToLast;
793
+ listener;
794
+ addedRows = [];
795
+ constructor(grid, gridEventListener, controlEventListener, getRowKey, newRowCreator, addRowToLast, listener) {
796
+ this.grid = grid;
797
+ this.gridEventListener = gridEventListener;
798
+ this.controlEventListener = controlEventListener;
799
+ this.newRowCreator = newRowCreator;
800
+ this.addRowToLast = addRowToLast;
801
+ this.listener = listener;
802
+ grid.editable = true;
803
+ const keyProvider = (row) => {
804
+ const key = this.getNewRowKey(row);
805
+ return key ? key : getRowKey(row);
806
+ };
807
+ grid.keyProvider = keyProvider;
808
+ grid.editingRows = reactive(new EditingRows(keyProvider));
809
+ gridEventListener.changeEditingRow = (row, editing) => {
810
+ if (!editing) {
811
+ this.removeIfAddedRow(row);
812
+ }
813
+ };
814
+ controlEventListener.clickAdd = () => this.createAndAddNewRow();
815
+ }
816
+ static cleanUpData(data) {
817
+ data?.forEach((row) => {
818
+ if (row && row[GRID_NEW_ROW_KEY])
819
+ delete row[GRID_NEW_ROW_KEY];
820
+ });
821
+ }
822
+ getModifiedRows() {
823
+ const addedKeys = this.addedRows.map((row) => row[GRID_NEW_ROW_KEY]);
824
+ return this.grid.editingRows?.getModifiedRows().map((editing) => editing.row).filter((row) => !addedKeys.includes(row[GRID_NEW_ROW_KEY])) || [];
825
+ }
826
+ getAddedRows() {
827
+ return this.addedRows;
828
+ }
829
+ clearAddedRows() {
830
+ this.addedRows.splice(0, this.addedRows.length);
831
+ }
832
+ isAddedRow(row) {
833
+ return !!this.getNewRowKey(row);
834
+ }
835
+ getNewRowKey(row) {
836
+ return row[GRID_NEW_ROW_KEY];
837
+ }
838
+ setNewRowKey(row) {
839
+ row[GRID_NEW_ROW_KEY] = `_ADDED_${++lastAddedRowIndex}`;
840
+ }
841
+ removeIfAddedRow(row) {
842
+ if (this.isAddedRow(row)) {
843
+ const keyProvider = this.grid.keyProvider;
844
+ const index = this.grid.data.findIndex((item) => keyProvider(item) === keyProvider(row));
845
+ if (index >= 0)
846
+ this.grid.data.splice(index, 1);
847
+ const rowIndex = this.addedRows.findIndex((item) => keyProvider(item) === keyProvider(row));
848
+ if (rowIndex >= 0)
849
+ this.addedRows.splice(rowIndex, 1);
850
+ this.listener?.("rowRemoved");
851
+ return true;
852
+ } else {
853
+ return false;
854
+ }
855
+ }
856
+ addNewRow(newRow) {
857
+ this.setNewRowKey(newRow);
858
+ this.appendAddedRow(newRow);
859
+ let index = 0;
860
+ if (this.addRowToLast) {
861
+ this.grid.data.push(newRow);
862
+ index = this.grid.data.length;
863
+ } else {
864
+ this.grid.data.unshift(newRow);
865
+ index = 0;
866
+ }
867
+ this.listener?.("rowAdded");
868
+ return index;
869
+ }
870
+ appendAddedRow(row) {
871
+ this.addedRows.push(row);
872
+ this.grid.editingRows?.addRow(row);
873
+ }
874
+ createAndAddNewRow() {
875
+ if (this.newRowCreator) {
876
+ const newRow = this.newRowCreator();
877
+ if (newRow)
878
+ this.addNewRow(newRow);
879
+ } else {
880
+ console.error("newRowCreator is missing.");
881
+ }
882
+ }
883
+ }
884
+ const gridColumnSettingChanged = async (grid, control, gridId, columnSettings, fixedColumnCount) => {
885
+ if (grid) {
886
+ grid.columnSettings = columnSettings;
887
+ grid.fixedColumnCount = fixedColumnCount;
888
+ }
889
+ if (control) {
890
+ control.columnSettings = columnSettings;
891
+ control.fixedColumnCount = fixedColumnCount;
892
+ }
893
+ await storeGridColumnSettingPreference();
894
+ };
895
+ class GridPreferenceLoader {
896
+ gridId;
897
+ handler;
898
+ preferenceLoaded = ref(true);
899
+ loadPromise = void 0;
900
+ constructor(gridId, handler) {
901
+ this.gridId = gridId;
902
+ this.handler = handler;
903
+ }
904
+ async loadGridPreference() {
905
+ console.log(this.gridId, this.handler);
906
+ }
907
+ async waitForLoaded() {
908
+ if (this.loadPromise)
909
+ await Promise.any([this.loadPromise, waitDuring(1e3)]);
910
+ }
911
+ }
912
+ class LocalStorageGridPreferenceStore {
913
+ async storePreference(gridId, preference) {
914
+ localStorage.setItem(`bs-pref-${gridId}`, JSON.stringify(preference));
915
+ }
916
+ async loadPreference(gridId) {
917
+ const json = localStorage.getItem(`bs-pref-${gridId}`);
918
+ return json ? JSON.parse(json) : void 0;
919
+ }
920
+ async removePreference(gridId) {
921
+ localStorage.removeItem(`bs-pref-${gridId}`);
922
+ }
923
+ }
924
+ const storeGridColumnSettingPreference = async (_gridId, _columnSettings, _fixedColumnCount) => {
925
+ };
926
+ const getCellText = (cell) => {
927
+ return cell?.textContent?.trim() || "";
928
+ };
929
+ const mergeSameValueVertical = (propertyIds, table) => {
930
+ if (table) {
931
+ propertyIds.forEach((propertyId) => {
932
+ const cells = table.querySelectorAll(`tbody tr > td[data-property-id="${propertyId}"]`);
933
+ for (let idx = 0; idx < cells.length; idx++) {
934
+ const value = getCellText(cells[idx]);
935
+ if (!value)
936
+ continue;
937
+ let count = 0;
938
+ for (let idxNext = idx + 1; idxNext < cells.length; idxNext++) {
939
+ const next = getCellText(cells[idxNext]);
940
+ if (!next || next !== value)
941
+ break;
942
+ count++;
943
+ }
944
+ if (count > 0) {
945
+ const cell = cells[idx];
946
+ cell.setAttribute("rowspan", `${count + 1}`);
947
+ cell.classList.add("bs-grid-merged-cell");
948
+ for (let hide = idx + 1; hide < idx + count + 1; hide++) {
949
+ cells[hide].style.display = "none";
950
+ }
951
+ }
952
+ idx += count;
953
+ }
954
+ });
955
+ }
956
+ };
957
+ const defaultCellFormatter = (column, value) => {
958
+ if (column.cellType === "NUMBER") {
959
+ return formatUtil.formatNumber(Number(value));
960
+ } else if (column.cellType === "PERCENTAGE") {
961
+ return formatUtil.formatPercent(Number(value));
962
+ } else {
963
+ return value;
964
+ }
965
+ };
966
+ const setFixedCellLeftStyle = async (table) => {
967
+ if (table) {
968
+ await nextTick();
969
+ const header = table.querySelector("tr.header-row");
970
+ if (header) {
971
+ const widths = [];
972
+ const headerCells = header.querySelectorAll("th.fixed");
973
+ headerCells.forEach((th) => {
974
+ const width = th.getBoundingClientRect().width;
975
+ widths.push(Math.floor(width));
976
+ });
977
+ let acc = 0;
978
+ for (let idx = 0; idx < widths.length; ++idx) {
979
+ widths[idx] = acc += widths[idx];
980
+ }
981
+ widths.unshift(0);
982
+ headerCells.forEach((th, idx) => th.style.left = `${widths[idx]}px`);
983
+ table.querySelectorAll("tr.data-row").forEach((tr) => {
984
+ tr.querySelectorAll("td.fixed").forEach((td, idx) => td.style.left = `${widths[idx]}px`);
985
+ });
986
+ header.querySelectorAll("th:not(.fixed)").forEach((th) => th.style.left = "auto");
987
+ }
988
+ }
989
+ };
990
+ const styleCssToObject = (style) => {
991
+ const result = {};
992
+ style?.split(";").forEach((item) => {
993
+ const [key, value] = item.split(":");
994
+ if (key && value)
995
+ result[key.trim()] = value.trim();
996
+ });
997
+ return result;
998
+ };
999
+ const styleClassToObject = (style) => {
1000
+ const result = {};
1001
+ style?.split(/\s/).filter((item) => item).forEach((item) => {
1002
+ result[item] = true;
1003
+ });
1004
+ return result;
1005
+ };
1006
+ const filterSlotName = (column) => {
1007
+ return `${column.propertyId}Filter`;
1008
+ };
1009
+ const editComponentSlotName = (column) => {
1010
+ return `${column.propertyId}Edit`;
1011
+ };
1012
+ const mergeColumnSettings = (columns, settings) => {
1013
+ const newSettings = settings.filter((col) => columns.find((baseCol) => baseCol.propertyId === col.propertyId));
1014
+ const added = columns.filter((baseCol) => !newSettings.find((col) => col.propertyId === baseCol.propertyId));
1015
+ added.forEach((addedCol) => {
1016
+ const addedColSetting = {
1017
+ propertyId: addedCol.propertyId,
1018
+ width: addedCol.width
1019
+ };
1020
+ const index = columns.findIndex((col) => col.propertyId === addedCol.propertyId);
1021
+ if (index === 0) {
1022
+ newSettings.splice(0, 0, addedColSetting);
1023
+ } else if (index > 0) {
1024
+ const prev = columns[index - 1];
1025
+ const prevIndex = newSettings.findIndex((col) => col.propertyId === prev.propertyId);
1026
+ if (prevIndex >= 0) {
1027
+ newSettings.splice(prevIndex + 1, 0, addedColSetting);
1028
+ } else {
1029
+ newSettings.push(addedColSetting);
1030
+ }
1031
+ } else {
1032
+ newSettings.push(addedColSetting);
1033
+ }
1034
+ });
1035
+ return newSettings;
1036
+ };
1037
+ const COLUMN_MIN_WIDTH = 24;
1038
+ const _sfc_main$h = /* @__PURE__ */ defineComponent({
1039
+ __name: "BSGridHeaderCellResizeHandle",
1040
+ props: {
1041
+ column: {}
1042
+ },
1043
+ emits: ["columnResized"],
1044
+ setup(__props, { emit: __emit }) {
1045
+ const props = __props;
1046
+ const emit = __emit;
1047
+ let startPosition = void 0;
1048
+ let deltaX = ref(0);
1049
+ let startWidth = 0;
1050
+ const resizeGuideHeight = ref();
1051
+ const startResize = (event) => {
1052
+ const target = event.target;
1053
+ target.setPointerCapture(event.pointerId);
1054
+ startWidth = props.column.render.width;
1055
+ startPosition = { x: event.clientX };
1056
+ resizeGuideHeight.value = `${getTableWrapHeight() || 30}px`;
1057
+ window.addEventListener("pointerup", endResize);
1058
+ };
1059
+ const doResize = (event) => {
1060
+ if (startPosition) {
1061
+ const min = COLUMN_MIN_WIDTH - startWidth;
1062
+ deltaX.value = Math.max(min, event.clientX - startPosition.x);
1063
+ }
1064
+ };
1065
+ const endResize = (event) => {
1066
+ if (startPosition) {
1067
+ const target = event.target;
1068
+ target.releasePointerCapture(event.pointerId);
1069
+ const newWidth = startWidth + (event.clientX - startPosition.x);
1070
+ const normalized = Math.max(COLUMN_MIN_WIDTH, Math.ceil(newWidth));
1071
+ if (props.column.render.width !== normalized) {
1072
+ props.column.render.width = normalized;
1073
+ }
1074
+ startPosition = void 0;
1075
+ deltaX.value = 0;
1076
+ emit("columnResized", props.column);
1077
+ }
1078
+ window.removeEventListener("pointerup", endResize);
1079
+ };
1080
+ const resizeHandle = ref();
1081
+ const getTableWrapHeight = () => {
1082
+ if (resizeHandle.value) {
1083
+ let el = resizeHandle.value;
1084
+ while (el && !el.classList.contains("table-wrap")) {
1085
+ el = el.parentElement;
1086
+ }
1087
+ if (el) return el.offsetHeight;
1088
+ }
1089
+ };
1090
+ return (_ctx, _cache) => {
1091
+ return openBlock(), createElementBlock("div", {
1092
+ ref_key: "resizeHandle",
1093
+ ref: resizeHandle,
1094
+ class: "resize-handle",
1095
+ onPointerdown: startResize,
1096
+ onPointermove: doResize,
1097
+ onPointerup: endResize
1098
+ }, [
1099
+ withDirectives(createElementVNode("div", {
1100
+ style: normalizeStyle({ transform: `translateX(${unref(deltaX)}px)`, height: resizeGuideHeight.value }),
1101
+ class: "resize-guide"
1102
+ }, null, 4), [
1103
+ [vShow, unref(startPosition)]
1104
+ ])
1105
+ ], 544);
1106
+ };
1107
+ }
1108
+ });
1109
+ const _export_sfc = (sfc, props) => {
1110
+ const target = sfc.__vccOpts || sfc;
1111
+ for (const [key, val] of props) {
1112
+ target[key] = val;
1113
+ }
1114
+ return target;
1115
+ };
1116
+ const BSGridHeaderCellResizeHandle = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["__scopeId", "data-v-3bda3a20"]]);
1117
+ const _hoisted_1$d = ["data-property-id"];
1118
+ const _hoisted_2$8 = { class: "bs-layout-horizontal align-items-center" };
1119
+ const _hoisted_3$4 = ["textContent"];
1120
+ const _hoisted_4$4 = ["textContent"];
1121
+ const _sfc_main$g = /* @__PURE__ */ defineComponent({
1122
+ __name: "BSGridHeaderCell",
1123
+ props: {
1124
+ column: {},
1125
+ columns: {},
1126
+ sorts: {},
1127
+ gridId: {},
1128
+ extensionHandler: {}
1129
+ },
1130
+ emits: ["sort", "columnResized", "toggleColumnFixed", "hideColumn", "restoreAllColumnSettings"],
1131
+ setup(__props, { emit: __emit }) {
1132
+ const props = __props;
1133
+ const emit = __emit;
1134
+ const thStyleCss = computed(() => {
1135
+ return {
1136
+ minWidth: `${props.column.render.width}px`,
1137
+ maxWidth: `${props.column.render.width}px`
1138
+ // left 는 BSGrid 의 onMounted 에서 설정함
1139
+ };
1140
+ });
1141
+ const styleCss = computed(() => {
1142
+ return styleCssToObject(props.column.headerCellStyleCss);
1143
+ });
1144
+ const styleClass = computed(() => {
1145
+ return styleClassToObject(props.column.headerCellStyleClass);
1146
+ });
1147
+ const ascending = computed(() => {
1148
+ const sortPropertyId = props.column.sortPropertyId || props.column.propertyId;
1149
+ const sort2 = props.sorts?.find((sort3) => sort3.propertyId === sortPropertyId);
1150
+ return sort2 ? sort2.ascending : void 0;
1151
+ });
1152
+ const sort = () => emit("sort", props.column, !ascending.value);
1153
+ const columnResized = (column) => emit("columnResized", column);
1154
+ const slots = useSlots();
1155
+ const hasFilter = computed(() => !!slots.filter);
1156
+ const contextMenu = useContextMenu();
1157
+ const showContextMenu = (event) => {
1158
+ const menus = [
1159
+ {
1160
+ type: "menu",
1161
+ caption: "Fixed",
1162
+ handler: () => emit("toggleColumnFixed", props.column.propertyId)
1163
+ },
1164
+ {
1165
+ type: "menu",
1166
+ caption: "Hide Column",
1167
+ handler: () => emit("hideColumn", props.column.propertyId)
1168
+ },
1169
+ { type: "separator" },
1170
+ {
1171
+ type: "menu",
1172
+ caption: "Restore All",
1173
+ handler: () => emit("restoreAllColumnSettings")
1174
+ }
1175
+ ];
1176
+ const param = {
1177
+ type: "HeaderCell",
1178
+ column: props.column
1179
+ };
1180
+ const extMenus = props.extensionHandler?.handleExtendsContextMenu(
1181
+ event,
1182
+ param
1183
+ );
1184
+ if (extMenus) {
1185
+ menus.push({ type: "separator" });
1186
+ menus.push(...extMenus);
1187
+ }
1188
+ contextMenu.showContextMenu(event, menus);
1189
+ };
1190
+ return (_ctx, _cache) => {
1191
+ return openBlock(), createElementBlock("th", {
1192
+ class: normalizeClass({ fixed: __props.column.render.fixed, "has-filter": hasFilter.value }),
1193
+ "data-property-id": __props.column.propertyId,
1194
+ style: normalizeStyle(thStyleCss.value),
1195
+ onContextmenu: withModifiers(showContextMenu, ["prevent", "stop"])
1196
+ }, [
1197
+ createElementVNode("div", {
1198
+ class: normalizeClass([styleClass.value, "position-relative"]),
1199
+ style: normalizeStyle(styleCss.value)
1200
+ }, [
1201
+ createElementVNode("div", _hoisted_2$8, [
1202
+ createElementVNode("span", {
1203
+ textContent: toDisplayString(__props.column.caption),
1204
+ class: "grow text-truncate"
1205
+ }, null, 8, _hoisted_3$4),
1206
+ __props.column.sortable ? (openBlock(), createElementBlock("span", {
1207
+ key: 0,
1208
+ class: normalizeClass([{
1209
+ "text-gray-400": ascending.value === void 0,
1210
+ descending: !ascending.value
1211
+ }, "sort-icon font-icon bs-clickable"]),
1212
+ onClick: sort,
1213
+ textContent: toDisplayString(ascending.value === void 0 ? "swap_vert" : "straight")
1214
+ }, null, 10, _hoisted_4$4)) : createCommentVNode("", true)
1215
+ ]),
1216
+ renderSlot(_ctx.$slots, "filter", {}, void 0, true),
1217
+ createVNode(BSGridHeaderCellResizeHandle, {
1218
+ column: __props.column,
1219
+ onColumnResized: columnResized
1220
+ }, null, 8, ["column"])
1221
+ ], 6)
1222
+ ], 46, _hoisted_1$d);
1223
+ };
1224
+ }
1225
+ });
1226
+ const BSGridHeaderCell = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["__scopeId", "data-v-e140e95e"]]);
1227
+ const _hoisted_1$c = { class: "checkbox bs-clickable" };
1228
+ const _hoisted_2$7 = { class: "font-icon" };
1229
+ const _sfc_main$f = /* @__PURE__ */ defineComponent({
1230
+ __name: "BSGridHeaderCellCheckbox",
1231
+ props: {
1232
+ selectedRowCount: {}
1233
+ },
1234
+ emits: ["click"],
1235
+ setup(__props, { emit: __emit }) {
1236
+ const props = __props;
1237
+ const emit = __emit;
1238
+ const checked = computed(() => props.selectedRowCount > 0);
1239
+ return (_ctx, _cache) => {
1240
+ return openBlock(), createElementBlock("th", {
1241
+ class: normalizeClass([{ checked: checked.value }, "fixed func-cell"]),
1242
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("click"))
1243
+ }, [
1244
+ createElementVNode("div", _hoisted_1$c, [
1245
+ createElementVNode("span", _hoisted_2$7, toDisplayString(checked.value ? "check_box" : "check_box_outline_blank"), 1)
1246
+ ])
1247
+ ], 2);
1248
+ };
1249
+ }
1250
+ });
1251
+ const _sfc_main$e = {};
1252
+ const _hoisted_1$b = { class: "fixed func-cell serial-no min-w-48" };
1253
+ function _sfc_render(_ctx, _cache) {
1254
+ return openBlock(), createElementBlock("th", _hoisted_1$b, [..._cache[0] || (_cache[0] = [
1255
+ createElementVNode("div", null, [
1256
+ createElementVNode("span", { class: "font-icon" }, "numbers")
1257
+ ], -1)
1258
+ ])]);
1259
+ }
1260
+ const BSGridHeaderCellSerialNo = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render]]);
1261
+ const _hoisted_1$a = ["data-property-id"];
1262
+ const _sfc_main$d = /* @__PURE__ */ defineComponent({
1263
+ __name: "BSGridCell",
1264
+ props: {
1265
+ column: {},
1266
+ columns: {},
1267
+ row: {},
1268
+ editing: { type: Boolean },
1269
+ selectOnClick: { type: Boolean },
1270
+ disableSelection: { type: Boolean }
1271
+ },
1272
+ emits: ["toggleSelection"],
1273
+ setup(__props, { emit: __emit }) {
1274
+ const props = __props;
1275
+ const emit = __emit;
1276
+ const slots = useSlots();
1277
+ const tdStyleCss = computed(() => {
1278
+ return {
1279
+ minWidth: `${props.column.render.width}px`,
1280
+ maxWidth: `${props.column.render.width}px`
1281
+ // left 는 BSGrid 의 onMounted 에서 설정함
1282
+ };
1283
+ });
1284
+ const tdStyleClass = computed(() => {
1285
+ return {
1286
+ fixed: props.column.render.fixed,
1287
+ "text-right": ["NUMBER", "MONEY", "PERCENTAGE"].includes(
1288
+ props.column.cellType || ""
1289
+ ),
1290
+ editing: props.editing && slots[`${props.column.templateId}Edit`],
1291
+ "cursor-pointer": props.selectOnClick
1292
+ };
1293
+ });
1294
+ const cellValue = computed(() => {
1295
+ const properties = props.column.propertyId.split(".");
1296
+ let value = props.row;
1297
+ for (let index = 0; index < properties.length; ++index) {
1298
+ if (!value || typeof value !== "object" || !(properties[index] in value)) {
1299
+ return "";
1300
+ }
1301
+ value = value[properties[index]];
1302
+ }
1303
+ return value ?? "";
1304
+ });
1305
+ const formattedCellValue = computed(() => {
1306
+ return defaultCellFormatter(props.column, cellValue.value);
1307
+ });
1308
+ const clickTd = () => {
1309
+ if (props.selectOnClick && !props.disableSelection) {
1310
+ emit("toggleSelection", props.column);
1311
+ }
1312
+ };
1313
+ const cellDiv = ref();
1314
+ const tooltipText = ref();
1315
+ watch(
1316
+ () => props.column.render.width,
1317
+ async () => {
1318
+ await nextTick();
1319
+ if (!props.editing && cellDiv.value && cellDiv.value.scrollWidth > cellDiv.value.clientWidth) {
1320
+ if (props.column.tooltipProvider) {
1321
+ tooltipText.value = props.column.tooltipProvider(props.row);
1322
+ } else {
1323
+ tooltipText.value = cellDiv.value.innerText;
1324
+ }
1325
+ } else {
1326
+ tooltipText.value = void 0;
1327
+ }
1328
+ },
1329
+ { immediate: true }
1330
+ );
1331
+ return (_ctx, _cache) => {
1332
+ return openBlock(), createElementBlock("td", {
1333
+ class: normalizeClass(tdStyleClass.value),
1334
+ "data-property-id": __props.column.propertyId,
1335
+ style: normalizeStyle(tdStyleCss.value),
1336
+ onClick: clickTd
1337
+ }, [
1338
+ withDirectives((openBlock(), createElementBlock("div", {
1339
+ ref_key: "cellDiv",
1340
+ ref: cellDiv,
1341
+ class: normalizeClass([__props.column.cellStyleClass, "text-nowrap text-ellipsis"]),
1342
+ style: normalizeStyle(__props.column.cellStyleCss)
1343
+ }, [
1344
+ __props.editing ? renderSlot(_ctx.$slots, `${__props.column.templateId}Edit`, {
1345
+ key: 0,
1346
+ cell: cellValue.value,
1347
+ propertyId: __props.column.propertyId,
1348
+ row: __props.row
1349
+ }, () => [
1350
+ renderSlot(_ctx.$slots, __props.column.templateId, {
1351
+ cell: cellValue.value,
1352
+ propertyId: __props.column.propertyId,
1353
+ row: __props.row
1354
+ }, () => [
1355
+ createTextVNode(toDisplayString(formattedCellValue.value), 1)
1356
+ ])
1357
+ ]) : renderSlot(_ctx.$slots, __props.column.templateId, {
1358
+ key: 1,
1359
+ cell: cellValue.value,
1360
+ propertyId: __props.column.propertyId,
1361
+ row: __props.row
1362
+ }, () => [
1363
+ createTextVNode(toDisplayString(formattedCellValue.value), 1)
1364
+ ])
1365
+ ], 6)), [
1366
+ [unref(vTooltip), { content: tooltipText.value }]
1367
+ ])
1368
+ ], 14, _hoisted_1$a);
1369
+ };
1370
+ }
1371
+ });
1372
+ const _hoisted_1$9 = { class: "fixed func-cell serial-no" };
1373
+ const _sfc_main$c = /* @__PURE__ */ defineComponent({
1374
+ __name: "BSGridCellSerialNo",
1375
+ props: {
1376
+ serialNo: {}
1377
+ },
1378
+ setup(__props) {
1379
+ return (_ctx, _cache) => {
1380
+ return openBlock(), createElementBlock("td", _hoisted_1$9, [
1381
+ createElementVNode("div", null, toDisplayString(__props.serialNo), 1)
1382
+ ]);
1383
+ };
1384
+ }
1385
+ });
1386
+ const _hoisted_1$8 = { class: "font-icon" };
1387
+ const _sfc_main$b = /* @__PURE__ */ defineComponent({
1388
+ __name: "BSGridCellCheckbox",
1389
+ props: {
1390
+ checked: { type: Boolean },
1391
+ disabled: { type: Boolean }
1392
+ },
1393
+ emits: ["click"],
1394
+ setup(__props, { emit: __emit }) {
1395
+ const props = __props;
1396
+ const emit = __emit;
1397
+ const toggleCheckbox = () => {
1398
+ if (!props.disabled) emit("click");
1399
+ };
1400
+ return (_ctx, _cache) => {
1401
+ return openBlock(), createElementBlock("td", {
1402
+ class: normalizeClass([{ checked: __props.checked, disabled: __props.disabled }, "fixed func-cell"]),
1403
+ onClick: toggleCheckbox
1404
+ }, [
1405
+ createElementVNode("div", {
1406
+ class: normalizeClass([{ "bs-clickable": !__props.disabled }, "checkbox"])
1407
+ }, [
1408
+ createElementVNode("div", _hoisted_1$8, toDisplayString(__props.checked ? "check_box" : "check_box_outline_blank"), 1)
1409
+ ], 2)
1410
+ ], 2);
1411
+ };
1412
+ }
1413
+ });
1414
+ const BSGridCellCheckbox = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-0211159f"]]);
1415
+ const _hoisted_1$7 = { class: "fixed func-cell cursor-pointer" };
1416
+ const _hoisted_2$6 = { class: "font-icon" };
1417
+ const _sfc_main$a = /* @__PURE__ */ defineComponent({
1418
+ __name: "BSGridCellEdit",
1419
+ props: {
1420
+ isEditing: { type: Boolean },
1421
+ showEditIcon: { type: Boolean }
1422
+ },
1423
+ emits: ["toggleEditMode"],
1424
+ setup(__props, { emit: __emit }) {
1425
+ const emit = __emit;
1426
+ return (_ctx, _cache) => {
1427
+ return openBlock(), createElementBlock("td", _hoisted_1$7, [
1428
+ __props.showEditIcon ? (openBlock(), createElementBlock("div", {
1429
+ key: 0,
1430
+ onClick: _cache[0] || (_cache[0] = withModifiers(($event) => emit("toggleEditMode"), ["stop"]))
1431
+ }, [
1432
+ createElementVNode("span", _hoisted_2$6, toDisplayString(__props.isEditing ? "replay" : "stylus"), 1)
1433
+ ])) : createCommentVNode("", true)
1434
+ ]);
1435
+ };
1436
+ }
1437
+ });
1438
+ let dndContext;
1439
+ const vDragSupport = {
1440
+ mounted: (el, binding) => {
1441
+ const draggable = binding.value.draggable;
1442
+ const sourceElement = binding.value.sourceProvider ? binding.value.sourceProvider(el) : el;
1443
+ const keyProvider = binding.value.keyProvider;
1444
+ const sourceType = binding.value.sourceType;
1445
+ const dropEffect = binding.value.dropEffect || "move";
1446
+ if (draggable) {
1447
+ el.draggable = true;
1448
+ el.ondragstart = (event) => {
1449
+ if (event.dataTransfer) {
1450
+ event.dataTransfer.dropEffect = dropEffect;
1451
+ event.dataTransfer.setDragImage(sourceElement, 0, 0);
1452
+ }
1453
+ dndContext = {
1454
+ sourceElement,
1455
+ key: keyProvider?.(sourceElement),
1456
+ sourceType
1457
+ };
1458
+ event.stopPropagation();
1459
+ };
1460
+ el.ondragend = () => {
1461
+ if (dndContext) {
1462
+ dndContext.dropPosition?.remove();
1463
+ dndContext = void 0;
1464
+ }
1465
+ };
1466
+ }
1467
+ }
1468
+ };
1469
+ const vDropSupport = {
1470
+ mounted: (el, binding) => {
1471
+ const droppable = binding.value.droppable;
1472
+ const isDroppable = binding.value.isDroppable;
1473
+ const createDropPosition = binding.value.createDropPosition || defaultCreateDropPosition;
1474
+ const locateDropPosition = binding.value.locateDropPosition || defaultLocateDropPosition;
1475
+ const dropHandler = binding.value.dropHandler;
1476
+ const direction = binding.value.direction || "vertical";
1477
+ if (droppable) {
1478
+ el.ondragover = (event) => {
1479
+ if (dndContext) {
1480
+ const target = event.currentTarget;
1481
+ if (!isDroppable || isDroppable(dndContext, target)) {
1482
+ const beforeOrAfter = direction === "horizontal" ? checkLeftOrRight(target, event) : checkUpOrDown(target, event);
1483
+ if (!dndContext.dropPosition) {
1484
+ dndContext.dropPosition = createDropPosition(dndContext, target, direction);
1485
+ }
1486
+ locateDropPosition(dndContext, target, dndContext.dropPosition, beforeOrAfter, direction);
1487
+ event.preventDefault();
1488
+ event.stopPropagation();
1489
+ }
1490
+ }
1491
+ };
1492
+ el.ondragleave = (event) => {
1493
+ const target = event.currentTarget;
1494
+ if (dndContext && dndContext.dropPosition && !componentUtil.isCursorInElement(event, target) && !componentUtil.isCursorInElement(event, dndContext.dropPosition)) {
1495
+ dndContext.dropPosition.remove();
1496
+ }
1497
+ event.preventDefault();
1498
+ event.stopPropagation();
1499
+ };
1500
+ el.ondrop = (event) => {
1501
+ if (dndContext) {
1502
+ const target = event.currentTarget;
1503
+ if (!isDroppable || isDroppable(dndContext, target)) {
1504
+ const beforeOrAfter = direction === "horizontal" ? checkLeftOrRight(target, event) : checkUpOrDown(target, event);
1505
+ dropHandler?.(dndContext, target, beforeOrAfter);
1506
+ }
1507
+ }
1508
+ };
1509
+ }
1510
+ }
1511
+ };
1512
+ const defaultCreateDropPosition = (_dndContext, target, direction) => {
1513
+ const div = target.ownerDocument.createElement("DIV");
1514
+ div.className = `bs-drop-position ${direction}`;
1515
+ return div;
1516
+ };
1517
+ const defaultLocateDropPosition = (_dndContext, target, dropPosition, beforeOrAfter) => {
1518
+ target.appendChild(dropPosition);
1519
+ dropPosition.classList.remove("before", "after");
1520
+ dropPosition.classList.add(beforeOrAfter);
1521
+ };
1522
+ const checkLeftOrRight = (target, event) => {
1523
+ const targetRect = target.getBoundingClientRect();
1524
+ const x = event.clientX - targetRect.left;
1525
+ return x < targetRect.width / 2 ? "before" : "after";
1526
+ };
1527
+ const checkUpOrDown = (target, event) => {
1528
+ const targetRect = target.getBoundingClientRect();
1529
+ const y = event.clientY - targetRect.top;
1530
+ return y < targetRect.height / 2 ? "before" : "after";
1531
+ };
1532
+ const _hoisted_1$6 = {
1533
+ class: "fixed func-cell drag-handle",
1534
+ draggable: "true"
1535
+ };
1536
+ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
1537
+ __name: "BSGridCellDragHandle",
1538
+ props: {
1539
+ rowIndex: {}
1540
+ },
1541
+ setup(__props) {
1542
+ return (_ctx, _cache) => {
1543
+ return withDirectives((openBlock(), createElementBlock("td", _hoisted_1$6, [..._cache[0] || (_cache[0] = [
1544
+ createElementVNode("div", { class: "font-icon" }, "drag_handle", -1)
1545
+ ])])), [
1546
+ [unref(vDragSupport), {
1547
+ draggable: true,
1548
+ sourceProvider: (td) => td.parentElement,
1549
+ keyProvider: () => __props.rowIndex,
1550
+ sourceType: "grid-row"
1551
+ }]
1552
+ ]);
1553
+ };
1554
+ }
1555
+ });
1556
+ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
1557
+ __name: "BSGridRow",
1558
+ props: {
1559
+ row: {},
1560
+ rowIndex: {},
1561
+ rowKey: {},
1562
+ allRows: {},
1563
+ columns: {},
1564
+ visibleColumns: {},
1565
+ fixedColumns: {},
1566
+ pageInfo: {},
1567
+ showSerial: { type: Boolean },
1568
+ showCheckbox: { type: Boolean },
1569
+ showDragHandle: { type: Boolean },
1570
+ selectedRows: {},
1571
+ editable: { type: Boolean },
1572
+ rowEditable: { type: Boolean },
1573
+ hideEditIcon: { type: Boolean },
1574
+ editingRow: {},
1575
+ isEditing: { type: Boolean },
1576
+ selectOnClick: { type: Boolean },
1577
+ disableSelection: { type: Boolean },
1578
+ disableUnselectedRowsSelection: { type: Boolean }
1579
+ },
1580
+ emits: ["toggleSelection", "enterEditMode", "cancelEditMode", "rowMoved"],
1581
+ setup(__props, { emit: __emit }) {
1582
+ const props = __props;
1583
+ const emit = __emit;
1584
+ const isRowSelected = computed(() => props.selectedRows.has(props.row));
1585
+ const toggleSelection = () => {
1586
+ emit("toggleSelection", props.row);
1587
+ };
1588
+ const enterEditMode = () => {
1589
+ if (props.editable && props.rowEditable) emit("enterEditMode", props.row, savePoint);
1590
+ };
1591
+ const toggleEditMode = () => {
1592
+ if (props.editable && props.rowEditable) {
1593
+ props.isEditing ? emit("cancelEditMode", props.row) : enterEditMode();
1594
+ }
1595
+ };
1596
+ const savePoint = provideSavePoint();
1597
+ watch(
1598
+ () => props.isEditing,
1599
+ async () => {
1600
+ if (props.isEditing) {
1601
+ await savePoint.setNextTick();
1602
+ if (props.editingRow && !props.editingRow.savePoint) {
1603
+ props.editingRow.savePoint = savePoint;
1604
+ }
1605
+ } else {
1606
+ savePoint.rollback();
1607
+ }
1608
+ },
1609
+ { immediate: true }
1610
+ );
1611
+ provideFieldContext({
1612
+ iteration: {
1613
+ componentName: "BSGrid",
1614
+ record: props.row,
1615
+ recordKey: props.rowKey,
1616
+ recordIndex: props.rowIndex,
1617
+ data: props.allRows
1618
+ }
1619
+ });
1620
+ const isDroppable = (dndContext2, target) => {
1621
+ const src = dndContext2.sourceElement;
1622
+ return src.tagName === "TR" && src.parentElement === target.parentElement;
1623
+ };
1624
+ const dropHandler = (dndContext2, _target, beforeOrAfter) => {
1625
+ const srcIndex = dndContext2.key;
1626
+ if (srcIndex !== void 0) {
1627
+ emit("rowMoved", srcIndex, props.rowIndex, beforeOrAfter === "before");
1628
+ }
1629
+ };
1630
+ return (_ctx, _cache) => {
1631
+ return withDirectives((openBlock(), createElementBlock("tr", {
1632
+ class: normalizeClass([{ selected: isRowSelected.value }, "data-row"]),
1633
+ onDblclick: withModifiers(enterEditMode, ["stop"])
1634
+ }, [
1635
+ __props.showDragHandle ? (openBlock(), createBlock(_sfc_main$9, {
1636
+ key: 0,
1637
+ "row-index": __props.rowIndex
1638
+ }, null, 8, ["row-index"])) : createCommentVNode("", true),
1639
+ __props.showCheckbox ? (openBlock(), createBlock(BSGridCellCheckbox, {
1640
+ key: 1,
1641
+ checked: isRowSelected.value,
1642
+ disabled: __props.disableSelection || __props.disableUnselectedRowsSelection && !isRowSelected.value,
1643
+ onClick: toggleSelection
1644
+ }, null, 8, ["checked", "disabled"])) : createCommentVNode("", true),
1645
+ __props.editable && !__props.hideEditIcon ? (openBlock(), createBlock(_sfc_main$a, {
1646
+ key: 2,
1647
+ "is-editing": __props.isEditing,
1648
+ "show-edit-icon": __props.rowEditable,
1649
+ onToggleEditMode: toggleEditMode
1650
+ }, null, 8, ["is-editing", "show-edit-icon"])) : createCommentVNode("", true),
1651
+ __props.showSerial ? (openBlock(), createBlock(_sfc_main$c, {
1652
+ key: 3,
1653
+ "serial-no": __props.rowIndex + (__props.pageInfo?.offset || 0) + 1
1654
+ }, null, 8, ["serial-no"])) : createCommentVNode("", true),
1655
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.visibleColumns, (column) => {
1656
+ return openBlock(), createBlock(_sfc_main$d, {
1657
+ key: `${column.propertyId}${__props.isEditing ? "Edit" : ""}`,
1658
+ column,
1659
+ columns: __props.columns,
1660
+ "disable-selection": __props.disableSelection,
1661
+ editing: __props.isEditing,
1662
+ row: __props.row,
1663
+ "select-on-click": __props.selectOnClick,
1664
+ onToggleSelection: toggleSelection
1665
+ }, createSlots({ _: 2 }, [
1666
+ _ctx.$slots[column.templateId] ? {
1667
+ name: column.templateId,
1668
+ fn: withCtx(({ row, cell, propertyId }) => [
1669
+ renderSlot(_ctx.$slots, column.templateId, {
1670
+ cell,
1671
+ propertyId,
1672
+ row
1673
+ })
1674
+ ]),
1675
+ key: "0"
1676
+ } : void 0,
1677
+ _ctx.$slots[`${column.templateId}Edit`] ? {
1678
+ name: `${column.templateId}Edit`,
1679
+ fn: withCtx(({ row, cell, propertyId }) => [
1680
+ renderSlot(_ctx.$slots, `${column.templateId}Edit`, {
1681
+ cell,
1682
+ propertyId,
1683
+ row
1684
+ })
1685
+ ]),
1686
+ key: "1"
1687
+ } : void 0
1688
+ ]), 1032, ["column", "columns", "disable-selection", "editing", "row", "select-on-click"]);
1689
+ }), 128))
1690
+ ], 34)), [
1691
+ [unref(vDropSupport), { droppable: __props.showDragHandle, isDroppable, dropHandler }]
1692
+ ]);
1693
+ };
1694
+ }
1695
+ });
1696
+ const _hoisted_1$5 = { class: "table-wrap" };
1697
+ const _hoisted_2$5 = { class: "header-row" };
1698
+ const _hoisted_3$3 = {
1699
+ key: 0,
1700
+ class: "fixed func-cell"
1701
+ };
1702
+ const _hoisted_4$3 = {
1703
+ key: 2,
1704
+ class: "fixed func-cell edit-icon"
1705
+ };
1706
+ const _hoisted_5$2 = { key: 0 };
1707
+ const _hoisted_6$1 = { key: 1 };
1708
+ const _hoisted_7$1 = ["textContent"];
1709
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
1710
+ __name: "BSGrid",
1711
+ props: {
1712
+ gridId: {},
1713
+ columns: { default: () => [] },
1714
+ data: {},
1715
+ pageInfo: {},
1716
+ sorts: {},
1717
+ loading: { type: Boolean },
1718
+ width: { default: "100%" },
1719
+ height: { default: "auto" },
1720
+ fixedColumnCount: { default: 0 },
1721
+ showSerial: { type: Boolean },
1722
+ showCheckbox: { type: Boolean },
1723
+ showDragHandle: { type: Boolean },
1724
+ showPageNavigation: { type: Boolean },
1725
+ selectOnClick: { type: Boolean },
1726
+ maxSelectCount: {},
1727
+ singleSelect: { type: Boolean },
1728
+ keyProvider: { type: Function, default: () => emptyKeyProvider },
1729
+ selectedRows: {},
1730
+ editable: { type: Boolean },
1731
+ hideEditIcon: { type: Boolean },
1732
+ editingRows: {},
1733
+ rowEditPolicy: {},
1734
+ rowSelectPolicy: {},
1735
+ alwaysEditing: { type: Boolean },
1736
+ rowDisplayPolicy: {},
1737
+ columnSettings: {},
1738
+ extensions: {},
1739
+ emptyMessage: {}
1740
+ },
1741
+ emits: ["offsetChanged", "update:selectedRows", "changeSelectedRows", "update:editingRows", "changeEditingRow", "update:sorts", "settingChanged", "tableChanged"],
1742
+ setup(__props, { emit: __emit }) {
1743
+ const props = __props;
1744
+ const emit = __emit;
1745
+ const internalColumns = computed(() => {
1746
+ const visibleColumns = props.columnSettings ? mergeColumnSettings(props.columns, props.columnSettings).filter((col) => !col.hidden).map((col) => {
1747
+ const orig = props.columns.find(
1748
+ (column) => column.propertyId === col.propertyId
1749
+ );
1750
+ return { ...orig, width: col.width || orig?.width };
1751
+ }).filter((col) => col.propertyId) : props.columns;
1752
+ return visibleColumns.map((col, index) => ({
1753
+ ...col,
1754
+ templateId: col.templateId || col.propertyId,
1755
+ // templateId 가 없으면 propertyId 를 사용한다.
1756
+ render: reactive({
1757
+ width: col.width || DEFAULT_GRID_COLUMN_WIDTH,
1758
+ fixed: index < props.fixedColumnCount
1759
+ })
1760
+ }));
1761
+ });
1762
+ const fixedColumns = computed(() => props.fixedColumnCount);
1763
+ watch(
1764
+ () => [JSON.stringify(props.columnSettings), props.fixedColumnCount],
1765
+ async () => {
1766
+ await setFixedCellLeftStyle(table.value);
1767
+ if (props.data) emit("tableChanged", table.value);
1768
+ }
1769
+ );
1770
+ const internalSelectedRows = props.selectedRows || reactive(/* @__PURE__ */ new Set());
1771
+ const disableUnselectedRowsSelection = computed(
1772
+ () => !!(props.maxSelectCount && internalSelectedRows.size >= props.maxSelectCount)
1773
+ );
1774
+ const toggleSelection = (row) => {
1775
+ if (internalSelectedRows.has(row)) {
1776
+ internalSelectedRows.delete(row);
1777
+ emit("changeSelectedRows", {
1778
+ allRows: false,
1779
+ targetRows: [row],
1780
+ selected: false
1781
+ });
1782
+ } else {
1783
+ if (props.singleSelect) internalSelectedRows.clear();
1784
+ internalSelectedRows.add(row);
1785
+ emit("changeSelectedRows", {
1786
+ allRows: false,
1787
+ targetRows: [row],
1788
+ selected: true
1789
+ });
1790
+ }
1791
+ emit("update:selectedRows", internalSelectedRows);
1792
+ };
1793
+ const toggleAllSelection = () => {
1794
+ if (internalSelectedRows.size > 0) {
1795
+ internalSelectedRows.clear();
1796
+ emit("changeSelectedRows", { allRows: true, selected: false });
1797
+ } else {
1798
+ if (props.singleSelect) {
1799
+ if (props.data[0]) {
1800
+ internalSelectedRows.add(props.data[0]);
1801
+ emit("changeSelectedRows", {
1802
+ allRows: false,
1803
+ targetRows: [props.data[0]],
1804
+ selected: true
1805
+ });
1806
+ }
1807
+ } else {
1808
+ const selectable = props.rowSelectPolicy ? props.data.filter((item) => props.rowSelectPolicy(item)) : props.data;
1809
+ const data = props.maxSelectCount ? selectable.slice(0, props.maxSelectCount) : selectable;
1810
+ data.forEach((row) => internalSelectedRows.add(row));
1811
+ emit("changeSelectedRows", { allRows: true, selected: true });
1812
+ }
1813
+ }
1814
+ emit("update:selectedRows", internalSelectedRows);
1815
+ };
1816
+ const clearSelection = () => {
1817
+ if (internalSelectedRows.size > 0) {
1818
+ internalSelectedRows.clear();
1819
+ emit("changeSelectedRows", { allRows: true, selected: false });
1820
+ emit("update:selectedRows", internalSelectedRows);
1821
+ }
1822
+ };
1823
+ const table = ref();
1824
+ const handleOffsetChange = (offset, currentPageInfo) => {
1825
+ emit("offsetChanged", offset, currentPageInfo);
1826
+ };
1827
+ const internalEditingRows = props.editingRows || reactive(new EditingRows(props.keyProvider));
1828
+ const enterEditMode = async (row, savePoint) => {
1829
+ if (!internalEditingRows.isEditingRow(row)) {
1830
+ internalEditingRows.addEditingRow({ row, savePoint });
1831
+ emit("update:editingRows", internalEditingRows);
1832
+ emit("changeEditingRow", row, true);
1833
+ await setFixedCellLeftStyle(table.value);
1834
+ emit("tableChanged", table.value);
1835
+ }
1836
+ };
1837
+ const cancelEditMode = async (row) => {
1838
+ if (internalEditingRows.isEditingRow(row)) {
1839
+ if (props.alwaysEditing) {
1840
+ internalEditingRows.removeRow(row);
1841
+ emit("changeEditingRow", row, false);
1842
+ await nextTick();
1843
+ internalEditingRows.addEditingRow({ row });
1844
+ emit("changeEditingRow", row, true);
1845
+ } else {
1846
+ internalEditingRows.removeRow(row);
1847
+ emit("update:editingRows", internalEditingRows);
1848
+ emit("changeEditingRow", row, false);
1849
+ await setFixedCellLeftStyle(table.value);
1850
+ emit("tableChanged", table.value);
1851
+ }
1852
+ }
1853
+ };
1854
+ const clearEditing = async () => {
1855
+ if (internalEditingRows.getRows().length > 0) {
1856
+ const rows = internalEditingRows.getRows().map((row) => row.row);
1857
+ internalEditingRows.clear();
1858
+ emit("update:editingRows", internalEditingRows);
1859
+ rows.forEach((row) => emit("changeEditingRow", row, false));
1860
+ await setFixedCellLeftStyle(table.value);
1861
+ emit("tableChanged", table.value);
1862
+ }
1863
+ };
1864
+ const initEditing = () => {
1865
+ if (props.alwaysEditing) {
1866
+ props.data.forEach((row) => {
1867
+ if ((!props.rowEditPolicy || props.rowEditPolicy(row, internalEditingRows)) && !internalEditingRows.isEditingRow(row)) {
1868
+ internalEditingRows.addEditingRow({ row });
1869
+ }
1870
+ });
1871
+ }
1872
+ };
1873
+ watch(
1874
+ () => [props.alwaysEditing, props.data.length],
1875
+ () => initEditing(),
1876
+ { immediate: true }
1877
+ );
1878
+ const internalSorts = props.sorts || reactive([]);
1879
+ const changeSort = (column, ascending) => {
1880
+ internalSorts.splice(0, internalSorts.length);
1881
+ if (ascending !== void 0) {
1882
+ internalSorts.push({
1883
+ propertyId: column.sortPropertyId || column.propertyId,
1884
+ ascending
1885
+ });
1886
+ }
1887
+ emit("update:sorts", internalSorts);
1888
+ };
1889
+ const rowMoved = (srcIndex, destIndex, before) => {
1890
+ if (srcIndex !== destIndex) {
1891
+ const dest = destIndex - (srcIndex < destIndex ? 1 : 0) + (before ? 0 : 1);
1892
+ const src = props.data.splice(srcIndex, 1)[0];
1893
+ props.data.splice(dest, 0, src);
1894
+ }
1895
+ };
1896
+ watch(
1897
+ () => [props.data, props.loading],
1898
+ async () => {
1899
+ await clearEditing();
1900
+ clearSelection();
1901
+ initEditing();
1902
+ await setFixedCellLeftStyle(table.value);
1903
+ },
1904
+ { immediate: true }
1905
+ );
1906
+ watchEffect(async () => {
1907
+ if (props.data.length > 0) await setFixedCellLeftStyle(table.value);
1908
+ emit("tableChanged", table.value);
1909
+ });
1910
+ const columnResized = async (column) => {
1911
+ setColumnWidth(column.propertyId, column.render.width);
1912
+ if (column.render.fixed) await setFixedCellLeftStyle(table.value);
1913
+ };
1914
+ const parentSavePoint = useSavePoint();
1915
+ if (parentSavePoint) {
1916
+ const childSavePoint = {
1917
+ set() {
1918
+ },
1919
+ rollback() {
1920
+ },
1921
+ isModified() {
1922
+ return !!internalEditingRows.getRows().find((row) => row.savePoint?.isModified());
1923
+ }
1924
+ };
1925
+ parentSavePoint.addChild(childSavePoint);
1926
+ onBeforeUnmount(() => parentSavePoint.removeChild(childSavePoint));
1927
+ cancelProvidedSavePoint();
1928
+ }
1929
+ const scrolledHorizontally = ref(false);
1930
+ const scrolledVertically = ref(false);
1931
+ onMounted(() => {
1932
+ table.value?.parentElement?.addEventListener("scroll", setScrollStyle, {
1933
+ passive: true
1934
+ });
1935
+ });
1936
+ const setScrollStyle = () => {
1937
+ scrolledHorizontally.value = (table.value?.parentElement?.scrollLeft || 0) > 0;
1938
+ scrolledVertically.value = (table.value?.parentElement?.scrollTop || 0) > 0;
1939
+ };
1940
+ const getColumnSettings = () => {
1941
+ return props.columnSettings || props.columns.map((col) => ({ propertyId: col.propertyId }));
1942
+ };
1943
+ const toggleColumnFixed = (propertyId) => {
1944
+ const index = internalColumns.value.findIndex(
1945
+ (col) => col.propertyId === propertyId
1946
+ );
1947
+ const newValue = props.fixedColumnCount === index + 1 ? 0 : index + 1;
1948
+ emit("settingChanged", props.columnSettings, newValue);
1949
+ };
1950
+ const hideColumn = (propertyId) => {
1951
+ const settings = getColumnSettings();
1952
+ const column = settings.find((col) => col.propertyId === propertyId);
1953
+ if (column) column.hidden = true;
1954
+ emit("settingChanged", settings, props.fixedColumnCount);
1955
+ };
1956
+ const restoreAllColumnSettings = () => {
1957
+ emit("settingChanged", void 0, void 0);
1958
+ };
1959
+ const setColumnWidth = (propertyId, width) => {
1960
+ const settings = getColumnSettings();
1961
+ const column = settings.find((col) => col.propertyId === propertyId);
1962
+ const orig = props.columns.find((col) => col.propertyId === propertyId);
1963
+ if (column) column.width = width === orig?.width ? void 0 : width;
1964
+ emit("settingChanged", settings, props.fixedColumnCount);
1965
+ };
1966
+ const extensionHandler = {
1967
+ handleExtendsContextMenu: (event, param) => {
1968
+ const context = {
1969
+ gridId: props.gridId,
1970
+ table: table.value || void 0
1971
+ };
1972
+ return props.extensions?.flatMap((ext) => ext.extendsContextMenu?.(event, param, context)).filter(notNull);
1973
+ }
1974
+ };
1975
+ return (_ctx, _cache) => {
1976
+ return openBlock(), createElementBlock("div", {
1977
+ class: normalizeClass([{
1978
+ "h-scrolled": scrolledHorizontally.value,
1979
+ "v-scrolled": scrolledVertically.value
1980
+ }, "bs-grid min-h-128"]),
1981
+ style: normalizeStyle({ width: __props.width, height: __props.height })
1982
+ }, [
1983
+ createElementVNode("div", _hoisted_1$5, [
1984
+ createElementVNode("table", {
1985
+ ref_key: "table",
1986
+ ref: table
1987
+ }, [
1988
+ createElementVNode("thead", null, [
1989
+ createElementVNode("tr", _hoisted_2$5, [
1990
+ __props.showDragHandle ? (openBlock(), createElementBlock("th", _hoisted_3$3, [..._cache[0] || (_cache[0] = [
1991
+ createElementVNode("div", null, null, -1)
1992
+ ])])) : createCommentVNode("", true),
1993
+ __props.showCheckbox ? (openBlock(), createBlock(_sfc_main$f, {
1994
+ key: 1,
1995
+ "selected-row-count": unref(internalSelectedRows).size,
1996
+ onClick: toggleAllSelection
1997
+ }, null, 8, ["selected-row-count"])) : createCommentVNode("", true),
1998
+ __props.editable && !__props.hideEditIcon ? (openBlock(), createElementBlock("th", _hoisted_4$3, [..._cache[1] || (_cache[1] = [
1999
+ createElementVNode("div", null, null, -1)
2000
+ ])])) : createCommentVNode("", true),
2001
+ __props.showSerial ? (openBlock(), createBlock(BSGridHeaderCellSerialNo, { key: 3 })) : createCommentVNode("", true),
2002
+ (openBlock(true), createElementBlock(Fragment, null, renderList(internalColumns.value, (column) => {
2003
+ return openBlock(), createBlock(BSGridHeaderCell, {
2004
+ key: column.propertyId,
2005
+ column,
2006
+ columns: internalColumns.value,
2007
+ "extension-handler": extensionHandler,
2008
+ "grid-id": __props.gridId,
2009
+ sorts: unref(internalSorts),
2010
+ onSort: changeSort,
2011
+ onColumnResized: columnResized,
2012
+ onToggleColumnFixed: toggleColumnFixed,
2013
+ onHideColumn: hideColumn,
2014
+ onRestoreAllColumnSettings: restoreAllColumnSettings
2015
+ }, createSlots({ _: 2 }, [
2016
+ _ctx.$slots[unref(filterSlotName)(column)] ? {
2017
+ name: "filter",
2018
+ fn: withCtx(() => [
2019
+ renderSlot(_ctx.$slots, unref(filterSlotName)(column))
2020
+ ]),
2021
+ key: "0"
2022
+ } : void 0
2023
+ ]), 1032, ["column", "columns", "grid-id", "sorts"]);
2024
+ }), 128))
2025
+ ])
2026
+ ]),
2027
+ createElementVNode("tbody", null, [
2028
+ __props.loading ? (openBlock(), createElementBlock("tr", _hoisted_5$2, [
2029
+ createElementVNode("td", null, [
2030
+ createVNode(unref(BSLoadingIcon), { class: "position-absolute pa-8" })
2031
+ ])
2032
+ ])) : __props.data && __props.data.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_6$1, [
2033
+ createElementVNode("td", null, [
2034
+ createElementVNode("div", {
2035
+ textContent: toDisplayString(__props.emptyMessage),
2036
+ class: "position-absolute text-nowrap pa-8"
2037
+ }, null, 8, _hoisted_7$1)
2038
+ ])
2039
+ ])) : __props.data ? (openBlock(true), createElementBlock(Fragment, { key: 2 }, renderList(__props.data, (row, index) => {
2040
+ return openBlock(), createBlock(_sfc_main$8, {
2041
+ key: __props.keyProvider(row) || index,
2042
+ "all-rows": __props.data,
2043
+ columns: internalColumns.value,
2044
+ "disable-selection": __props.rowSelectPolicy && !__props.rowSelectPolicy(row),
2045
+ "disable-unselected-rows-selection": disableUnselectedRowsSelection.value,
2046
+ editable: __props.editable,
2047
+ "editing-row": __props.editingRows?.getEditingRow(row),
2048
+ "fixed-columns": fixedColumns.value,
2049
+ "hide-edit-icon": __props.hideEditIcon,
2050
+ "is-editing": unref(internalEditingRows).isEditingRow(row),
2051
+ "page-info": __props.pageInfo,
2052
+ row,
2053
+ "row-editable": !__props.rowEditPolicy || __props.rowEditPolicy(row, unref(internalEditingRows)),
2054
+ "row-index": index,
2055
+ "row-key": __props.keyProvider(row),
2056
+ "select-on-click": __props.selectOnClick,
2057
+ "selected-rows": unref(internalSelectedRows),
2058
+ "show-checkbox": __props.showCheckbox,
2059
+ "show-drag-handle": __props.showDragHandle,
2060
+ "show-serial": __props.showSerial,
2061
+ style: normalizeStyle({
2062
+ display: __props.rowDisplayPolicy?.(row) === false ? "none" : void 0
2063
+ }),
2064
+ "visible-columns": internalColumns.value,
2065
+ onToggleSelection: toggleSelection,
2066
+ onEnterEditMode: enterEditMode,
2067
+ onCancelEditMode: cancelEditMode,
2068
+ onRowMoved: rowMoved
2069
+ }, createSlots({ _: 2 }, [
2070
+ renderList(Object.keys(_ctx.$slots), (slot, _index) => {
2071
+ return {
2072
+ name: slot,
2073
+ fn: withCtx(({ row: row2, cell, propertyId }) => [
2074
+ renderSlot(_ctx.$slots, slot, {
2075
+ cell,
2076
+ propertyId,
2077
+ row: row2
2078
+ })
2079
+ ])
2080
+ };
2081
+ })
2082
+ ]), 1032, ["all-rows", "columns", "disable-selection", "disable-unselected-rows-selection", "editable", "editing-row", "fixed-columns", "hide-edit-icon", "is-editing", "page-info", "row", "row-editable", "row-index", "row-key", "select-on-click", "selected-rows", "show-checkbox", "show-drag-handle", "show-serial", "style", "visible-columns"]);
2083
+ }), 128)) : createCommentVNode("", true)
2084
+ ])
2085
+ ], 512)
2086
+ ]),
2087
+ __props.showPageNavigation ? (openBlock(), createBlock(unref(BSPageNavigation), {
2088
+ key: 0,
2089
+ limit: __props.pageInfo?.limit || 10,
2090
+ offset: __props.pageInfo?.offset || 0,
2091
+ "total-count": __props.pageInfo?.totalCount || 0,
2092
+ "visible-page-count": 20,
2093
+ onOffsetChanged: handleOffsetChange
2094
+ }, null, 8, ["limit", "offset", "total-count"])) : createCommentVNode("", true)
2095
+ ], 6);
2096
+ };
2097
+ }
2098
+ });
2099
+ const _hoisted_1$4 = { class: "text-center" };
2100
+ const _hoisted_2$4 = { class: "text-center" };
2101
+ const _hoisted_3$2 = { class: "bs-layout-horizontal" };
2102
+ const _hoisted_4$2 = { class: "bs-layout-horizontal grow justify-content-end gap-8" };
2103
+ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
2104
+ __name: "BSGridColumnSettingModal",
2105
+ props: {
2106
+ columns: {},
2107
+ columnSettings: {},
2108
+ fixedColumnCount: {},
2109
+ columnSettingTitle: { default: "Column Settings" }
2110
+ },
2111
+ emits: ["settingChanged"],
2112
+ setup(__props, { emit: __emit }) {
2113
+ const props = __props;
2114
+ const emit = __emit;
2115
+ const settingColumns = [
2116
+ {
2117
+ propertyId: "caption",
2118
+ caption: "Caption",
2119
+ width: 200
2120
+ },
2121
+ { propertyId: "visible", caption: "Visible", width: 60 },
2122
+ { propertyId: "fixed", caption: "Fixed", width: 60 },
2123
+ { propertyId: "width", caption: "Width", width: 100 }
2124
+ ];
2125
+ const gridHandler = createInputGridHandler({
2126
+ getRowKey: (row) => row.propertyId
2127
+ });
2128
+ const editingColumns = ref([]);
2129
+ const margeColumnSettingsAndOrigColumns = (columnSettings, columns) => {
2130
+ const origColumns = [...columns || []];
2131
+ const result = columnSettings.map((col) => {
2132
+ const origIndex = origColumns.findIndex(
2133
+ (orig) => orig.propertyId === col.propertyId
2134
+ );
2135
+ if (origIndex >= 0) {
2136
+ const orig = origColumns.splice(origIndex, 1)[0];
2137
+ return { ...orig, hidden: col.hidden, width: col.width || orig.width };
2138
+ } else {
2139
+ return void 0;
2140
+ }
2141
+ }).filter(notNull);
2142
+ origColumns.forEach((orig) => {
2143
+ result.push({ ...orig, width: orig.width });
2144
+ });
2145
+ return result;
2146
+ };
2147
+ onMounted(() => {
2148
+ const columns = props.columnSettings ? margeColumnSettingsAndOrigColumns(props.columnSettings, props.columns) : props.columns?.map((orig) => ({ ...orig })) || [];
2149
+ editingColumns.value = columns.map((col, idx) => ({
2150
+ ...col,
2151
+ fixed: idx < (props.fixedColumnCount || 0)
2152
+ }));
2153
+ gridHandler.setGridData(editingColumns.value);
2154
+ });
2155
+ const updateFixedColumn = async (value, row) => {
2156
+ const rowIndex = editingColumns.value.indexOf(row);
2157
+ const oldFixedIndex = editingColumns.value.findLastIndex((col) => col.fixed) + 1;
2158
+ await nextTick();
2159
+ const fixedIndex = !value && oldFixedIndex === 0 && rowIndex === 0 ? -1 : rowIndex;
2160
+ editingColumns.value.forEach((col, idx) => col.fixed = idx <= fixedIndex);
2161
+ };
2162
+ const modalHandle = useModalHandle();
2163
+ const save = () => {
2164
+ const columnSettings = editingColumns.value.map((col) => {
2165
+ const orig = props.columns?.find((c) => c.propertyId === col.propertyId);
2166
+ return {
2167
+ propertyId: col.propertyId,
2168
+ hidden: col.hidden ? true : void 0,
2169
+ width: col.width !== orig?.width ? col.width : void 0
2170
+ };
2171
+ });
2172
+ const fixedColumnCount = editingColumns.value.findLastIndex((col) => col.fixed) + 1;
2173
+ emit("settingChanged", columnSettings, fixedColumnCount);
2174
+ modalHandle.close();
2175
+ };
2176
+ const close = () => {
2177
+ modalHandle.close();
2178
+ };
2179
+ const restore = () => {
2180
+ emit("settingChanged", void 0, void 0);
2181
+ modalHandle.close();
2182
+ };
2183
+ modalHandle.setDefaultStyle({
2184
+ maxWidth: "600px",
2185
+ maxHeight: "80%"
2186
+ });
2187
+ return (_ctx, _cache) => {
2188
+ return openBlock(), createBlock(unref(BSModalFrame), { title: __props.columnSettingTitle }, {
2189
+ default: withCtx(() => [
2190
+ createVNode(_sfc_main$7, mergeProps({
2191
+ columns: settingColumns,
2192
+ height: "100%",
2193
+ "show-drag-handle": "",
2194
+ "show-serial": ""
2195
+ }, unref(gridHandler).grid, toHandlers(unref(gridHandler).gridEventListener)), {
2196
+ visible: withCtx(({ row }) => [
2197
+ createElementVNode("div", _hoisted_1$4, [
2198
+ createVNode(unref(BSCheckbox), {
2199
+ "model-value": !row.hidden,
2200
+ class: "reverted",
2201
+ "onUpdate:modelValue": (value) => row.hidden = !value
2202
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
2203
+ ])
2204
+ ]),
2205
+ fixed: withCtx(({ row }) => [
2206
+ createElementVNode("div", _hoisted_2$4, [
2207
+ createVNode(unref(BSCheckbox), {
2208
+ modelValue: row.fixed,
2209
+ "onUpdate:modelValue": [($event) => row.fixed = $event, ($event) => updateFixedColumn($event, row)],
2210
+ class: "reverted"
2211
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2212
+ ])
2213
+ ]),
2214
+ width: withCtx(({ row }) => [
2215
+ createVNode(unref(BSNumberInput), {
2216
+ modelValue: row.width,
2217
+ "onUpdate:modelValue": ($event) => row.width = $event,
2218
+ width: "100%"
2219
+ }, null, 8, ["modelValue", "onUpdate:modelValue"])
2220
+ ]),
2221
+ _: 1
2222
+ }, 16)
2223
+ ]),
2224
+ buttons: withCtx(() => [
2225
+ createElementVNode("div", _hoisted_3$2, [
2226
+ createElementVNode("div", null, [
2227
+ createVNode(unref(BSButton), {
2228
+ caption: "Restore Settings",
2229
+ "button-color": "gray",
2230
+ onClick: restore
2231
+ })
2232
+ ]),
2233
+ createElementVNode("div", _hoisted_4$2, [
2234
+ createVNode(unref(BSButton), {
2235
+ caption: "Cancel",
2236
+ onClick: close
2237
+ }),
2238
+ createVNode(unref(BSButton), {
2239
+ caption: "OK",
2240
+ "button-color": "blue",
2241
+ onClick: save
2242
+ })
2243
+ ])
2244
+ ])
2245
+ ]),
2246
+ _: 1
2247
+ }, 8, ["title"]);
2248
+ };
2249
+ }
2250
+ });
2251
+ const _hoisted_1$3 = { class: "bs-grid-control" };
2252
+ const _hoisted_2$3 = { key: 0 };
2253
+ const _hoisted_3$1 = { key: 1 };
2254
+ const _hoisted_4$1 = { key: 2 };
2255
+ const _hoisted_5$1 = { key: 3 };
2256
+ const _hoisted_6 = { key: 4 };
2257
+ const _hoisted_7 = ["textContent"];
2258
+ const _hoisted_8 = { key: 5 };
2259
+ const _hoisted_9 = ["textContent"];
2260
+ const _hoisted_10 = { key: 6 };
2261
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
2262
+ __name: "BSGridControl",
2263
+ props: {
2264
+ gridId: {},
2265
+ showSetting: { type: Boolean },
2266
+ showRefresh: { type: Boolean },
2267
+ showClearFilter: { type: Boolean },
2268
+ showFilter: { type: Boolean },
2269
+ showLimit: { type: Boolean },
2270
+ showAddButton: { type: Boolean },
2271
+ showRemoveButton: { type: Boolean },
2272
+ columns: {},
2273
+ columnSettings: {},
2274
+ fixedColumnCount: {},
2275
+ limitItems: { default: () => [100, 300, 500] },
2276
+ limit: { default: 100 },
2277
+ totalCount: {},
2278
+ selectedRows: {},
2279
+ gridFilters: {}
2280
+ },
2281
+ emits: ["update:limit", "refresh", "clearFilter", "clickAdd", "clickRemove", "settingChanged"],
2282
+ setup(__props, { emit: __emit }) {
2283
+ const props = __props;
2284
+ const emit = __emit;
2285
+ const limitValue = ref(props.limit || props.limitItems?.[0] || 100);
2286
+ const selectedCount = computed(() => props.selectedRows?.size || 0);
2287
+ const formattedTotalCount = computed(
2288
+ () => formatUtil.formatNumber(props.totalCount) || ""
2289
+ );
2290
+ const formattedSelectedCount = computed(
2291
+ () => formatUtil.formatNumber(selectedCount.value) || ""
2292
+ );
2293
+ const changeLimit = (limit) => {
2294
+ emit("update:limit", Math.max(1, limit || 0));
2295
+ };
2296
+ const refreshGrid = () => {
2297
+ emit("refresh");
2298
+ };
2299
+ const clearGridFilter = () => {
2300
+ emit("clearFilter");
2301
+ };
2302
+ const modal = useModal();
2303
+ const openSettingModal = () => {
2304
+ modal.openModal({
2305
+ component: defineAsyncComponent(
2306
+ () => import("./BSGridColumnSettingModal-GMHDkrKO.js")
2307
+ ),
2308
+ bind: {
2309
+ columns: props.columns,
2310
+ columnSettings: props.columnSettings,
2311
+ fixedColumnCount: props.fixedColumnCount
2312
+ },
2313
+ on: {
2314
+ settingChanged: (columnSettings, fixedColumnCount) => emit("settingChanged", columnSettings, fixedColumnCount)
2315
+ }
2316
+ });
2317
+ };
2318
+ return (_ctx, _cache) => {
2319
+ return openBlock(), createElementBlock("div", _hoisted_1$3, [
2320
+ __props.showSetting ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
2321
+ createVNode(unref(BSButton), {
2322
+ caption: "Column Settings",
2323
+ "data-id": "columnSettingBtn",
2324
+ "left-icon": "data_table",
2325
+ onClick: openSettingModal
2326
+ })
2327
+ ])) : createCommentVNode("", true),
2328
+ __props.showRefresh ? (openBlock(), createElementBlock("div", _hoisted_3$1, [
2329
+ createVNode(unref(BSButton), {
2330
+ caption: "Refresh",
2331
+ "data-id": "refreshBtn",
2332
+ "left-icon": "sync",
2333
+ onClick: refreshGrid
2334
+ })
2335
+ ])) : createCommentVNode("", true),
2336
+ __props.showClearFilter ? (openBlock(), createElementBlock("div", _hoisted_4$1, [
2337
+ createVNode(unref(BSButton), {
2338
+ caption: "Clear Settings",
2339
+ "data-id": "clearSettingBtn",
2340
+ "left-icon": "filter_alt_off",
2341
+ onClick: clearGridFilter
2342
+ })
2343
+ ])) : createCommentVNode("", true),
2344
+ __props.showAddButton ? (openBlock(), createElementBlock("div", _hoisted_5$1, [
2345
+ createVNode(unref(BSButton), {
2346
+ caption: "Add Row",
2347
+ "data-id": "addRowBtn",
2348
+ "left-icon": "add",
2349
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("clickAdd"))
2350
+ })
2351
+ ])) : createCommentVNode("", true),
2352
+ __props.showRemoveButton ? (openBlock(), createElementBlock("div", _hoisted_6, [
2353
+ createVNode(unref(BSButton), {
2354
+ caption: "Remove Row",
2355
+ "data-id": "removeRowBtn",
2356
+ "left-icon": "remove",
2357
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("clickRemove"))
2358
+ })
2359
+ ])) : createCommentVNode("", true),
2360
+ createElementVNode("div", null, [
2361
+ _cache[3] || (_cache[3] = createElementVNode("span", { textContent: "Total" }, null, -1)),
2362
+ _cache[4] || (_cache[4] = createTextVNode(": ", -1)),
2363
+ createElementVNode("span", {
2364
+ "data-id": "totalCount",
2365
+ textContent: toDisplayString(formattedTotalCount.value)
2366
+ }, null, 8, _hoisted_7)
2367
+ ]),
2368
+ selectedCount.value > 0 ? (openBlock(), createElementBlock("div", _hoisted_8, [
2369
+ _cache[5] || (_cache[5] = createElementVNode("span", { textContent: "Selected" }, null, -1)),
2370
+ _cache[6] || (_cache[6] = createTextVNode(": ", -1)),
2371
+ createElementVNode("span", {
2372
+ "data-id": "selectedCount",
2373
+ textContent: toDisplayString(formattedSelectedCount.value)
2374
+ }, null, 8, _hoisted_9)
2375
+ ])) : createCommentVNode("", true),
2376
+ __props.showLimit ? (openBlock(), createElementBlock("div", _hoisted_10, [
2377
+ createVNode(unref(BSSelect), {
2378
+ modelValue: limitValue.value,
2379
+ "onUpdate:modelValue": [
2380
+ _cache[2] || (_cache[2] = ($event) => limitValue.value = $event),
2381
+ changeLimit
2382
+ ],
2383
+ items: __props.limitItems,
2384
+ class: "page-length",
2385
+ "data-id": "limitSelect"
2386
+ }, null, 8, ["modelValue", "items"])
2387
+ ])) : createCommentVNode("", true)
2388
+ ]);
2389
+ };
2390
+ }
2391
+ });
2392
+ const _hoisted_1$2 = { class: "bs-text-filter" };
2393
+ const _hoisted_2$2 = { class: "input-wrap" };
2394
+ const _hoisted_3 = { class: "textarea-wrap" };
2395
+ const _hoisted_4 = {
2396
+ class: "filter-caption text-nowrap",
2397
+ "data-id": "filterCaption"
2398
+ };
2399
+ const _hoisted_5 = ["textContent"];
2400
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
2401
+ __name: "BSTextFilter",
2402
+ props: {
2403
+ textFilterItems: { default: () => [] },
2404
+ modelValue: {},
2405
+ keyword: {}
2406
+ },
2407
+ emits: ["update:modelValue", "search"],
2408
+ setup(__props, { emit: __emit }) {
2409
+ const props = __props;
2410
+ const emit = __emit;
2411
+ const likeTextFilterItems = computed(() => props.textFilterItems);
2412
+ const inTextFilterItems = computed(() => props.textFilterItems.filter((filter) => filter.allowMultiLineFilter));
2413
+ const hasTextAreaFilterItem = computed(() => inTextFilterItems.value.length > 0);
2414
+ const filterMode = ref("INPUT");
2415
+ const changeFilterMode = (mode) => filterMode.value = mode;
2416
+ const likeFilterItems = computed(() => likeTextFilterItems.value.filter((item) => !item.filterCreator && item.filterType !== "NUMBER"));
2417
+ const equalFilterItemPropertyIds = computed(() => likeTextFilterItems.value.filter((item) => !item.filterCreator && item.filterType === "NUMBER").map((item) => item.propertyId));
2418
+ const customFilterItems = computed(() => likeTextFilterItems.value.filter((item) => item.filterCreator));
2419
+ const inFilterItemPropertyIds = computed(() => inTextFilterItems.value.map((filter) => filter.propertyId));
2420
+ const getFilterKeyword = (filter) => {
2421
+ const actualFilter = filter instanceof OrFilter ? filter.filters[0] : filter;
2422
+ if (actualFilter && "getFilterValueString" in actualFilter) {
2423
+ const value = actualFilter.getFilterValueString();
2424
+ return Array.isArray(value) ? value.join("\n") : value;
2425
+ }
2426
+ return "";
2427
+ };
2428
+ const inputText = ref(getFilterKeyword(props.modelValue));
2429
+ watch(
2430
+ () => props.modelValue,
2431
+ () => inputText.value = getFilterKeyword(props.modelValue)
2432
+ );
2433
+ const inputTextChanged = async () => {
2434
+ inputText.value = inputText.value.trim();
2435
+ const filter = await createFilter(inputText.value);
2436
+ if (props.modelValue?.toString() !== filter?.toString()) {
2437
+ emit("update:modelValue", filter, likeTextFilterItems.value);
2438
+ }
2439
+ };
2440
+ const textareaText = ref(getFilterKeyword(props.modelValue));
2441
+ const textareaTextChanged = async () => {
2442
+ textareaText.value = textareaText.value.trim();
2443
+ const filter = await createFilter(textareaText.value);
2444
+ if (props.modelValue?.toString() !== filter?.toString()) {
2445
+ emit("update:modelValue", filter, inTextFilterItems.value);
2446
+ }
2447
+ };
2448
+ const makeLikeFilters = (items, keyword) => {
2449
+ if (items.length === 0) return [];
2450
+ const prefixSuffix = items.map((item) => (item.prefix === false ? "f" : "t") + (item.suffix === false ? "f" : "t"));
2451
+ if (prefixSuffix.every((val) => val === prefixSuffix[0])) {
2452
+ const likeNames = likeFilterItems.value.map((item) => item.propertyId);
2453
+ const first = items[0];
2454
+ return [likeFilter(likeNames, keyword, first.prefix !== false, first.suffix !== false, true)];
2455
+ } else {
2456
+ return items.map((item) => likeFilter([item.propertyId], keyword, item.prefix !== false, item.suffix !== false, true));
2457
+ }
2458
+ };
2459
+ const createFilter = async (text) => {
2460
+ const keyword = text?.trim();
2461
+ if (!keyword) return void 0;
2462
+ if (filterMode.value === "INPUT") {
2463
+ const like = makeLikeFilters(likeFilterItems.value, keyword);
2464
+ const equalNames = equalFilterItemPropertyIds.value;
2465
+ const equal = equalNames.length > 0 && !Number.isNaN(Number(keyword)) ? equalFilter(equalNames, Number(keyword), true) : void 0;
2466
+ const customFilters = (await Promise.all(customFilterItems.value.map(async (item) => {
2467
+ let created = item.filterCreator?.(item.propertyId, keyword);
2468
+ if (created && created instanceof Promise) {
2469
+ created = await created;
2470
+ }
2471
+ return created || [];
2472
+ }))).flatMap((item) => item);
2473
+ const allFilters = [...like, equal, ...customFilters].filter(notNull);
2474
+ if (allFilters.length >= 2) return orFilter(allFilters);
2475
+ else return allFilters[0];
2476
+ } else if (filterMode.value === "TEXTAREA") {
2477
+ const names = inFilterItemPropertyIds.value;
2478
+ const keywords = keyword.split("\n");
2479
+ return inFilter(names, keywords, true);
2480
+ }
2481
+ };
2482
+ watch(
2483
+ () => props.keyword,
2484
+ () => {
2485
+ inputText.value = props.keyword || "";
2486
+ inputTextChanged();
2487
+ },
2488
+ { immediate: true }
2489
+ );
2490
+ return (_ctx, _cache) => {
2491
+ return openBlock(), createElementBlock("div", _hoisted_1$2, [
2492
+ withDirectives(createElementVNode("div", _hoisted_2$2, [
2493
+ withDirectives(createElementVNode("input", {
2494
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => inputText.value = $event),
2495
+ "data-id": "textFilterInput",
2496
+ type: "text",
2497
+ onChange: inputTextChanged,
2498
+ onKeyup: _cache[1] || (_cache[1] = withKeys(withModifiers(() => {
2499
+ }, ["prevent", "stop"]), ["enter"]))
2500
+ }, null, 544), [
2501
+ [vModelText, inputText.value]
2502
+ ]),
2503
+ hasTextAreaFilterItem.value ? (openBlock(), createElementBlock("span", {
2504
+ key: 0,
2505
+ class: "filter-mode-btn font-icon bs-clickable mr-4 mt-5",
2506
+ onClick: _cache[2] || (_cache[2] = ($event) => changeFilterMode("TEXTAREA"))
2507
+ }, "south")) : createCommentVNode("", true)
2508
+ ], 512), [
2509
+ [vShow, filterMode.value === "INPUT"]
2510
+ ]),
2511
+ withDirectives(createElementVNode("div", _hoisted_3, [
2512
+ withDirectives(createElementVNode("textarea", {
2513
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => textareaText.value = $event),
2514
+ "data-id": "textFilterTextarea",
2515
+ onChange: textareaTextChanged
2516
+ }, null, 544), [
2517
+ [vModelText, textareaText.value]
2518
+ ]),
2519
+ createElementVNode("span", {
2520
+ class: "font-icon bs-clickable mr-4 mt-5",
2521
+ onClick: _cache[4] || (_cache[4] = ($event) => changeFilterMode("INPUT"))
2522
+ }, "north")
2523
+ ], 512), [
2524
+ [vShow, filterMode.value === "TEXTAREA"]
2525
+ ]),
2526
+ createElementVNode("div", _hoisted_4, [
2527
+ (openBlock(true), createElementBlock(Fragment, null, renderList(filterMode.value === "INPUT" ? likeTextFilterItems.value : inTextFilterItems.value, (item) => {
2528
+ return openBlock(), createElementBlock("span", {
2529
+ key: item.propertyId,
2530
+ textContent: toDisplayString(item.caption)
2531
+ }, null, 8, _hoisted_5);
2532
+ }), 128))
2533
+ ])
2534
+ ]);
2535
+ };
2536
+ }
2537
+ });
2538
+ function getDefaultExportFromCjs(x) {
2539
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
2540
+ }
2541
+ var utc$2 = { exports: {} };
2542
+ var utc$1 = utc$2.exports;
2543
+ var hasRequiredUtc;
2544
+ function requireUtc() {
2545
+ if (hasRequiredUtc) return utc$2.exports;
2546
+ hasRequiredUtc = 1;
2547
+ (function(module, exports) {
2548
+ !(function(t, i) {
2549
+ module.exports = i();
2550
+ })(utc$1, (function() {
2551
+ var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g;
2552
+ return function(s, f, n) {
2553
+ var u = f.prototype;
2554
+ n.utc = function(t2) {
2555
+ var i2 = { date: t2, utc: true, args: arguments };
2556
+ return new f(i2);
2557
+ }, u.utc = function(i2) {
2558
+ var e2 = n(this.toDate(), { locale: this.$L, utc: true });
2559
+ return i2 ? e2.add(this.utcOffset(), t) : e2;
2560
+ }, u.local = function() {
2561
+ return n(this.toDate(), { locale: this.$L, utc: false });
2562
+ };
2563
+ var r = u.parse;
2564
+ u.parse = function(t2) {
2565
+ t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), r.call(this, t2);
2566
+ };
2567
+ var o = u.init;
2568
+ u.init = function() {
2569
+ if (this.$u) {
2570
+ var t2 = this.$d;
2571
+ this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds();
2572
+ } else o.call(this);
2573
+ };
2574
+ var a = u.utcOffset;
2575
+ u.utcOffset = function(s2, f2) {
2576
+ var n2 = this.$utils().u;
2577
+ if (n2(s2)) return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset;
2578
+ if ("string" == typeof s2 && (s2 = (function(t2) {
2579
+ void 0 === t2 && (t2 = "");
2580
+ var s3 = t2.match(i);
2581
+ if (!s3) return null;
2582
+ var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2];
2583
+ return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3;
2584
+ })(s2), null === s2)) return this;
2585
+ var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2;
2586
+ if (0 === u2) return this.utc(f2);
2587
+ var r2 = this.clone();
2588
+ if (f2) return r2.$offset = u2, r2.$u = false, r2;
2589
+ var o2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset();
2590
+ return (r2 = this.local().add(u2 + o2, t)).$offset = u2, r2.$x.$localOffset = o2, r2;
2591
+ };
2592
+ var h = u.format;
2593
+ u.format = function(t2) {
2594
+ var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : "");
2595
+ return h.call(this, i2);
2596
+ }, u.valueOf = function() {
2597
+ var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset());
2598
+ return this.$d.valueOf() - 6e4 * t2;
2599
+ }, u.isUTC = function() {
2600
+ return !!this.$u;
2601
+ }, u.toISOString = function() {
2602
+ return this.toDate().toISOString();
2603
+ }, u.toString = function() {
2604
+ return this.toDate().toUTCString();
2605
+ };
2606
+ var l = u.toDate;
2607
+ u.toDate = function(t2) {
2608
+ return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this);
2609
+ };
2610
+ var c = u.diff;
2611
+ u.diff = function(t2, i2, e2) {
2612
+ if (t2 && this.$u === t2.$u) return c.call(this, t2, i2, e2);
2613
+ var s2 = this.local(), f2 = n(t2).local();
2614
+ return c.call(s2, f2, i2, e2);
2615
+ };
2616
+ };
2617
+ }));
2618
+ })(utc$2);
2619
+ return utc$2.exports;
2620
+ }
2621
+ var utcExports = requireUtc();
2622
+ const utc = /* @__PURE__ */ getDefaultExportFromCjs(utcExports);
2623
+ var timezone$2 = { exports: {} };
2624
+ var timezone$1 = timezone$2.exports;
2625
+ var hasRequiredTimezone;
2626
+ function requireTimezone() {
2627
+ if (hasRequiredTimezone) return timezone$2.exports;
2628
+ hasRequiredTimezone = 1;
2629
+ (function(module, exports) {
2630
+ !(function(t, e) {
2631
+ module.exports = e();
2632
+ })(timezone$1, (function() {
2633
+ var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {};
2634
+ return function(n, i, o) {
2635
+ var r, a = function(t2, n2, i2) {
2636
+ void 0 === i2 && (i2 = {});
2637
+ var o2 = new Date(t2), r2 = (function(t3, n3) {
2638
+ void 0 === n3 && (n3 = {});
2639
+ var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3];
2640
+ return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3;
2641
+ })(n2, i2);
2642
+ return r2.formatToParts(o2);
2643
+ }, u = function(e2, n2) {
2644
+ for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) {
2645
+ var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2];
2646
+ c >= 0 && (r2[c] = parseInt(m, 10));
2647
+ }
2648
+ var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2;
2649
+ return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4;
2650
+ }, f = i.prototype;
2651
+ f.tz = function(t2, e2) {
2652
+ void 0 === t2 && (t2 = r);
2653
+ var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2;
2654
+ if (!Number(s2)) n2 = this.utcOffset(0, e2);
2655
+ else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) {
2656
+ var m = n2.utcOffset();
2657
+ n2 = n2.add(i2 - m, "minute");
2658
+ }
2659
+ return n2.$x.$timezone = t2, n2;
2660
+ }, f.offsetName = function(t2) {
2661
+ var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find((function(t3) {
2662
+ return "timezonename" === t3.type.toLowerCase();
2663
+ }));
2664
+ return n2 && n2.value;
2665
+ };
2666
+ var s = f.startOf;
2667
+ f.startOf = function(t2, e2) {
2668
+ if (!this.$x || !this.$x.$timezone) return s.call(this, t2, e2);
2669
+ var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L });
2670
+ return s.call(n2, t2, e2).tz(this.$x.$timezone, true);
2671
+ }, o.tz = function(t2, e2, n2) {
2672
+ var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2);
2673
+ if ("string" != typeof t2) return o(t2).tz(a2);
2674
+ var s2 = (function(t3, e3, n3) {
2675
+ var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3);
2676
+ if (e3 === o2) return [i3, e3];
2677
+ var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3);
2678
+ return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)];
2679
+ })(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c);
2680
+ return d.$x.$timezone = a2, d;
2681
+ }, o.tz.guess = function() {
2682
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
2683
+ }, o.tz.setDefault = function(t2) {
2684
+ r = t2;
2685
+ };
2686
+ };
2687
+ }));
2688
+ })(timezone$2);
2689
+ return timezone$2.exports;
2690
+ }
2691
+ var timezoneExports = requireTimezone();
2692
+ const timezone = /* @__PURE__ */ getDefaultExportFromCjs(timezoneExports);
2693
+ dayjs.extend(utc);
2694
+ dayjs.extend(timezone);
2695
+ const createDateRangeFromPreset = (value, timeZone) => {
2696
+ const from = value.from ? resolveMoment(value.from, true, timeZone) : void 0;
2697
+ const to = value.to ? resolveMoment(value.to, false, timeZone) : void 0;
2698
+ return { from: from?.toISOString(), to: to?.toISOString() };
2699
+ };
2700
+ const resolveMoment = (setting, from, timeZone, baseDate) => {
2701
+ switch (setting.type) {
2702
+ case "TODAY":
2703
+ return resolveToday(from, timeZone, baseDate);
2704
+ case "THIS_WEEK":
2705
+ return resolveThisWeek(from, timeZone, baseDate);
2706
+ case "THIS_MONTH":
2707
+ return resolveThisMonth(from, timeZone, baseDate);
2708
+ case "THIS_YEAR":
2709
+ return resolveThisYear(from, timeZone, baseDate);
2710
+ case "LAST_HOURS":
2711
+ return resolveLastHours(setting.value || 0, from, timeZone, baseDate);
2712
+ case "LAST_DAYS":
2713
+ return resolveLastDays(setting.value || 0, from, timeZone, baseDate);
2714
+ case "DAYS_AGO":
2715
+ return resolveDaysAgo(setting.value || 0, from, timeZone, baseDate);
2716
+ case "WEEKS_AGO":
2717
+ return resolveWeeksAgo(setting.value || 0, from, timeZone, baseDate);
2718
+ case "MONTHS_AGO":
2719
+ return resolveMonthsAgo(setting.value || 0, from, timeZone, baseDate);
2720
+ case "YEARS_AGO":
2721
+ return resolveYearsAgo(setting.value || 0, from, timeZone, baseDate);
2722
+ }
2723
+ };
2724
+ const resolveToday = (from, timeZone, baseDate) => {
2725
+ const today = (baseDate || dayjs()).tz(timeZone);
2726
+ return from ? today.startOf("day") : today.endOf("day");
2727
+ };
2728
+ const resolveThisWeek = (from, timeZone, baseDate) => {
2729
+ const today = (baseDate || dayjs()).tz(timeZone);
2730
+ return from ? today.startOf("week") : today.endOf("week");
2731
+ };
2732
+ const resolveThisMonth = (from, timeZone, baseDate) => {
2733
+ const today = (baseDate || dayjs()).tz(timeZone);
2734
+ return from ? today.startOf("month") : today.endOf("month");
2735
+ };
2736
+ const resolveThisYear = (from, timeZone, baseDate) => {
2737
+ const today = (baseDate || dayjs()).tz(timeZone);
2738
+ return from ? today.startOf("year") : today.endOf("year");
2739
+ };
2740
+ const resolveLastHours = (hours, from, timeZone, baseDate) => {
2741
+ const today = (baseDate || dayjs()).tz(timeZone);
2742
+ return from ? today.add(-hours, "hour").startOf("minute") : today.endOf("minute");
2743
+ };
2744
+ const resolveLastDays = (days, from, timeZone, baseDate) => {
2745
+ const today = (baseDate || dayjs()).tz(timeZone);
2746
+ return from ? today.add(-days, "day").startOf("day") : today.endOf("day");
2747
+ };
2748
+ const resolveDaysAgo = (days, from, timeZone, baseDate) => {
2749
+ const today = (baseDate || dayjs()).tz(timeZone);
2750
+ return from ? today.add(-days, "day").startOf("day") : today.add(-days, "day").endOf("day");
2751
+ };
2752
+ const resolveWeeksAgo = (weeks, from, timeZone, baseDate) => {
2753
+ const today = (baseDate || dayjs()).tz(timeZone);
2754
+ return from ? today.add(-weeks, "week").startOf("week") : today.add(-weeks, "week").endOf("week");
2755
+ };
2756
+ const resolveMonthsAgo = (months, from, timeZone, baseDate) => {
2757
+ const today = (baseDate || dayjs()).tz(timeZone);
2758
+ return from ? today.add(-months, "month").startOf("month") : today.add(-months, "month").endOf("month");
2759
+ };
2760
+ const resolveYearsAgo = (years, from, timeZone, baseDate) => {
2761
+ const today = (baseDate || dayjs()).tz(timeZone);
2762
+ return from ? today.add(-years, "year").startOf("year") : today.add(-years, "year").endOf("year");
2763
+ };
2764
+ const serializeMomentSetting = (setting) => {
2765
+ if (!setting)
2766
+ return "";
2767
+ const value = setting.value === void 0 ? "" : `:${setting.value}`;
2768
+ return `${setting.type}${value}`;
2769
+ };
2770
+ const convertDateRangePresetKey = (preset) => {
2771
+ if (preset.from === void 0 && preset.to === void 0)
2772
+ return "";
2773
+ return `${serializeMomentSetting(preset.from)}~${serializeMomentSetting(preset.to)}`;
2774
+ };
2775
+ const findPreset = (presetKey, candidatePresets) => {
2776
+ if (!presetKey)
2777
+ return void 0;
2778
+ return candidatePresets?.find((preset) => convertDateRangePresetKey(preset) === presetKey);
2779
+ };
2780
+ class BetweenDateFilterWithPreset extends BetweenDateFilter {
2781
+ name;
2782
+ fromValue;
2783
+ toValue;
2784
+ presetKey;
2785
+ constructor(name, fromValue, toValue, preset) {
2786
+ super(name, fromValue, toValue);
2787
+ this.name = name;
2788
+ this.fromValue = fromValue;
2789
+ this.toValue = toValue;
2790
+ this.presetKey = preset ? convertDateRangePresetKey(preset) : void 0;
2791
+ }
2792
+ // candidatePresets 중 presetKey 에 해당하는 preset 을 찾아, fromValue, toValue 를 설정한다.
2793
+ // preset 을 찾을 수 없으면 undefined 를 리턴한다.
2794
+ static createFromPresetKey(name, presetKey, candidatePresets, timeZone) {
2795
+ const preset = findPreset(presetKey, candidatePresets);
2796
+ const range = preset ? createDateRangeFromPreset(preset, timeZone) : void 0;
2797
+ return range ? new BetweenDateFilterWithPreset(name, range.from, range.to, preset) : void 0;
2798
+ }
2799
+ }
2800
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
2801
+ __name: "BSDateRangePresets",
2802
+ props: {
2803
+ modelValue: {},
2804
+ presets: { default: () => [] },
2805
+ timeZone: {}
2806
+ },
2807
+ emits: ["update:modelValue"],
2808
+ setup(__props, { emit: __emit }) {
2809
+ const props = __props;
2810
+ const emit = __emit;
2811
+ const blueseaConfig = useBlueseaConfig();
2812
+ const actualTimeZone = computed(() => props.timeZone || blueseaConfig.timeZone);
2813
+ const currentPreset = ref();
2814
+ const presetSelected = (value) => {
2815
+ const range = value ? createDateRangeFromPreset(value, actualTimeZone.value) : void 0;
2816
+ emit("update:modelValue", range, value);
2817
+ };
2818
+ const findPreset2 = (range) => {
2819
+ return props.presets.find((preset) => {
2820
+ const presetValue = createDateRangeFromPreset(preset, actualTimeZone.value);
2821
+ return range?.from === presetValue.from && range?.to === presetValue.to;
2822
+ });
2823
+ };
2824
+ watch(
2825
+ () => props.modelValue,
2826
+ () => {
2827
+ currentPreset.value = findPreset2(props.modelValue);
2828
+ },
2829
+ { immediate: true }
2830
+ );
2831
+ return (_ctx, _cache) => {
2832
+ return __props.presets && __props.presets.length > 0 ? (openBlock(), createBlock(unref(BSRadioButtonGroup), {
2833
+ key: 0,
2834
+ modelValue: currentPreset.value,
2835
+ "onUpdate:modelValue": [
2836
+ _cache[0] || (_cache[0] = ($event) => currentPreset.value = $event),
2837
+ presetSelected
2838
+ ],
2839
+ items: __props.presets,
2840
+ "label-provider": (item) => item.caption,
2841
+ class: "button-group-style nowrap",
2842
+ name: "dateRangePreset"
2843
+ }, null, 8, ["modelValue", "items", "label-provider"])) : createCommentVNode("", true);
2844
+ };
2845
+ }
2846
+ });
2847
+ const _hoisted_1$1 = {
2848
+ key: 0,
2849
+ class: "date-filters .bs-layout-vertical mr-16"
2850
+ };
2851
+ const _hoisted_2$1 = ["onClick"];
2852
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2853
+ __name: "BSDateRangeFilters",
2854
+ props: {
2855
+ dateFilter: {},
2856
+ modelValue: {},
2857
+ captionMinWidth: { default: "140px" },
2858
+ dateFormat: {},
2859
+ popupDateFormat: {},
2860
+ popupStartYear: {},
2861
+ popupEndYear: {},
2862
+ filterWidth: {},
2863
+ presets: {},
2864
+ resolution: {}
2865
+ },
2866
+ emits: ["update:modelValue"],
2867
+ setup(__props, { emit: __emit }) {
2868
+ const props = __props;
2869
+ const emit = __emit;
2870
+ const dateFilterValues = ref([]);
2871
+ const resetDateFilter = () => {
2872
+ const items = props.dateFilter?.filterItems;
2873
+ if (items && items.length > 0) {
2874
+ let values = void 0;
2875
+ if (props.modelValue && props.modelValue.filters.length > 0) {
2876
+ const validPropertyIds = items.map((item) => item.propertyId);
2877
+ values = props.modelValue.filters.filter((filter) => filter instanceof BetweenDateFilter).map((filter) => filter).map((filter) => ({
2878
+ propertyId: filter.name,
2879
+ value: {
2880
+ from: filter.fromValue ? String(filter.fromValue) : void 0,
2881
+ // string 타입으로 가정함
2882
+ to: filter.toValue ? String(filter.toValue) : void 0
2883
+ // string 타입으로 가정함
2884
+ }
2885
+ })).filter((value) => validPropertyIds.includes(value.propertyId));
2886
+ }
2887
+ if (!values || values.length === 0) {
2888
+ values = [
2889
+ {
2890
+ propertyId: items[0].propertyId,
2891
+ value: {}
2892
+ }
2893
+ ];
2894
+ }
2895
+ if (JSON.stringify(values) !== JSON.stringify(dateFilterValues.value)) {
2896
+ dateFilterValues.value = values;
2897
+ }
2898
+ }
2899
+ };
2900
+ watch(
2901
+ () => props.modelValue,
2902
+ () => resetDateFilter(),
2903
+ { immediate: true }
2904
+ );
2905
+ const setDateFilterPropertyId = (index, propertyId) => {
2906
+ const item = dateFilterValues.value[index];
2907
+ if (propertyId) item.propertyId = propertyId;
2908
+ emitValue();
2909
+ };
2910
+ const setDateFilterValue = (index, value, preset) => {
2911
+ const item = dateFilterValues.value[index];
2912
+ item.value = value || {};
2913
+ item.preset = preset;
2914
+ emitValue();
2915
+ };
2916
+ const addDateFilter = () => {
2917
+ const dateFilterItems = props.dateFilter?.filterItems || [];
2918
+ if (dateFilterValues.value.length < dateFilterItems.length) {
2919
+ const selectedPropertyIds = dateFilterValues.value.map(
2920
+ (value) => value.propertyId
2921
+ );
2922
+ const notSelected = dateFilterItems.filter(
2923
+ (item) => !selectedPropertyIds.includes(item.propertyId)
2924
+ );
2925
+ if (notSelected.length > 0) {
2926
+ dateFilterValues.value.push({
2927
+ propertyId: notSelected[0].propertyId,
2928
+ value: {}
2929
+ });
2930
+ }
2931
+ }
2932
+ };
2933
+ const removeDateFilter = (index) => {
2934
+ if (index >= 0 && index < dateFilterValues.value.length) {
2935
+ dateFilterValues.value.splice(index, 1);
2936
+ emitValue();
2937
+ }
2938
+ };
2939
+ const emitValue = () => {
2940
+ const filters = dateFilterValues.value.map(
2941
+ (item) => new BetweenDateFilterWithPreset(
2942
+ item.propertyId,
2943
+ item.value.from,
2944
+ item.value.to,
2945
+ item.preset
2946
+ )
2947
+ );
2948
+ const and = filters.length > 0 ? andFilter(filters) : void 0;
2949
+ if (props.modelValue?.toString() !== and?.toString()) {
2950
+ emit("update:modelValue", and);
2951
+ }
2952
+ };
2953
+ const dateFormatOfFilterItem = (propertyId) => {
2954
+ return props.dateFilter.filterItems.find((item) => item.propertyId === propertyId)?.dateFormat || props.dateFormat;
2955
+ };
2956
+ const popupDateFormatOfFilterItem = (propertyId) => {
2957
+ return props.dateFilter.filterItems.find((item) => item.propertyId === propertyId)?.popupDateFormat || props.popupDateFormat;
2958
+ };
2959
+ const timeZoneOfFilterItem = (propertyId) => {
2960
+ return props.dateFilter.filterItems.find(
2961
+ (item) => item.propertyId === propertyId
2962
+ )?.timeZone;
2963
+ };
2964
+ const filterWidthOfFilterItem = (propertyId) => {
2965
+ return props.dateFilter.filterItems.find((item) => item.propertyId === propertyId)?.filterWidth || props.filterWidth;
2966
+ };
2967
+ return (_ctx, _cache) => {
2968
+ const _component_BSDateRangeFilter = resolveComponent("BSDateRangeFilter");
2969
+ return __props.dateFilter.filterItems ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
2970
+ (openBlock(true), createElementBlock(Fragment, null, renderList(dateFilterValues.value, (item, index) => {
2971
+ return openBlock(), createElementBlock("div", {
2972
+ key: index,
2973
+ class: "bs-layout-horizontal mb-4 flex-align-center"
2974
+ }, [
2975
+ index === 0 ? (openBlock(), createElementBlock("span", {
2976
+ key: 0,
2977
+ class: normalizeClass([{
2978
+ disabled: dateFilterValues.value.length >= __props.dateFilter.filterItems.length
2979
+ }, "font-icon bs-clickable mr-4"]),
2980
+ "data-id": "addDateFilterBtn",
2981
+ onClick: addDateFilter
2982
+ }, "add", 2)) : (openBlock(), createElementBlock("span", {
2983
+ key: 1,
2984
+ class: "font-icon bs-clickable mr-4",
2985
+ "data-id": "removeDateFilterBtn",
2986
+ onClick: ($event) => removeDateFilter(index)
2987
+ }, "remove", 8, _hoisted_2$1)),
2988
+ createVNode(unref(BSSelect), {
2989
+ items: __props.dateFilter.filterItems,
2990
+ "label-provider": (filter) => filter.caption,
2991
+ "model-value": item.propertyId,
2992
+ style: normalizeStyle({ minWidth: __props.captionMinWidth }),
2993
+ "value-provider": (filter) => filter.propertyId,
2994
+ class: "mr-4",
2995
+ "data-id": "filterItemSelect",
2996
+ "onUpdate:modelValue": ($event) => setDateFilterPropertyId(index, $event)
2997
+ }, null, 8, ["items", "label-provider", "model-value", "style", "value-provider", "onUpdate:modelValue"]),
2998
+ createVNode(_component_BSDateRangeFilter, {
2999
+ "display-format": dateFormatOfFilterItem(item.propertyId),
3000
+ "from-id": `${item.propertyId}From`,
3001
+ "model-value": item.value,
3002
+ "name-from": `${item.propertyId}From`,
3003
+ "name-to": `${item.propertyId}To`,
3004
+ "popup-display-format": popupDateFormatOfFilterItem(item.propertyId),
3005
+ "popup-end-year": __props.popupEndYear,
3006
+ "popup-start-year": __props.popupStartYear,
3007
+ resolution: __props.resolution,
3008
+ "time-zone": timeZoneOfFilterItem(item.propertyId),
3009
+ "to-id": `${item.propertyId}To`,
3010
+ width: filterWidthOfFilterItem(item.propertyId),
3011
+ "onUpdate:modelValue": ($event) => setDateFilterValue(index, $event)
3012
+ }, null, 8, ["display-format", "from-id", "model-value", "name-from", "name-to", "popup-display-format", "popup-end-year", "popup-start-year", "resolution", "time-zone", "to-id", "width", "onUpdate:modelValue"]),
3013
+ createVNode(_sfc_main$3, {
3014
+ modelValue: item.value,
3015
+ "onUpdate:modelValue": [
3016
+ ($event) => item.value = $event,
3017
+ (value, preset) => setDateFilterValue(index, value, preset)
3018
+ ],
3019
+ presets: __props.presets,
3020
+ "time-zone": timeZoneOfFilterItem(item.propertyId),
3021
+ class: "ml-4"
3022
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "presets", "time-zone"])
3023
+ ]);
3024
+ }), 128))
3025
+ ])) : createCommentVNode("", true);
3026
+ };
3027
+ }
3028
+ });
3029
+ const _hoisted_1 = { class: "bs-grid-lookup bs-layout-horizontal flex-align-start" };
3030
+ const _hoisted_2 = { class: "text-nowrap" };
3031
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
3032
+ __name: "BSGridLookup",
3033
+ props: {
3034
+ gridId: {},
3035
+ config: {},
3036
+ modelValue: {},
3037
+ dateRangePresets: {},
3038
+ dateFilterCaptionMinWidth: {},
3039
+ dateFilterDateFormat: { default: "YYYY-MM-DD HH:mm" },
3040
+ dateFilterResolution: { default: "DAY" },
3041
+ dateFilterPopupDateFormat: {},
3042
+ dateFilterWidth: {},
3043
+ dateFilterPopupStartYear: {},
3044
+ dateFilterPopupEndYear: {},
3045
+ keyword: {},
3046
+ gridPreferenceDateFilterValues: {}
3047
+ },
3048
+ emits: ["update:modelValue", "search"],
3049
+ setup(__props, { emit: __emit }) {
3050
+ const props = __props;
3051
+ const emit = __emit;
3052
+ const textFilterValue = ref();
3053
+ const dateFilterValue = ref();
3054
+ const makeFilters = () => {
3055
+ const filters = [];
3056
+ if (textFilterValue.value) filters.push(textFilterValue.value);
3057
+ if (dateFilterValue.value) {
3058
+ dateFilterValue.value.filters.filter((filter) => !filter.isEmpty()).forEach((filter) => filters.push(filter));
3059
+ }
3060
+ return filters;
3061
+ };
3062
+ const emitUpdateModelValue = () => {
3063
+ emit("update:modelValue", makeFilters());
3064
+ };
3065
+ const emitSearch = () => {
3066
+ emit("search", makeFilters());
3067
+ };
3068
+ const emitUpdateModelValueAndSearch = () => {
3069
+ emitUpdateModelValue();
3070
+ emitSearch();
3071
+ };
3072
+ const blueseaConfig = useBlueseaConfig();
3073
+ const findDateFilterTimeZone = (name, dateFilter) => {
3074
+ return dateFilter?.filterItems.find((f) => f.propertyId === name)?.timeZone || blueseaConfig.timeZone;
3075
+ };
3076
+ watch(
3077
+ () => props.gridPreferenceDateFilterValues,
3078
+ () => {
3079
+ if (props.gridPreferenceDateFilterValues && props.gridPreferenceDateFilterValues.filters && props.gridPreferenceDateFilterValues.filters.length > 0) {
3080
+ const filters = props.gridPreferenceDateFilterValues.filters.map((filter) => {
3081
+ const f = filter;
3082
+ if (f.name && (f.fromValue || f.toValue)) {
3083
+ if (f.presetKey) {
3084
+ const presets = props.dateRangePresets || //blueseaConfig.componentConfig.gridLookup?.dateRangePresets ||
3085
+ [];
3086
+ const timeZone = findDateFilterTimeZone(
3087
+ f.name,
3088
+ props.config?.dateFilter
3089
+ );
3090
+ return BetweenDateFilterWithPreset.createFromPresetKey(
3091
+ f.name,
3092
+ f.presetKey,
3093
+ presets,
3094
+ timeZone
3095
+ );
3096
+ } else {
3097
+ return new BetweenDateFilterWithPreset(
3098
+ f.name,
3099
+ f.fromValue,
3100
+ f.toValue
3101
+ );
3102
+ }
3103
+ }
3104
+ }).filter(notNull);
3105
+ if (filters.length > 0) {
3106
+ dateFilterValue.value = andFilter(filters);
3107
+ emitUpdateModelValue();
3108
+ }
3109
+ }
3110
+ }
3111
+ );
3112
+ const saveSearchCondition = async () => {
3113
+ };
3114
+ const resetSearchCondition = () => {
3115
+ textFilterValue.value = void 0;
3116
+ dateFilterValue.value = void 0;
3117
+ emitUpdateModelValueAndSearch();
3118
+ };
3119
+ return (_ctx, _cache) => {
3120
+ return openBlock(), createElementBlock("div", _hoisted_1, [
3121
+ __props.config?.textFilter ? (openBlock(), createBlock(_sfc_main$4, {
3122
+ key: 0,
3123
+ modelValue: textFilterValue.value,
3124
+ "onUpdate:modelValue": [
3125
+ _cache[0] || (_cache[0] = ($event) => textFilterValue.value = $event),
3126
+ emitUpdateModelValueAndSearch
3127
+ ],
3128
+ keyword: __props.keyword,
3129
+ "text-filter-items": __props.config.textFilter.filterItems,
3130
+ class: "mr-16"
3131
+ }, null, 8, ["modelValue", "keyword", "text-filter-items"])) : createCommentVNode("", true),
3132
+ __props.config?.dateFilter ? (openBlock(), createBlock(_sfc_main$2, {
3133
+ key: 1,
3134
+ modelValue: dateFilterValue.value,
3135
+ "onUpdate:modelValue": [
3136
+ _cache[1] || (_cache[1] = ($event) => dateFilterValue.value = $event),
3137
+ emitUpdateModelValueAndSearch
3138
+ ],
3139
+ "caption-min-width": __props.dateFilterCaptionMinWidth,
3140
+ "date-filter": __props.config.dateFilter,
3141
+ "date-format": __props.dateFilterDateFormat,
3142
+ "filter-width": __props.dateFilterWidth,
3143
+ "popup-date-format": __props.dateFilterPopupDateFormat,
3144
+ "popup-end-year": __props.dateFilterPopupEndYear,
3145
+ "popup-start-year": __props.dateFilterPopupStartYear,
3146
+ presets: __props.dateRangePresets,
3147
+ resolution: __props.dateFilterResolution
3148
+ }, null, 8, ["modelValue", "caption-min-width", "date-filter", "date-format", "filter-width", "popup-date-format", "popup-end-year", "popup-start-year", "presets", "resolution"])) : createCommentVNode("", true),
3149
+ createElementVNode("div", _hoisted_2, [
3150
+ createVNode(unref(BSButton), {
3151
+ caption: "Search",
3152
+ class: "blue",
3153
+ "left-icon": "search",
3154
+ onClick: emitSearch
3155
+ }),
3156
+ __props.config?.dateFilter ? (openBlock(), createBlock(unref(BSButton), {
3157
+ key: 0,
3158
+ caption: "Save",
3159
+ class: "ml-4",
3160
+ onClick: saveSearchCondition
3161
+ })) : createCommentVNode("", true),
3162
+ createVNode(unref(BSButton), {
3163
+ caption: "Reset",
3164
+ class: "ml-4",
3165
+ onClick: resetSearchCondition
3166
+ })
3167
+ ])
3168
+ ]);
3169
+ };
3170
+ }
3171
+ });
3172
+ const _sfc_main = /* @__PURE__ */ defineComponent({
3173
+ __name: "BSDateRangeFilter",
3174
+ props: {
3175
+ idFrom: {},
3176
+ idTo: {},
3177
+ nameFrom: {},
3178
+ nameTo: {},
3179
+ modelValue: {},
3180
+ disabled: { type: Boolean },
3181
+ width: { default: "300px" },
3182
+ resolution: { default: "DAY" },
3183
+ displayFormat: {},
3184
+ popupDisplayFormat: {},
3185
+ popupStartYear: {},
3186
+ popupEndYear: {},
3187
+ timeZone: {}
3188
+ },
3189
+ emits: ["update:modelValue"],
3190
+ setup(__props, { emit: __emit }) {
3191
+ const props = __props;
3192
+ const emit = __emit;
3193
+ const fromValue = ref();
3194
+ const toValue = ref();
3195
+ watch(
3196
+ () => props.modelValue,
3197
+ () => {
3198
+ fromValue.value = props.modelValue?.from;
3199
+ toValue.value = props.modelValue?.to;
3200
+ },
3201
+ { immediate: true }
3202
+ );
3203
+ const emitValue = () => {
3204
+ const value = {
3205
+ from: fromValue.value,
3206
+ to: toValue.value
3207
+ };
3208
+ emit("update:modelValue", value);
3209
+ };
3210
+ return (_ctx, _cache) => {
3211
+ return openBlock(), createBlock(unref(BSDateRange), {
3212
+ "from-value": fromValue.value,
3213
+ "onUpdate:fromValue": [
3214
+ _cache[0] || (_cache[0] = ($event) => fromValue.value = $event),
3215
+ emitValue
3216
+ ],
3217
+ "to-value": toValue.value,
3218
+ "onUpdate:toValue": [
3219
+ _cache[1] || (_cache[1] = ($event) => toValue.value = $event),
3220
+ emitValue
3221
+ ],
3222
+ "disabled-from": __props.disabled,
3223
+ "disabled-to": __props.disabled,
3224
+ "display-format": __props.displayFormat,
3225
+ "id-from": __props.idFrom,
3226
+ "id-to": __props.idTo,
3227
+ "name-from": __props.nameFrom,
3228
+ "name-to": __props.nameTo,
3229
+ "popup-display-format": __props.popupDisplayFormat,
3230
+ "popup-end-year": __props.popupEndYear,
3231
+ "popup-start-year": __props.popupStartYear,
3232
+ resolution: __props.resolution,
3233
+ "time-zone": __props.timeZone,
3234
+ "validate-date-order": false,
3235
+ width: __props.width,
3236
+ "hide-extra-date": ""
3237
+ }, null, 8, ["from-value", "to-value", "disabled-from", "disabled-to", "display-format", "id-from", "id-to", "name-from", "name-to", "popup-display-format", "popup-end-year", "popup-start-year", "resolution", "time-zone", "width"]);
3238
+ };
3239
+ }
3240
+ });
3241
+ export {
3242
+ AbstractFilter,
3243
+ AndFilter,
3244
+ _sfc_main as BSDateRangeFilter,
3245
+ _sfc_main$2 as BSDateRangeFilters,
3246
+ _sfc_main$3 as BSDateRangePresets,
3247
+ _sfc_main$7 as BSGrid,
3248
+ _sfc_main$d as BSGridCell,
3249
+ BSGridCellCheckbox,
3250
+ _sfc_main$9 as BSGridCellDragHandle,
3251
+ _sfc_main$a as BSGridCellEdit,
3252
+ _sfc_main$c as BSGridCellSerialNo,
3253
+ _sfc_main$6 as BSGridColumnSettingModal,
3254
+ _sfc_main$5 as BSGridControl,
3255
+ BSGridHeaderCell,
3256
+ _sfc_main$f as BSGridHeaderCellCheckbox,
3257
+ BSGridHeaderCellResizeHandle,
3258
+ BSGridHeaderCellSerialNo,
3259
+ _sfc_main$1 as BSGridLookup,
3260
+ _sfc_main$8 as BSGridRow,
3261
+ _sfc_main$4 as BSTextFilter,
3262
+ BetweenDateFilter,
3263
+ BetweenDateFilterWithPreset,
3264
+ BetweenFilter,
3265
+ DEFAULT_GRID_COLUMN_WIDTH,
3266
+ EditableInputGridHandlerImpl,
3267
+ EditablePageGridHandlerImpl,
3268
+ EditingRows,
3269
+ EqualFilter,
3270
+ GridHandlerEditableSupport,
3271
+ GridHandlerSelectDeleteSupport,
3272
+ InFilter,
3273
+ InputGridHandlerImpl,
3274
+ IsNotNullFilter,
3275
+ IsNullFilter,
3276
+ LikeFilter,
3277
+ LocalStorageGridPreferenceStore,
3278
+ NotFilter,
3279
+ OrFilter,
3280
+ PageGridHandlerImpl,
3281
+ PaginatedList,
3282
+ SearchParam,
3283
+ acceptFilter,
3284
+ andFilter,
3285
+ betweenDateFilter,
3286
+ betweenFilter,
3287
+ convertDateRangePresetKey,
3288
+ createDateRangeFromPreset,
3289
+ createInputGridHandler,
3290
+ createPageGridHandler,
3291
+ defaultCellFormatter,
3292
+ editComponentSlotName,
3293
+ equalFilter,
3294
+ filterSlotName,
3295
+ inFilter,
3296
+ isNotNullFilter,
3297
+ isNullFilter,
3298
+ likeFilter,
3299
+ mergeColumnSettings,
3300
+ mergeSameValueVertical,
3301
+ nameFilterCreator,
3302
+ notFilter,
3303
+ orFilter,
3304
+ resolveMoment,
3305
+ setFixedCellLeftStyle,
3306
+ styleClassToObject,
3307
+ styleCssToObject,
3308
+ vDragSupport,
3309
+ vDropSupport
3310
+ };