@htlkg/components 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -0
- package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js +367 -0
- package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js.map +1 -0
- package/dist/Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js +263 -0
- package/dist/Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js.map +1 -0
- package/dist/DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js +580 -0
- package/dist/DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js.map +1 -0
- package/dist/ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js +187 -0
- package/dist/ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js.map +1 -0
- package/dist/_plugin-vue_export-helper-1tPrXgE0.js +11 -0
- package/dist/_plugin-vue_export-helper-1tPrXgE0.js.map +1 -0
- package/dist/components.css +15 -0
- package/dist/composables/index.js +32 -573
- package/dist/composables/index.js.map +1 -1
- package/dist/data/index.js +18 -0
- package/dist/data/index.js.map +1 -0
- package/dist/domain/index.js +8 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/filterHelpers-DgRyoYSa.js +1386 -0
- package/dist/filterHelpers-DgRyoYSa.js.map +1 -0
- package/dist/forms/index.js +6 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/index-DGO_pNgG.js +79 -0
- package/dist/index-DGO_pNgG.js.map +1 -0
- package/dist/index-QK97OdqQ.js +25 -0
- package/dist/index-QK97OdqQ.js.map +1 -0
- package/dist/index.js +67 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/index.js +8 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/overlays/index.js +8 -0
- package/dist/overlays/index.js.map +1 -0
- package/dist/stores/index.js +14 -0
- package/dist/stores/index.js.map +1 -0
- package/dist/useAdminPage-GhgXp0x8.js +1070 -0
- package/dist/useAdminPage-GhgXp0x8.js.map +1 -0
- package/dist/useTable-DutR1gkg.js +293 -0
- package/dist/useTable-DutR1gkg.js.map +1 -0
- package/package.json +43 -14
- package/src/composables/composables.md +109 -0
- package/src/composables/index.ts +69 -0
- package/src/composables/useAdminPage.ts +462 -0
- package/src/composables/useConfirmation.ts +358 -0
- package/src/composables/usePageContext.ts +171 -0
- package/src/composables/useStats.ts +361 -0
- package/src/composables/useTable.ts +26 -5
- package/src/composables/useWizard.ts +448 -0
- package/src/data/DataTable.vue +553 -0
- package/src/data/Table/Table.vue +295 -0
- package/src/data/columnHelpers.ts +503 -0
- package/src/data/data.md +106 -0
- package/src/data/filterHelpers.ts +358 -0
- package/src/data/index.ts +31 -0
- package/src/domain/domain.md +102 -0
- package/src/forms/JsonSchemaForm.vue +4 -1
- package/src/forms/forms.md +89 -0
- package/src/index.ts +4 -3
- package/src/navigation/navigation.md +80 -0
- package/src/overlays/overlays.md +86 -0
- package/src/stores/stores.md +82 -0
|
@@ -0,0 +1,1386 @@
|
|
|
1
|
+
import { defineComponent, ref, computed, createBlock, openBlock, unref, createElementBlock, toDisplayString, Fragment, renderList, renderSlot, createTextVNode, toRef, watch } from "vue";
|
|
2
|
+
import { uiTable, uiSelectMultiple, uiSelect, uiChart } from "@hotelinking/ui";
|
|
3
|
+
import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.js";
|
|
4
|
+
import { u as useTable } from "./useTable-DutR1gkg.js";
|
|
5
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
6
|
+
__name: "Table",
|
|
7
|
+
props: {
|
|
8
|
+
items: {},
|
|
9
|
+
header: {},
|
|
10
|
+
loading: { type: Boolean, default: false },
|
|
11
|
+
currentPage: { default: 1 },
|
|
12
|
+
totalPages: { default: 1 },
|
|
13
|
+
totalItems: { default: 0 },
|
|
14
|
+
pageSize: { default: 10 },
|
|
15
|
+
orderedBy: { default: "" },
|
|
16
|
+
orderDirection: { default: "asc" },
|
|
17
|
+
actions: {},
|
|
18
|
+
selectAllItemsModal: {},
|
|
19
|
+
resetSelected: { type: Boolean, default: false },
|
|
20
|
+
smartFilterCategories: {},
|
|
21
|
+
filterLiterals: { default: () => ({
|
|
22
|
+
filters: "Smart Filters",
|
|
23
|
+
contains: "contains",
|
|
24
|
+
is: "is",
|
|
25
|
+
and: "and",
|
|
26
|
+
or: "or",
|
|
27
|
+
deleteAll: "Delete All",
|
|
28
|
+
filter: "Filter"
|
|
29
|
+
}) },
|
|
30
|
+
filters: {},
|
|
31
|
+
tableActionsDropdown: {},
|
|
32
|
+
tableActionButtons: {},
|
|
33
|
+
noResults: {},
|
|
34
|
+
hiddenColumns: {}
|
|
35
|
+
},
|
|
36
|
+
emits: ["update:currentPage", "update:pageSize", "update:selected", "update:orderedBy", "update:orderDirection", "update:resetSelected", "table-action", "table-action-selected", "table-action-button-clicked", "smart-filters-sent", "smart-filters-cleared", "smart-filter-deleted", "custom-emit", "modal-action", "select-all-items", "deselect-all-items", "no-results-action", "no-results-option-selected", "columns-visibility-changed", "order-by", "change-page", "change-page-size"],
|
|
37
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
38
|
+
const props = __props;
|
|
39
|
+
const emit = __emit;
|
|
40
|
+
const internalHiddenColumns = ref(props.hiddenColumns || []);
|
|
41
|
+
const selectedItemIds = ref(/* @__PURE__ */ new Set());
|
|
42
|
+
const pageSizeOptions = computed(() => [
|
|
43
|
+
{ name: "10", value: "10", active: props.pageSize === 10 },
|
|
44
|
+
{ name: "25", value: "25", active: props.pageSize === 25 },
|
|
45
|
+
{ name: "50", value: "50", active: props.pageSize === 50 },
|
|
46
|
+
{ name: "100", value: "100", active: props.pageSize === 100 }
|
|
47
|
+
]);
|
|
48
|
+
function handleOrderBy(event) {
|
|
49
|
+
emit("update:orderedBy", event.value);
|
|
50
|
+
emit("update:orderDirection", event.orderDirection);
|
|
51
|
+
emit("order-by", event);
|
|
52
|
+
}
|
|
53
|
+
function handleChangePage(page) {
|
|
54
|
+
emit("update:currentPage", page);
|
|
55
|
+
emit("change-page", page);
|
|
56
|
+
}
|
|
57
|
+
function handleChangePageSize(size) {
|
|
58
|
+
const numSize = typeof size === "string" ? Number(size) : size;
|
|
59
|
+
emit("update:pageSize", numSize);
|
|
60
|
+
emit("change-page-size", size);
|
|
61
|
+
emit("update:currentPage", 1);
|
|
62
|
+
}
|
|
63
|
+
function handleTableAction(data) {
|
|
64
|
+
selectedItemIds.value = new Set(data.items);
|
|
65
|
+
updateSelectedItems();
|
|
66
|
+
emit("table-action", data);
|
|
67
|
+
}
|
|
68
|
+
function handleTableActionSelected(item) {
|
|
69
|
+
emit("table-action-selected", item);
|
|
70
|
+
}
|
|
71
|
+
function handleTableActionButtonClicked(data) {
|
|
72
|
+
emit("table-action-button-clicked", data);
|
|
73
|
+
}
|
|
74
|
+
function handleSmartFiltersSent(filters2) {
|
|
75
|
+
emit("smart-filters-sent", filters2);
|
|
76
|
+
}
|
|
77
|
+
function handleSmartFiltersCleared() {
|
|
78
|
+
emit("smart-filters-cleared");
|
|
79
|
+
}
|
|
80
|
+
function handleSmartFilterDeleted(index) {
|
|
81
|
+
emit("smart-filter-deleted", index);
|
|
82
|
+
}
|
|
83
|
+
function handleCustomEmit(data) {
|
|
84
|
+
emit("custom-emit", data);
|
|
85
|
+
}
|
|
86
|
+
function handleColumnsVisibilityChanged(event) {
|
|
87
|
+
if (event.hidden) {
|
|
88
|
+
if (!internalHiddenColumns.value.includes(event.index)) {
|
|
89
|
+
internalHiddenColumns.value.push(event.index);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
const index = internalHiddenColumns.value.indexOf(event.index);
|
|
93
|
+
if (index > -1) {
|
|
94
|
+
internalHiddenColumns.value.splice(index, 1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
emit("columns-visibility-changed", event);
|
|
98
|
+
}
|
|
99
|
+
function handleModalAction(data) {
|
|
100
|
+
emit("modal-action", data);
|
|
101
|
+
}
|
|
102
|
+
function handleSelectAllItems() {
|
|
103
|
+
selectedItemIds.value = new Set(props.items.map((item) => item.id));
|
|
104
|
+
updateSelectedItems();
|
|
105
|
+
emit("select-all-items");
|
|
106
|
+
}
|
|
107
|
+
function handleDeselectAllItems() {
|
|
108
|
+
selectedItemIds.value.clear();
|
|
109
|
+
updateSelectedItems();
|
|
110
|
+
emit("deselect-all-items");
|
|
111
|
+
}
|
|
112
|
+
function handleNoResultsAction(action) {
|
|
113
|
+
emit("no-results-action", action);
|
|
114
|
+
}
|
|
115
|
+
function handleNoResultsOptionSelected(item) {
|
|
116
|
+
emit("no-results-option-selected", item);
|
|
117
|
+
}
|
|
118
|
+
function handleSelectedItemsDeleted() {
|
|
119
|
+
emit("update:resetSelected", false);
|
|
120
|
+
}
|
|
121
|
+
function updateSelectedItems() {
|
|
122
|
+
const selected = props.items.filter((item) => item.id && selectedItemIds.value.has(item.id));
|
|
123
|
+
emit("update:selected", selected);
|
|
124
|
+
}
|
|
125
|
+
__expose({
|
|
126
|
+
clearSelection: () => {
|
|
127
|
+
emit("update:resetSelected", true);
|
|
128
|
+
selectedItemIds.value.clear();
|
|
129
|
+
updateSelectedItems();
|
|
130
|
+
},
|
|
131
|
+
getHiddenColumns: () => internalHiddenColumns.value,
|
|
132
|
+
getSelectedItems: () => Array.from(selectedItemIds.value),
|
|
133
|
+
getSelectedItemsData: () => props.items.filter((item) => item.id && selectedItemIds.value.has(item.id))
|
|
134
|
+
});
|
|
135
|
+
return (_ctx, _cache) => {
|
|
136
|
+
return openBlock(), createBlock(unref(uiTable), {
|
|
137
|
+
loading: __props.loading,
|
|
138
|
+
header: __props.header,
|
|
139
|
+
items: __props.items,
|
|
140
|
+
"ordered-by": __props.orderedBy,
|
|
141
|
+
"order-direction": __props.orderDirection,
|
|
142
|
+
actions: __props.actions,
|
|
143
|
+
"hidden-columns": internalHiddenColumns.value,
|
|
144
|
+
"reset-selected": __props.resetSelected,
|
|
145
|
+
"select-all-items-modal": __props.selectAllItemsModal,
|
|
146
|
+
"smart-filter-categories": __props.smartFilterCategories,
|
|
147
|
+
"filter-literals": __props.filterLiterals,
|
|
148
|
+
filters: __props.filters,
|
|
149
|
+
"table-actions-dropdown": __props.tableActionsDropdown,
|
|
150
|
+
"table-action-buttons": __props.tableActionButtons,
|
|
151
|
+
"pagination-current": __props.currentPage,
|
|
152
|
+
"pagination-total": __props.totalPages,
|
|
153
|
+
"pagination-total-items": __props.totalItems,
|
|
154
|
+
"page-size-options": pageSizeOptions.value,
|
|
155
|
+
"current-page-size": __props.pageSize,
|
|
156
|
+
"no-results": __props.noResults,
|
|
157
|
+
onOrderBy: handleOrderBy,
|
|
158
|
+
onTableAction: handleTableAction,
|
|
159
|
+
onTableActionSelected: handleTableActionSelected,
|
|
160
|
+
onTableActionButtonClicked: handleTableActionButtonClicked,
|
|
161
|
+
onSmartFiltersSent: handleSmartFiltersSent,
|
|
162
|
+
onSmartFiltersCleared: handleSmartFiltersCleared,
|
|
163
|
+
onSmartFilterDeleted: handleSmartFilterDeleted,
|
|
164
|
+
onChangePage: handleChangePage,
|
|
165
|
+
onChangePageSize: handleChangePageSize,
|
|
166
|
+
onCustomEmit: handleCustomEmit,
|
|
167
|
+
onColumnsVisibilityChanged: handleColumnsVisibilityChanged,
|
|
168
|
+
onSelectedItemsDeleted: handleSelectedItemsDeleted,
|
|
169
|
+
onModalAction: handleModalAction,
|
|
170
|
+
onSelectAllItems: handleSelectAllItems,
|
|
171
|
+
onDeselectAllItems: handleDeselectAllItems,
|
|
172
|
+
onNoResultsAction: handleNoResultsAction,
|
|
173
|
+
onNoResultsOptionSelected: handleNoResultsOptionSelected
|
|
174
|
+
}, null, 8, ["loading", "header", "items", "ordered-by", "order-direction", "actions", "hidden-columns", "reset-selected", "select-all-items-modal", "smart-filter-categories", "filter-literals", "filters", "table-actions-dropdown", "table-action-buttons", "pagination-current", "pagination-total", "pagination-total-items", "page-size-options", "current-page-size", "no-results"]);
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
const Table = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-80c477af"]]);
|
|
179
|
+
const _hoisted_1 = { class: "w-full" };
|
|
180
|
+
const _hoisted_2 = {
|
|
181
|
+
key: 0,
|
|
182
|
+
class: "p-8 text-center text-gray-600"
|
|
183
|
+
};
|
|
184
|
+
const _hoisted_3 = {
|
|
185
|
+
key: 1,
|
|
186
|
+
class: "p-8 text-center text-gray-600"
|
|
187
|
+
};
|
|
188
|
+
const _hoisted_4 = {
|
|
189
|
+
key: 2,
|
|
190
|
+
class: "flex flex-col gap-2"
|
|
191
|
+
};
|
|
192
|
+
const _hoisted_5 = ["onClick"];
|
|
193
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
194
|
+
__name: "DataList",
|
|
195
|
+
props: {
|
|
196
|
+
items: {},
|
|
197
|
+
loading: { type: Boolean, default: false },
|
|
198
|
+
emptyMessage: { default: "No items to display" }
|
|
199
|
+
},
|
|
200
|
+
emits: ["item-click"],
|
|
201
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
202
|
+
const props = __props;
|
|
203
|
+
const emit = __emit;
|
|
204
|
+
__expose({
|
|
205
|
+
getItems: () => props.items
|
|
206
|
+
});
|
|
207
|
+
return (_ctx, _cache) => {
|
|
208
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
209
|
+
__props.loading ? (openBlock(), createElementBlock("div", _hoisted_2, " Loading... ")) : __props.items.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(__props.emptyMessage), 1)) : (openBlock(), createElementBlock("div", _hoisted_4, [
|
|
210
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, index) => {
|
|
211
|
+
return openBlock(), createElementBlock("div", {
|
|
212
|
+
key: index,
|
|
213
|
+
class: "p-4 border border-gray-200 rounded-md cursor-pointer hover:bg-gray-50 transition-colors",
|
|
214
|
+
onClick: ($event) => emit("item-click", item)
|
|
215
|
+
}, [
|
|
216
|
+
renderSlot(_ctx.$slots, "default", {
|
|
217
|
+
item,
|
|
218
|
+
index
|
|
219
|
+
}, () => [
|
|
220
|
+
createTextVNode(toDisplayString(JSON.stringify(item)), 1)
|
|
221
|
+
])
|
|
222
|
+
], 8, _hoisted_5);
|
|
223
|
+
}), 128))
|
|
224
|
+
]))
|
|
225
|
+
]);
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
230
|
+
__name: "SearchableSelect",
|
|
231
|
+
props: {
|
|
232
|
+
options: {},
|
|
233
|
+
modelValue: { default: null },
|
|
234
|
+
labelKey: { default: "label" },
|
|
235
|
+
valueKey: { default: "id" },
|
|
236
|
+
placeholder: { default: "Select an option" },
|
|
237
|
+
label: { default: "" },
|
|
238
|
+
error: { default: "" },
|
|
239
|
+
color: { default: "gray" },
|
|
240
|
+
loading: { type: Boolean, default: false },
|
|
241
|
+
disabled: { type: Boolean, default: false },
|
|
242
|
+
requiredText: { default: "" },
|
|
243
|
+
multiple: { type: Boolean, default: false }
|
|
244
|
+
},
|
|
245
|
+
emits: ["update:modelValue", "change"],
|
|
246
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
247
|
+
const props = __props;
|
|
248
|
+
const emit = __emit;
|
|
249
|
+
const transformedItems = computed(() => {
|
|
250
|
+
return props.options.map((option) => ({
|
|
251
|
+
id: String(option[props.valueKey]),
|
|
252
|
+
name: String(option[props.labelKey]),
|
|
253
|
+
label: option.label ? String(option.label) : void 0
|
|
254
|
+
}));
|
|
255
|
+
});
|
|
256
|
+
const selectedItem = computed(() => {
|
|
257
|
+
if (props.multiple || !props.modelValue) {
|
|
258
|
+
return { id: "", name: "", label: void 0 };
|
|
259
|
+
}
|
|
260
|
+
const value = props.modelValue;
|
|
261
|
+
return {
|
|
262
|
+
id: String(value[props.valueKey]),
|
|
263
|
+
name: String(value[props.labelKey]),
|
|
264
|
+
label: value.label ? String(value.label) : void 0
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
const selectedItems = computed(() => {
|
|
268
|
+
if (!props.multiple || !props.modelValue) return [];
|
|
269
|
+
const values = Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue];
|
|
270
|
+
return values.map((value) => ({
|
|
271
|
+
id: String(value[props.valueKey]),
|
|
272
|
+
name: String(value[props.labelKey]),
|
|
273
|
+
label: value.label ? String(value.label) : void 0
|
|
274
|
+
}));
|
|
275
|
+
});
|
|
276
|
+
function handleSelectChange(selected) {
|
|
277
|
+
if (props.multiple) {
|
|
278
|
+
const originalValues = selected.map((item) => {
|
|
279
|
+
return props.options.find((opt) => String(opt[props.valueKey]) === item.id);
|
|
280
|
+
}).filter(Boolean);
|
|
281
|
+
emit("update:modelValue", originalValues);
|
|
282
|
+
emit("change", originalValues);
|
|
283
|
+
} else {
|
|
284
|
+
const originalValue = props.options.find((opt) => String(opt[props.valueKey]) === selected.id);
|
|
285
|
+
emit("update:modelValue", originalValue || null);
|
|
286
|
+
emit("change", originalValue || null);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
__expose({
|
|
290
|
+
getSelected: () => props.modelValue
|
|
291
|
+
});
|
|
292
|
+
return (_ctx, _cache) => {
|
|
293
|
+
return __props.multiple ? (openBlock(), createBlock(unref(uiSelectMultiple), {
|
|
294
|
+
key: 0,
|
|
295
|
+
items: transformedItems.value,
|
|
296
|
+
label: __props.label,
|
|
297
|
+
placeholder: __props.placeholder,
|
|
298
|
+
error: __props.error,
|
|
299
|
+
color: __props.color,
|
|
300
|
+
select: selectedItems.value,
|
|
301
|
+
loading: __props.loading,
|
|
302
|
+
disabled: __props.disabled,
|
|
303
|
+
"required-text": __props.requiredText,
|
|
304
|
+
onSelectChanged: handleSelectChange
|
|
305
|
+
}, null, 8, ["items", "label", "placeholder", "error", "color", "select", "loading", "disabled", "required-text"])) : (openBlock(), createBlock(unref(uiSelect), {
|
|
306
|
+
key: 1,
|
|
307
|
+
items: transformedItems.value,
|
|
308
|
+
label: __props.label,
|
|
309
|
+
placeholder: __props.placeholder,
|
|
310
|
+
error: __props.error,
|
|
311
|
+
color: __props.color,
|
|
312
|
+
select: selectedItem.value,
|
|
313
|
+
loading: __props.loading,
|
|
314
|
+
disabled: __props.disabled,
|
|
315
|
+
"required-text": __props.requiredText,
|
|
316
|
+
onSelectChanged: handleSelectChange
|
|
317
|
+
}, null, 8, ["items", "label", "placeholder", "error", "color", "select", "loading", "disabled", "required-text"]));
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
322
|
+
__name: "Chart",
|
|
323
|
+
props: {
|
|
324
|
+
id: {},
|
|
325
|
+
title: {},
|
|
326
|
+
series: {},
|
|
327
|
+
type: { default: "line" },
|
|
328
|
+
options: {},
|
|
329
|
+
loading: { type: Boolean, default: false },
|
|
330
|
+
empty: { type: Boolean, default: false },
|
|
331
|
+
range: {},
|
|
332
|
+
horizontal: { type: Boolean, default: false },
|
|
333
|
+
stacked: { type: Boolean, default: false },
|
|
334
|
+
height: {},
|
|
335
|
+
labels: {},
|
|
336
|
+
dates: {},
|
|
337
|
+
isNps: { type: Boolean, default: false },
|
|
338
|
+
npsLiterals: {},
|
|
339
|
+
annotations: {}
|
|
340
|
+
},
|
|
341
|
+
emits: ["range-selected", "chart-updated", "data-point-selection", "maximize"],
|
|
342
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
343
|
+
const props = __props;
|
|
344
|
+
const emit = __emit;
|
|
345
|
+
function handleRangeSelected(data) {
|
|
346
|
+
emit("range-selected", data);
|
|
347
|
+
}
|
|
348
|
+
function handleChartUpdated() {
|
|
349
|
+
emit("chart-updated");
|
|
350
|
+
}
|
|
351
|
+
function handleDataPointSelection(data) {
|
|
352
|
+
emit("data-point-selection", data);
|
|
353
|
+
}
|
|
354
|
+
function handleMaximizeChart(chartId) {
|
|
355
|
+
emit("maximize", chartId);
|
|
356
|
+
}
|
|
357
|
+
function refresh() {
|
|
358
|
+
emit("chart-updated");
|
|
359
|
+
}
|
|
360
|
+
function getChartId() {
|
|
361
|
+
return props.id;
|
|
362
|
+
}
|
|
363
|
+
__expose({
|
|
364
|
+
refresh,
|
|
365
|
+
getChartId
|
|
366
|
+
});
|
|
367
|
+
return (_ctx, _cache) => {
|
|
368
|
+
return openBlock(), createBlock(unref(uiChart), {
|
|
369
|
+
id: __props.id,
|
|
370
|
+
title: __props.title,
|
|
371
|
+
type: __props.type,
|
|
372
|
+
series: __props.series,
|
|
373
|
+
options: __props.options,
|
|
374
|
+
loading: __props.loading,
|
|
375
|
+
empty: __props.empty,
|
|
376
|
+
range: __props.range,
|
|
377
|
+
horizontal: __props.horizontal,
|
|
378
|
+
stacked: __props.stacked,
|
|
379
|
+
height: __props.height,
|
|
380
|
+
labels: __props.labels,
|
|
381
|
+
dates: __props.dates,
|
|
382
|
+
isNps: __props.isNps,
|
|
383
|
+
npsLiterals: __props.npsLiterals,
|
|
384
|
+
annotations: __props.annotations,
|
|
385
|
+
onSelectedRange: handleRangeSelected,
|
|
386
|
+
onChartUpdated: handleChartUpdated,
|
|
387
|
+
onDataPointSelection: handleDataPointSelection,
|
|
388
|
+
onMaximizeChart: handleMaximizeChart
|
|
389
|
+
}, null, 8, ["id", "title", "type", "series", "options", "loading", "empty", "range", "horizontal", "stacked", "height", "labels", "dates", "isNps", "npsLiterals", "annotations"]);
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
394
|
+
__name: "DataTable",
|
|
395
|
+
props: {
|
|
396
|
+
items: {},
|
|
397
|
+
columns: {},
|
|
398
|
+
filters: {},
|
|
399
|
+
initialFilters: {},
|
|
400
|
+
loading: { type: Boolean, default: false },
|
|
401
|
+
pageSize: { default: 10 },
|
|
402
|
+
currentPage: { default: 1 },
|
|
403
|
+
totalPages: { default: 1 },
|
|
404
|
+
totalItems: { default: 0 },
|
|
405
|
+
idKey: { default: "id" },
|
|
406
|
+
actions: {},
|
|
407
|
+
selectable: { type: Boolean, default: false },
|
|
408
|
+
bulkActions: {},
|
|
409
|
+
noResults: {},
|
|
410
|
+
defaultSortKey: {},
|
|
411
|
+
defaultSortOrder: { default: "asc" },
|
|
412
|
+
syncUrl: { type: Boolean, default: false }
|
|
413
|
+
},
|
|
414
|
+
emits: ["action", "bulkAction", "selection", "rowClick", "customEmit", "pageChange", "sortChange", "filterChange"],
|
|
415
|
+
setup(__props, { emit: __emit }) {
|
|
416
|
+
const props = __props;
|
|
417
|
+
const emit = __emit;
|
|
418
|
+
function updateUrl(params) {
|
|
419
|
+
if (typeof window === "undefined") return;
|
|
420
|
+
const url = new URL(window.location.href);
|
|
421
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
422
|
+
if (value !== void 0 && value !== "") {
|
|
423
|
+
url.searchParams.set(key, value);
|
|
424
|
+
} else {
|
|
425
|
+
url.searchParams.delete(key);
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
window.location.href = url.toString();
|
|
429
|
+
}
|
|
430
|
+
function handlePageChange(page) {
|
|
431
|
+
if (props.syncUrl) {
|
|
432
|
+
emit("pageChange", page);
|
|
433
|
+
updateUrl({ page: String(page) });
|
|
434
|
+
} else {
|
|
435
|
+
table.handlePageChange(page);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function handlePageSizeChange(size) {
|
|
439
|
+
if (props.syncUrl) {
|
|
440
|
+
updateUrl({ pageSize: String(size), page: "1" });
|
|
441
|
+
} else {
|
|
442
|
+
table.handlePageSizeChange(size);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
function handleOrderBy(event) {
|
|
446
|
+
if (props.syncUrl) {
|
|
447
|
+
emit("sortChange", event.value, event.orderDirection);
|
|
448
|
+
updateUrl({ sortKey: event.value, sortOrder: event.orderDirection, page: "1" });
|
|
449
|
+
} else {
|
|
450
|
+
table.handleOrderBy(event);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function extractFilterValue(value) {
|
|
454
|
+
if (value === void 0 || value === null || value === "") {
|
|
455
|
+
return void 0;
|
|
456
|
+
}
|
|
457
|
+
if (typeof value === "object" && value !== null && "id" in value) {
|
|
458
|
+
return String(value.id);
|
|
459
|
+
}
|
|
460
|
+
return String(value);
|
|
461
|
+
}
|
|
462
|
+
function handleFiltersApplied(filters2) {
|
|
463
|
+
if (props.syncUrl) {
|
|
464
|
+
const filterParams = { page: "1" };
|
|
465
|
+
if (filters2 && typeof filters2 === "object" && "filters" in filters2 && Array.isArray(filters2.filters)) {
|
|
466
|
+
filters2.filters.forEach((f) => {
|
|
467
|
+
const extractedValue = extractFilterValue(f.value);
|
|
468
|
+
if (extractedValue !== void 0) {
|
|
469
|
+
filterParams[f.name] = extractedValue;
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
} else if (Array.isArray(filters2)) {
|
|
473
|
+
filters2.forEach((f) => {
|
|
474
|
+
const key = f.category || f.name;
|
|
475
|
+
const extractedValue = extractFilterValue(f.value);
|
|
476
|
+
if (key && extractedValue !== void 0) {
|
|
477
|
+
filterParams[key] = extractedValue;
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
} else if (filters2 && typeof filters2 === "object") {
|
|
481
|
+
Object.entries(filters2).forEach(([key, value]) => {
|
|
482
|
+
if (key === "logicOperator" || key === "filters") return;
|
|
483
|
+
const extractedValue = extractFilterValue(value);
|
|
484
|
+
if (extractedValue !== void 0) {
|
|
485
|
+
filterParams[key] = extractedValue;
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
emit("filterChange", filterParams);
|
|
490
|
+
updateUrl(filterParams);
|
|
491
|
+
} else {
|
|
492
|
+
table.handleSmartFiltersApplied(filters2);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function handleFiltersCleared() {
|
|
496
|
+
if (props.syncUrl) {
|
|
497
|
+
if (typeof window === "undefined") return;
|
|
498
|
+
const url = new URL(window.location.href);
|
|
499
|
+
const keysToRemove = [];
|
|
500
|
+
url.searchParams.forEach((_, key) => {
|
|
501
|
+
if (!["page", "pageSize", "sortKey", "sortOrder"].includes(key)) {
|
|
502
|
+
keysToRemove.push(key);
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
keysToRemove.forEach((key) => url.searchParams.delete(key));
|
|
506
|
+
url.searchParams.set("page", "1");
|
|
507
|
+
window.location.href = url.toString();
|
|
508
|
+
} else {
|
|
509
|
+
table.handleSmartFiltersCleared();
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
function handleFilterDeleted(index) {
|
|
513
|
+
if (props.syncUrl) {
|
|
514
|
+
handleFiltersCleared();
|
|
515
|
+
} else {
|
|
516
|
+
table.handleSmartFilterDeleted(index);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
const table = useTable({
|
|
520
|
+
items: toRef(() => props.items),
|
|
521
|
+
pageSize: props.pageSize,
|
|
522
|
+
sortKey: props.defaultSortKey ?? "",
|
|
523
|
+
sortOrder: props.defaultSortOrder,
|
|
524
|
+
idKey: props.idKey
|
|
525
|
+
});
|
|
526
|
+
const tableHeader = computed(
|
|
527
|
+
() => props.columns.map((col) => ({
|
|
528
|
+
name: col.key,
|
|
529
|
+
label: col.label,
|
|
530
|
+
sortable: col.sortable !== false,
|
|
531
|
+
width: col.width
|
|
532
|
+
}))
|
|
533
|
+
);
|
|
534
|
+
const tableItems = computed(() => {
|
|
535
|
+
const itemsToRender = props.syncUrl ? props.items : table.paginatedItems.value;
|
|
536
|
+
return itemsToRender.map((item, itemIndex) => ({
|
|
537
|
+
id: item[props.idKey],
|
|
538
|
+
row: props.columns.map((col) => {
|
|
539
|
+
if (col.render) {
|
|
540
|
+
return col.render(item, itemIndex);
|
|
541
|
+
}
|
|
542
|
+
const value = item[col.key];
|
|
543
|
+
return formatCellValue(value, col.type);
|
|
544
|
+
}),
|
|
545
|
+
// Store original item for action handlers
|
|
546
|
+
_originalData: item
|
|
547
|
+
}));
|
|
548
|
+
});
|
|
549
|
+
const filterCategories = computed(
|
|
550
|
+
() => {
|
|
551
|
+
var _a;
|
|
552
|
+
return ((_a = props.filters) == null ? void 0 : _a.map((f) => ({
|
|
553
|
+
id: f.key,
|
|
554
|
+
name: f.label,
|
|
555
|
+
componentType: mapFilterType(f.type),
|
|
556
|
+
defaultProps: buildFilterProps(f)
|
|
557
|
+
}))) ?? [];
|
|
558
|
+
}
|
|
559
|
+
);
|
|
560
|
+
const initialTableFilters = computed(() => {
|
|
561
|
+
if (!props.initialFilters || !props.filters) return void 0;
|
|
562
|
+
const filterEntries = Object.entries(props.initialFilters).filter(
|
|
563
|
+
([, value]) => value !== void 0 && value !== null && value !== ""
|
|
564
|
+
);
|
|
565
|
+
if (filterEntries.length === 0) return void 0;
|
|
566
|
+
return {
|
|
567
|
+
logicOperator: "and",
|
|
568
|
+
filters: filterEntries.map(([key, value]) => {
|
|
569
|
+
var _a;
|
|
570
|
+
const filterDef = (_a = props.filters) == null ? void 0 : _a.find((f) => f.key === key);
|
|
571
|
+
return {
|
|
572
|
+
name: key,
|
|
573
|
+
label: (filterDef == null ? void 0 : filterDef.label) ?? key,
|
|
574
|
+
type: filterDef ? mapFilterType(filterDef.type) : "uiInput",
|
|
575
|
+
value: String(value)
|
|
576
|
+
};
|
|
577
|
+
})
|
|
578
|
+
};
|
|
579
|
+
});
|
|
580
|
+
const rowActions = computed(() => {
|
|
581
|
+
if (!props.actions || props.actions.length === 0) return void 0;
|
|
582
|
+
return props.actions.map((action) => {
|
|
583
|
+
if (typeof action === "string") {
|
|
584
|
+
return { name: action, id: action };
|
|
585
|
+
}
|
|
586
|
+
return { name: action.label, id: action.id };
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
const bulkActionButtons = computed(() => {
|
|
590
|
+
if (!props.bulkActions || !props.selectable) return void 0;
|
|
591
|
+
return props.bulkActions.map((action) => ({
|
|
592
|
+
text: action.label,
|
|
593
|
+
id: action.id,
|
|
594
|
+
color: action.variant === "danger" ? "red" : action.variant === "warning" ? "yellow" : "blue",
|
|
595
|
+
icon: action.icon
|
|
596
|
+
}));
|
|
597
|
+
});
|
|
598
|
+
const selectAllModal = computed(() => {
|
|
599
|
+
if (!props.selectable) return void 0;
|
|
600
|
+
return {
|
|
601
|
+
title: "Select All Items",
|
|
602
|
+
message: `Select all ${table.totalItems.value} items?`,
|
|
603
|
+
cancelText: "Select page only",
|
|
604
|
+
confirmText: "Select all"
|
|
605
|
+
};
|
|
606
|
+
});
|
|
607
|
+
function formatCellValue(value, type) {
|
|
608
|
+
if (value === null || value === void 0) return "";
|
|
609
|
+
switch (type) {
|
|
610
|
+
case "date":
|
|
611
|
+
if (value instanceof Date) {
|
|
612
|
+
return value.toLocaleDateString();
|
|
613
|
+
}
|
|
614
|
+
if (typeof value === "string") {
|
|
615
|
+
return new Date(value).toLocaleDateString();
|
|
616
|
+
}
|
|
617
|
+
return value;
|
|
618
|
+
case "number":
|
|
619
|
+
return typeof value === "number" ? value.toLocaleString() : value;
|
|
620
|
+
case "badge":
|
|
621
|
+
return { content: value, type: "badge" };
|
|
622
|
+
case "tag":
|
|
623
|
+
return { content: value, type: "tag" };
|
|
624
|
+
default:
|
|
625
|
+
return value;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
function mapFilterType(type) {
|
|
629
|
+
switch (type) {
|
|
630
|
+
case "select":
|
|
631
|
+
return "uiSelect";
|
|
632
|
+
default:
|
|
633
|
+
return "uiInput";
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
function buildFilterProps(filter) {
|
|
637
|
+
const defaultProps = {};
|
|
638
|
+
if (filter.placeholder) {
|
|
639
|
+
defaultProps.placeholder = filter.placeholder;
|
|
640
|
+
}
|
|
641
|
+
if (filter.type === "select" && filter.options) {
|
|
642
|
+
defaultProps.items = filter.options.map((opt, index) => ({
|
|
643
|
+
id: String(index),
|
|
644
|
+
name: String(opt.value),
|
|
645
|
+
// This is what gets used as filter value
|
|
646
|
+
label: opt.label
|
|
647
|
+
// This is what gets displayed
|
|
648
|
+
}));
|
|
649
|
+
}
|
|
650
|
+
if (filter.type === "number") {
|
|
651
|
+
defaultProps.type = "number";
|
|
652
|
+
}
|
|
653
|
+
return defaultProps;
|
|
654
|
+
}
|
|
655
|
+
function handleTableAction(data) {
|
|
656
|
+
const itemId = data.items[0];
|
|
657
|
+
const tableItem = tableItems.value.find((ti) => ti.id === itemId);
|
|
658
|
+
if (tableItem && tableItem._originalData) {
|
|
659
|
+
emit("action", data.action, tableItem._originalData);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
function handleBulkActionClick(data) {
|
|
663
|
+
emit("bulkAction", data.id, table.selectedItems.value);
|
|
664
|
+
}
|
|
665
|
+
function handleCustomEmit(data) {
|
|
666
|
+
emit("customEmit", data);
|
|
667
|
+
}
|
|
668
|
+
watch(
|
|
669
|
+
() => table.selectedItems.value,
|
|
670
|
+
(items) => {
|
|
671
|
+
emit("selection", items);
|
|
672
|
+
},
|
|
673
|
+
{ deep: true }
|
|
674
|
+
);
|
|
675
|
+
return (_ctx, _cache) => {
|
|
676
|
+
return openBlock(), createBlock(Table, {
|
|
677
|
+
header: tableHeader.value,
|
|
678
|
+
items: tableItems.value,
|
|
679
|
+
loading: __props.loading,
|
|
680
|
+
"current-page": __props.syncUrl ? __props.currentPage : unref(table).currentPage.value,
|
|
681
|
+
"total-pages": __props.syncUrl ? __props.totalPages : unref(table).totalPages.value,
|
|
682
|
+
"total-items": __props.syncUrl ? __props.totalItems : unref(table).totalItems.value,
|
|
683
|
+
"page-size": __props.syncUrl ? __props.pageSize : unref(table).pageSize.value,
|
|
684
|
+
"ordered-by": __props.defaultSortKey ?? unref(table).sortKey.value,
|
|
685
|
+
"order-direction": __props.defaultSortOrder ?? unref(table).sortOrder.value,
|
|
686
|
+
"smart-filter-categories": filterCategories.value,
|
|
687
|
+
filters: initialTableFilters.value,
|
|
688
|
+
"hidden-columns": unref(table).hiddenColumns.value,
|
|
689
|
+
"reset-selected": unref(table).resetSelected.value,
|
|
690
|
+
actions: rowActions.value,
|
|
691
|
+
"select-all-items-modal": selectAllModal.value,
|
|
692
|
+
"table-action-buttons": bulkActionButtons.value,
|
|
693
|
+
"no-results": __props.noResults,
|
|
694
|
+
onChangePage: handlePageChange,
|
|
695
|
+
onChangePageSize: handlePageSizeChange,
|
|
696
|
+
onOrderBy: handleOrderBy,
|
|
697
|
+
onSmartFiltersSent: handleFiltersApplied,
|
|
698
|
+
onSmartFiltersCleared: handleFiltersCleared,
|
|
699
|
+
onSmartFilterDeleted: handleFilterDeleted,
|
|
700
|
+
onColumnsVisibilityChanged: unref(table).handleColumnsVisibilityChanged,
|
|
701
|
+
onModalAction: unref(table).handleModalAction,
|
|
702
|
+
onTableAction: handleTableAction,
|
|
703
|
+
onTableActionButtonClicked: handleBulkActionClick,
|
|
704
|
+
onCustomEmit: handleCustomEmit
|
|
705
|
+
}, null, 8, ["header", "items", "loading", "current-page", "total-pages", "total-items", "page-size", "ordered-by", "order-direction", "smart-filter-categories", "filters", "hidden-columns", "reset-selected", "actions", "select-all-items-modal", "table-action-buttons", "no-results", "onColumnsVisibilityChanged", "onModalAction"]);
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
const columns = {
|
|
710
|
+
/**
|
|
711
|
+
* Simple text column
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* columns.text('name', 'Name')
|
|
715
|
+
*/
|
|
716
|
+
text: (key, label, options) => ({
|
|
717
|
+
key,
|
|
718
|
+
label,
|
|
719
|
+
type: "text",
|
|
720
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
721
|
+
width: options == null ? void 0 : options.width
|
|
722
|
+
}),
|
|
723
|
+
/**
|
|
724
|
+
* Number column with locale formatting
|
|
725
|
+
*
|
|
726
|
+
* @example
|
|
727
|
+
* columns.number('amount', 'Amount')
|
|
728
|
+
* columns.number('price', 'Price', { prefix: '$', decimals: 2 })
|
|
729
|
+
*/
|
|
730
|
+
number: (key, label, options) => ({
|
|
731
|
+
key,
|
|
732
|
+
label,
|
|
733
|
+
type: "number",
|
|
734
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
735
|
+
render: (item) => {
|
|
736
|
+
const value = item[key];
|
|
737
|
+
if (value === null || value === void 0) return "";
|
|
738
|
+
const formatted = (options == null ? void 0 : options.decimals) !== void 0 ? Number(value).toLocaleString(void 0, {
|
|
739
|
+
minimumFractionDigits: options.decimals,
|
|
740
|
+
maximumFractionDigits: options.decimals
|
|
741
|
+
}) : Number(value).toLocaleString();
|
|
742
|
+
return `${(options == null ? void 0 : options.prefix) ?? ""}${formatted}${(options == null ? void 0 : options.suffix) ?? ""}`;
|
|
743
|
+
}
|
|
744
|
+
}),
|
|
745
|
+
/**
|
|
746
|
+
* Date column with formatting
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* columns.date('createdAt', 'Created')
|
|
750
|
+
* columns.date('updatedAt', 'Updated', { format: 'long' })
|
|
751
|
+
*/
|
|
752
|
+
date: (key, label, options) => ({
|
|
753
|
+
key,
|
|
754
|
+
label,
|
|
755
|
+
type: "date",
|
|
756
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
757
|
+
render: (item) => {
|
|
758
|
+
const value = item[key];
|
|
759
|
+
if (!value) return "";
|
|
760
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
761
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
762
|
+
const formatOptions = {
|
|
763
|
+
short: { dateStyle: "short" },
|
|
764
|
+
medium: { dateStyle: "medium" },
|
|
765
|
+
long: { dateStyle: "long" },
|
|
766
|
+
full: { dateStyle: "full" }
|
|
767
|
+
}[(options == null ? void 0 : options.format) ?? "medium"];
|
|
768
|
+
return date.toLocaleDateString(options == null ? void 0 : options.locale, formatOptions);
|
|
769
|
+
}
|
|
770
|
+
}),
|
|
771
|
+
/**
|
|
772
|
+
* DateTime column with formatting
|
|
773
|
+
*
|
|
774
|
+
* @example
|
|
775
|
+
* columns.dateTime('createdAt', 'Created At')
|
|
776
|
+
*/
|
|
777
|
+
dateTime: (key, label, options) => ({
|
|
778
|
+
key,
|
|
779
|
+
label,
|
|
780
|
+
type: "date",
|
|
781
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
782
|
+
render: (item) => {
|
|
783
|
+
const value = item[key];
|
|
784
|
+
if (!value) return "";
|
|
785
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
786
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
787
|
+
return date.toLocaleString(options == null ? void 0 : options.locale, {
|
|
788
|
+
dateStyle: "medium",
|
|
789
|
+
timeStyle: "short"
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
}),
|
|
793
|
+
/**
|
|
794
|
+
* Tag column with optional color function
|
|
795
|
+
*
|
|
796
|
+
* @example
|
|
797
|
+
* columns.tag('status', 'Status')
|
|
798
|
+
* columns.tag('status', 'Status', (item) => item.active ? 'green' : 'red')
|
|
799
|
+
*/
|
|
800
|
+
tag: (key, label, colorFn, options) => ({
|
|
801
|
+
key,
|
|
802
|
+
label,
|
|
803
|
+
type: "tag",
|
|
804
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
805
|
+
render: (item) => {
|
|
806
|
+
const value = item[key];
|
|
807
|
+
return {
|
|
808
|
+
content: value,
|
|
809
|
+
color: (colorFn == null ? void 0 : colorFn(item)) ?? "gray",
|
|
810
|
+
type: "tag"
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
}),
|
|
814
|
+
/**
|
|
815
|
+
* Badge column (numeric badge style)
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* columns.badge('count', 'Count')
|
|
819
|
+
* columns.badge('brandCount', 'Brands')
|
|
820
|
+
*/
|
|
821
|
+
badge: (key, label, options) => ({
|
|
822
|
+
key,
|
|
823
|
+
label,
|
|
824
|
+
type: "badge",
|
|
825
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
826
|
+
render: (item) => ({
|
|
827
|
+
content: item[key],
|
|
828
|
+
type: "badge"
|
|
829
|
+
})
|
|
830
|
+
}),
|
|
831
|
+
/**
|
|
832
|
+
* Boolean column rendered as tag
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* columns.boolean('active', 'Active')
|
|
836
|
+
* columns.boolean('verified', 'Verified', { trueLabel: 'Yes', falseLabel: 'No' })
|
|
837
|
+
*/
|
|
838
|
+
boolean: (key, label, options) => ({
|
|
839
|
+
key,
|
|
840
|
+
label,
|
|
841
|
+
type: "tag",
|
|
842
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
843
|
+
render: (item) => {
|
|
844
|
+
const value = Boolean(item[key]);
|
|
845
|
+
return {
|
|
846
|
+
content: value ? (options == null ? void 0 : options.trueLabel) ?? "Yes" : (options == null ? void 0 : options.falseLabel) ?? "No",
|
|
847
|
+
color: value ? (options == null ? void 0 : options.trueColor) ?? "green" : (options == null ? void 0 : options.falseColor) ?? "red",
|
|
848
|
+
type: "tag"
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
}),
|
|
852
|
+
/**
|
|
853
|
+
* Email column (renders as link)
|
|
854
|
+
*
|
|
855
|
+
* @example
|
|
856
|
+
* columns.email('email', 'Email')
|
|
857
|
+
*/
|
|
858
|
+
email: (key, label, options) => ({
|
|
859
|
+
key,
|
|
860
|
+
label,
|
|
861
|
+
type: "text",
|
|
862
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
863
|
+
render: (item) => ({
|
|
864
|
+
content: item[key],
|
|
865
|
+
type: "link",
|
|
866
|
+
href: `mailto:${item[key]}`
|
|
867
|
+
})
|
|
868
|
+
}),
|
|
869
|
+
/**
|
|
870
|
+
* Actions column (row actions)
|
|
871
|
+
*
|
|
872
|
+
* @example
|
|
873
|
+
* columns.actions(['view', 'edit', 'delete'])
|
|
874
|
+
*/
|
|
875
|
+
actions: (actions) => ({
|
|
876
|
+
key: "_actions",
|
|
877
|
+
label: "",
|
|
878
|
+
sortable: false,
|
|
879
|
+
render: () => actions
|
|
880
|
+
}),
|
|
881
|
+
/**
|
|
882
|
+
* Custom render column
|
|
883
|
+
*
|
|
884
|
+
* @example
|
|
885
|
+
* columns.custom('fullName', 'Name', (item) => `${item.firstName} ${item.lastName}`)
|
|
886
|
+
*/
|
|
887
|
+
custom: (key, label, render, options) => ({
|
|
888
|
+
key,
|
|
889
|
+
label,
|
|
890
|
+
sortable: (options == null ? void 0 : options.sortable) ?? false,
|
|
891
|
+
width: options == null ? void 0 : options.width,
|
|
892
|
+
render
|
|
893
|
+
}),
|
|
894
|
+
/**
|
|
895
|
+
* Truncated text column
|
|
896
|
+
*
|
|
897
|
+
* @example
|
|
898
|
+
* columns.truncate('description', 'Description', 50)
|
|
899
|
+
*/
|
|
900
|
+
truncate: (key, label, maxLength, options) => ({
|
|
901
|
+
key,
|
|
902
|
+
label,
|
|
903
|
+
type: "text",
|
|
904
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
905
|
+
render: (item) => {
|
|
906
|
+
const value = String(item[key] ?? "");
|
|
907
|
+
if (value.length <= maxLength) return value;
|
|
908
|
+
return `${value.substring(0, maxLength)}...`;
|
|
909
|
+
}
|
|
910
|
+
}),
|
|
911
|
+
/**
|
|
912
|
+
* Image column
|
|
913
|
+
*
|
|
914
|
+
* @example
|
|
915
|
+
* columns.image('avatar', 'Avatar', { size: 32 })
|
|
916
|
+
*/
|
|
917
|
+
image: (key, label, options) => ({
|
|
918
|
+
key,
|
|
919
|
+
label,
|
|
920
|
+
sortable: false,
|
|
921
|
+
render: (item) => ({
|
|
922
|
+
content: item[key] || (options == null ? void 0 : options.fallback),
|
|
923
|
+
type: "image",
|
|
924
|
+
size: (options == null ? void 0 : options.size) ?? 32
|
|
925
|
+
})
|
|
926
|
+
}),
|
|
927
|
+
/**
|
|
928
|
+
* Progress column
|
|
929
|
+
*
|
|
930
|
+
* @example
|
|
931
|
+
* columns.progress('completion', 'Progress')
|
|
932
|
+
*/
|
|
933
|
+
progress: (key, label, options) => ({
|
|
934
|
+
key,
|
|
935
|
+
label,
|
|
936
|
+
type: "number",
|
|
937
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
938
|
+
render: (item) => ({
|
|
939
|
+
content: item[key],
|
|
940
|
+
type: "progress",
|
|
941
|
+
max: (options == null ? void 0 : options.max) ?? 100
|
|
942
|
+
})
|
|
943
|
+
}),
|
|
944
|
+
/**
|
|
945
|
+
* Clickable link column that emits an action
|
|
946
|
+
*
|
|
947
|
+
* @example
|
|
948
|
+
* // Simple link with action
|
|
949
|
+
* columns.link('name', 'Campaign Name', (item) => ({
|
|
950
|
+
* action: 'view',
|
|
951
|
+
* data: { id: item.id }
|
|
952
|
+
* }))
|
|
953
|
+
*
|
|
954
|
+
* // Link with custom emit handler in parent
|
|
955
|
+
* columns.link('title', 'Title', (item) => ({
|
|
956
|
+
* action: 'openDetails',
|
|
957
|
+
* data: item
|
|
958
|
+
* }))
|
|
959
|
+
*/
|
|
960
|
+
link: (key, label, emitConfig, options) => ({
|
|
961
|
+
key,
|
|
962
|
+
label,
|
|
963
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
964
|
+
width: options == null ? void 0 : options.width,
|
|
965
|
+
render: (item) => ({
|
|
966
|
+
content: item[key],
|
|
967
|
+
type: "link",
|
|
968
|
+
emits: emitConfig(item)
|
|
969
|
+
})
|
|
970
|
+
}),
|
|
971
|
+
/**
|
|
972
|
+
* Link to external URL
|
|
973
|
+
*
|
|
974
|
+
* @example
|
|
975
|
+
* columns.externalLink('website', 'Website')
|
|
976
|
+
* columns.externalLink('url', 'URL', { newTab: true })
|
|
977
|
+
*/
|
|
978
|
+
externalLink: (key, label, options) => ({
|
|
979
|
+
key,
|
|
980
|
+
label,
|
|
981
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
982
|
+
render: (item) => {
|
|
983
|
+
const url = item[key];
|
|
984
|
+
const display = (options == null ? void 0 : options.displayKey) ? item[options.displayKey] : url;
|
|
985
|
+
return {
|
|
986
|
+
content: display,
|
|
987
|
+
type: "link",
|
|
988
|
+
href: url,
|
|
989
|
+
target: (options == null ? void 0 : options.newTab) ? "_blank" : void 0
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
}),
|
|
993
|
+
/**
|
|
994
|
+
* Relative time column (e.g., "2 hours ago")
|
|
995
|
+
*
|
|
996
|
+
* @example
|
|
997
|
+
* columns.relativeTime('updatedAt', 'Last Updated')
|
|
998
|
+
*/
|
|
999
|
+
relativeTime: (key, label, options) => ({
|
|
1000
|
+
key,
|
|
1001
|
+
label,
|
|
1002
|
+
type: "date",
|
|
1003
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
1004
|
+
render: (item) => {
|
|
1005
|
+
const value = item[key];
|
|
1006
|
+
if (!value) return "";
|
|
1007
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
1008
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
1009
|
+
const now = /* @__PURE__ */ new Date();
|
|
1010
|
+
const diffMs = now.getTime() - date.getTime();
|
|
1011
|
+
const diffSecs = Math.floor(diffMs / 1e3);
|
|
1012
|
+
const diffMins = Math.floor(diffSecs / 60);
|
|
1013
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
1014
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
1015
|
+
if (diffSecs < 60) return "Just now";
|
|
1016
|
+
if (diffMins < 60) return `${diffMins}m ago`;
|
|
1017
|
+
if (diffHours < 24) return `${diffHours}h ago`;
|
|
1018
|
+
if (diffDays < 7) return `${diffDays}d ago`;
|
|
1019
|
+
return date.toLocaleDateString(options == null ? void 0 : options.locale);
|
|
1020
|
+
}
|
|
1021
|
+
}),
|
|
1022
|
+
/**
|
|
1023
|
+
* User/Avatar column with name and optional subtitle
|
|
1024
|
+
*
|
|
1025
|
+
* @example
|
|
1026
|
+
* columns.user('assignee', 'Assigned To', { avatarKey: 'avatar', subtitleKey: 'email' })
|
|
1027
|
+
*/
|
|
1028
|
+
user: (key, label, options) => ({
|
|
1029
|
+
key,
|
|
1030
|
+
label,
|
|
1031
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
1032
|
+
render: (item) => ({
|
|
1033
|
+
content: item[key],
|
|
1034
|
+
type: "guest",
|
|
1035
|
+
avatar: (options == null ? void 0 : options.avatarKey) ? item[options.avatarKey] : void 0,
|
|
1036
|
+
subtitle: (options == null ? void 0 : options.subtitleKey) ? item[options.subtitleKey] : void 0
|
|
1037
|
+
})
|
|
1038
|
+
}),
|
|
1039
|
+
/**
|
|
1040
|
+
* Currency column with formatting
|
|
1041
|
+
*
|
|
1042
|
+
* @example
|
|
1043
|
+
* columns.currency('amount', 'Total', { currency: 'EUR' })
|
|
1044
|
+
* columns.currency('price', 'Price', { currency: 'USD', locale: 'en-US' })
|
|
1045
|
+
*/
|
|
1046
|
+
currency: (key, label, options) => ({
|
|
1047
|
+
key,
|
|
1048
|
+
label,
|
|
1049
|
+
type: "number",
|
|
1050
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
1051
|
+
render: (item) => {
|
|
1052
|
+
const value = item[key];
|
|
1053
|
+
if (value === null || value === void 0) return "";
|
|
1054
|
+
return new Intl.NumberFormat((options == null ? void 0 : options.locale) ?? "en-US", {
|
|
1055
|
+
style: "currency",
|
|
1056
|
+
currency: (options == null ? void 0 : options.currency) ?? "EUR"
|
|
1057
|
+
}).format(Number(value));
|
|
1058
|
+
}
|
|
1059
|
+
}),
|
|
1060
|
+
/**
|
|
1061
|
+
* Percentage column
|
|
1062
|
+
*
|
|
1063
|
+
* @example
|
|
1064
|
+
* columns.percentage('openRate', 'Open Rate')
|
|
1065
|
+
* columns.percentage('completion', 'Progress', { decimals: 0 })
|
|
1066
|
+
*/
|
|
1067
|
+
percentage: (key, label, options) => ({
|
|
1068
|
+
key,
|
|
1069
|
+
label,
|
|
1070
|
+
type: "number",
|
|
1071
|
+
sortable: (options == null ? void 0 : options.sortable) ?? true,
|
|
1072
|
+
render: (item) => {
|
|
1073
|
+
const value = item[key];
|
|
1074
|
+
if (value === null || value === void 0) return "";
|
|
1075
|
+
const numValue = (options == null ? void 0 : options.multiply) ? Number(value) * 100 : Number(value);
|
|
1076
|
+
return `${numValue.toFixed((options == null ? void 0 : options.decimals) ?? 1)}%`;
|
|
1077
|
+
}
|
|
1078
|
+
})
|
|
1079
|
+
};
|
|
1080
|
+
const statusColors = {
|
|
1081
|
+
active: "green",
|
|
1082
|
+
inactive: "gray",
|
|
1083
|
+
pending: "yellow",
|
|
1084
|
+
approved: "green",
|
|
1085
|
+
rejected: "red",
|
|
1086
|
+
draft: "gray",
|
|
1087
|
+
published: "green",
|
|
1088
|
+
archived: "gray",
|
|
1089
|
+
error: "red",
|
|
1090
|
+
success: "green",
|
|
1091
|
+
warning: "yellow",
|
|
1092
|
+
info: "blue"
|
|
1093
|
+
};
|
|
1094
|
+
function getStatusColor(status) {
|
|
1095
|
+
return statusColors[status == null ? void 0 : status.toLowerCase()] ?? "gray";
|
|
1096
|
+
}
|
|
1097
|
+
function createStatusColorFn(key) {
|
|
1098
|
+
return (item) => getStatusColor(String(item[key]));
|
|
1099
|
+
}
|
|
1100
|
+
const statusOptions = [
|
|
1101
|
+
{ label: "Active", value: "active" },
|
|
1102
|
+
{ label: "Inactive", value: "inactive" },
|
|
1103
|
+
{ label: "Pending", value: "pending" },
|
|
1104
|
+
{ label: "Archived", value: "archived" }
|
|
1105
|
+
];
|
|
1106
|
+
const booleanOptions = [
|
|
1107
|
+
{ label: "Yes", value: "true" },
|
|
1108
|
+
{ label: "No", value: "false" }
|
|
1109
|
+
];
|
|
1110
|
+
const filters = {
|
|
1111
|
+
/**
|
|
1112
|
+
* Text search filter
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* filters.text('name', 'Name')
|
|
1116
|
+
* filters.text('email', 'Email', 'Search by email address...')
|
|
1117
|
+
*/
|
|
1118
|
+
text: (key, label, placeholder) => ({
|
|
1119
|
+
key,
|
|
1120
|
+
label,
|
|
1121
|
+
type: "text",
|
|
1122
|
+
placeholder: placeholder ?? `Search by ${label.toLowerCase()}...`
|
|
1123
|
+
}),
|
|
1124
|
+
/**
|
|
1125
|
+
* Select dropdown filter
|
|
1126
|
+
*
|
|
1127
|
+
* @example
|
|
1128
|
+
* filters.select('role', 'Role', [
|
|
1129
|
+
* { label: 'Admin', value: 'admin' },
|
|
1130
|
+
* { label: 'User', value: 'user' },
|
|
1131
|
+
* ])
|
|
1132
|
+
*/
|
|
1133
|
+
select: (key, label, options) => ({
|
|
1134
|
+
key,
|
|
1135
|
+
label,
|
|
1136
|
+
type: "select",
|
|
1137
|
+
options
|
|
1138
|
+
}),
|
|
1139
|
+
/**
|
|
1140
|
+
* Status filter with common status options
|
|
1141
|
+
*
|
|
1142
|
+
* @example
|
|
1143
|
+
* filters.status()
|
|
1144
|
+
* filters.status('state', 'State')
|
|
1145
|
+
* filters.status('status', 'Status', [
|
|
1146
|
+
* { label: 'Active', value: 'active' },
|
|
1147
|
+
* { label: 'Draft', value: 'draft' },
|
|
1148
|
+
* ])
|
|
1149
|
+
*/
|
|
1150
|
+
status: (key = "status", label = "Status", options) => ({
|
|
1151
|
+
key,
|
|
1152
|
+
label,
|
|
1153
|
+
type: "select",
|
|
1154
|
+
options: options ?? statusOptions
|
|
1155
|
+
}),
|
|
1156
|
+
/**
|
|
1157
|
+
* Boolean (Yes/No) filter
|
|
1158
|
+
*
|
|
1159
|
+
* @example
|
|
1160
|
+
* filters.boolean('verified', 'Verified')
|
|
1161
|
+
* filters.boolean('active', 'Active', 'Enabled', 'Disabled')
|
|
1162
|
+
*/
|
|
1163
|
+
boolean: (key, label, trueLabel = "Yes", falseLabel = "No") => ({
|
|
1164
|
+
key,
|
|
1165
|
+
label,
|
|
1166
|
+
type: "select",
|
|
1167
|
+
options: [
|
|
1168
|
+
{ label: trueLabel, value: "true" },
|
|
1169
|
+
{ label: falseLabel, value: "false" }
|
|
1170
|
+
]
|
|
1171
|
+
}),
|
|
1172
|
+
/**
|
|
1173
|
+
* Number filter
|
|
1174
|
+
*
|
|
1175
|
+
* @example
|
|
1176
|
+
* filters.number('age', 'Age')
|
|
1177
|
+
* filters.number('amount', 'Amount', 'Enter amount...')
|
|
1178
|
+
*/
|
|
1179
|
+
number: (key, label, placeholder) => ({
|
|
1180
|
+
key,
|
|
1181
|
+
label,
|
|
1182
|
+
type: "number",
|
|
1183
|
+
placeholder: placeholder ?? `Enter ${label.toLowerCase()}...`
|
|
1184
|
+
}),
|
|
1185
|
+
/**
|
|
1186
|
+
* Date filter
|
|
1187
|
+
*
|
|
1188
|
+
* @example
|
|
1189
|
+
* filters.date('createdAt', 'Created Date')
|
|
1190
|
+
*/
|
|
1191
|
+
date: (key, label) => ({
|
|
1192
|
+
key,
|
|
1193
|
+
label,
|
|
1194
|
+
type: "date"
|
|
1195
|
+
}),
|
|
1196
|
+
/**
|
|
1197
|
+
* Date range filter
|
|
1198
|
+
*
|
|
1199
|
+
* @example
|
|
1200
|
+
* filters.dateRange('createdAt', 'Created')
|
|
1201
|
+
*/
|
|
1202
|
+
dateRange: (key, label) => ({
|
|
1203
|
+
key,
|
|
1204
|
+
label,
|
|
1205
|
+
type: "dateRange"
|
|
1206
|
+
}),
|
|
1207
|
+
/**
|
|
1208
|
+
* Role filter with common role options
|
|
1209
|
+
*
|
|
1210
|
+
* @example
|
|
1211
|
+
* filters.role()
|
|
1212
|
+
* filters.role('userRole', 'User Role')
|
|
1213
|
+
*/
|
|
1214
|
+
role: (key = "role", label = "Role", options) => ({
|
|
1215
|
+
key,
|
|
1216
|
+
label,
|
|
1217
|
+
type: "select",
|
|
1218
|
+
options: options ?? [
|
|
1219
|
+
{ label: "Admin", value: "admin" },
|
|
1220
|
+
{ label: "Manager", value: "manager" },
|
|
1221
|
+
{ label: "User", value: "user" },
|
|
1222
|
+
{ label: "Guest", value: "guest" }
|
|
1223
|
+
]
|
|
1224
|
+
}),
|
|
1225
|
+
/**
|
|
1226
|
+
* Type filter (generic entity type)
|
|
1227
|
+
*
|
|
1228
|
+
* @example
|
|
1229
|
+
* filters.type('campaignType', 'Type', [
|
|
1230
|
+
* { label: 'Email', value: 'email' },
|
|
1231
|
+
* { label: 'SMS', value: 'sms' },
|
|
1232
|
+
* ])
|
|
1233
|
+
*/
|
|
1234
|
+
type: (key, label, options) => ({
|
|
1235
|
+
key,
|
|
1236
|
+
label,
|
|
1237
|
+
type: "select",
|
|
1238
|
+
options
|
|
1239
|
+
}),
|
|
1240
|
+
/**
|
|
1241
|
+
* Priority filter
|
|
1242
|
+
*
|
|
1243
|
+
* @example
|
|
1244
|
+
* filters.priority()
|
|
1245
|
+
* filters.priority('urgency', 'Urgency')
|
|
1246
|
+
*/
|
|
1247
|
+
priority: (key = "priority", label = "Priority") => ({
|
|
1248
|
+
key,
|
|
1249
|
+
label,
|
|
1250
|
+
type: "select",
|
|
1251
|
+
options: [
|
|
1252
|
+
{ label: "Low", value: "low" },
|
|
1253
|
+
{ label: "Medium", value: "medium" },
|
|
1254
|
+
{ label: "High", value: "high" },
|
|
1255
|
+
{ label: "Critical", value: "critical" }
|
|
1256
|
+
]
|
|
1257
|
+
}),
|
|
1258
|
+
/**
|
|
1259
|
+
* Category filter from dynamic options
|
|
1260
|
+
*
|
|
1261
|
+
* @example
|
|
1262
|
+
* // From array of objects
|
|
1263
|
+
* filters.fromData('categoryId', 'Category', categories, 'name', 'id')
|
|
1264
|
+
*/
|
|
1265
|
+
fromData: (key, label, data, labelKey, valueKey) => ({
|
|
1266
|
+
key,
|
|
1267
|
+
label,
|
|
1268
|
+
type: "select",
|
|
1269
|
+
options: data.map((item) => ({
|
|
1270
|
+
label: String(item[labelKey]),
|
|
1271
|
+
value: item[valueKey]
|
|
1272
|
+
}))
|
|
1273
|
+
}),
|
|
1274
|
+
/**
|
|
1275
|
+
* Enum filter from TypeScript enum
|
|
1276
|
+
*
|
|
1277
|
+
* @example
|
|
1278
|
+
* enum Status { Active = 'active', Inactive = 'inactive' }
|
|
1279
|
+
* filters.fromEnum('status', 'Status', Status)
|
|
1280
|
+
*/
|
|
1281
|
+
fromEnum: (key, label, enumObj) => ({
|
|
1282
|
+
key,
|
|
1283
|
+
label,
|
|
1284
|
+
type: "select",
|
|
1285
|
+
options: Object.entries(enumObj).filter(([k]) => Number.isNaN(Number(k))).map(([enumKey, enumValue]) => ({
|
|
1286
|
+
label: enumKey.replace(/([A-Z])/g, " $1").trim(),
|
|
1287
|
+
// Convert camelCase to Title Case
|
|
1288
|
+
value: enumValue
|
|
1289
|
+
}))
|
|
1290
|
+
})
|
|
1291
|
+
};
|
|
1292
|
+
function createFilterGroup(config) {
|
|
1293
|
+
const result = [];
|
|
1294
|
+
if (config.search) {
|
|
1295
|
+
config.search.forEach((field) => {
|
|
1296
|
+
result.push(filters.text(field, field.charAt(0).toUpperCase() + field.slice(1)));
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
if (config.status) {
|
|
1300
|
+
if (typeof config.status === "boolean") {
|
|
1301
|
+
result.push(filters.status());
|
|
1302
|
+
} else {
|
|
1303
|
+
result.push(filters.status(config.status.key, config.status.label, config.status.options));
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
if (config.dateRange) {
|
|
1307
|
+
result.push(filters.dateRange(config.dateRange, "Date Range"));
|
|
1308
|
+
}
|
|
1309
|
+
if (config.custom) {
|
|
1310
|
+
result.push(...config.custom);
|
|
1311
|
+
}
|
|
1312
|
+
return result;
|
|
1313
|
+
}
|
|
1314
|
+
const filterPresets = {
|
|
1315
|
+
/**
|
|
1316
|
+
* Filters for user/account tables
|
|
1317
|
+
*/
|
|
1318
|
+
users: () => [
|
|
1319
|
+
filters.text("name", "Name"),
|
|
1320
|
+
filters.text("email", "Email"),
|
|
1321
|
+
filters.role(),
|
|
1322
|
+
filters.status()
|
|
1323
|
+
],
|
|
1324
|
+
/**
|
|
1325
|
+
* Filters for campaign tables
|
|
1326
|
+
*/
|
|
1327
|
+
campaigns: () => [
|
|
1328
|
+
filters.text("name", "Campaign Name"),
|
|
1329
|
+
filters.status("status", "Status", [
|
|
1330
|
+
{ label: "Active", value: "active" },
|
|
1331
|
+
{ label: "Draft", value: "draft" },
|
|
1332
|
+
{ label: "Completed", value: "completed" },
|
|
1333
|
+
{ label: "Archived", value: "archived" },
|
|
1334
|
+
{ label: "Failed", value: "failed" }
|
|
1335
|
+
]),
|
|
1336
|
+
filters.dateRange("createdAt", "Created Date")
|
|
1337
|
+
],
|
|
1338
|
+
/**
|
|
1339
|
+
* Filters for contact tables
|
|
1340
|
+
*/
|
|
1341
|
+
contacts: () => [
|
|
1342
|
+
filters.text("name", "Name"),
|
|
1343
|
+
filters.text("email", "Email"),
|
|
1344
|
+
filters.text("phone", "Phone"),
|
|
1345
|
+
filters.status()
|
|
1346
|
+
],
|
|
1347
|
+
/**
|
|
1348
|
+
* Filters for booking/reservation tables
|
|
1349
|
+
*/
|
|
1350
|
+
bookings: () => [
|
|
1351
|
+
filters.text("guestName", "Guest Name"),
|
|
1352
|
+
filters.text("confirmationNumber", "Confirmation #"),
|
|
1353
|
+
filters.status("status", "Status", [
|
|
1354
|
+
{ label: "Confirmed", value: "confirmed" },
|
|
1355
|
+
{ label: "Pending", value: "pending" },
|
|
1356
|
+
{ label: "Cancelled", value: "cancelled" },
|
|
1357
|
+
{ label: "Completed", value: "completed" }
|
|
1358
|
+
]),
|
|
1359
|
+
filters.dateRange("checkIn", "Check-in Date")
|
|
1360
|
+
],
|
|
1361
|
+
/**
|
|
1362
|
+
* Filters for audit/log tables
|
|
1363
|
+
*/
|
|
1364
|
+
auditLogs: () => [
|
|
1365
|
+
filters.text("action", "Action"),
|
|
1366
|
+
filters.text("user", "User"),
|
|
1367
|
+
filters.dateRange("timestamp", "Date")
|
|
1368
|
+
]
|
|
1369
|
+
};
|
|
1370
|
+
export {
|
|
1371
|
+
Table as T,
|
|
1372
|
+
_sfc_main$3 as _,
|
|
1373
|
+
_sfc_main$2 as a,
|
|
1374
|
+
_sfc_main$1 as b,
|
|
1375
|
+
_sfc_main as c,
|
|
1376
|
+
columns as d,
|
|
1377
|
+
createStatusColorFn as e,
|
|
1378
|
+
filters as f,
|
|
1379
|
+
getStatusColor as g,
|
|
1380
|
+
filterPresets as h,
|
|
1381
|
+
createFilterGroup as i,
|
|
1382
|
+
statusOptions as j,
|
|
1383
|
+
booleanOptions as k,
|
|
1384
|
+
statusColors as s
|
|
1385
|
+
};
|
|
1386
|
+
//# sourceMappingURL=filterHelpers-DgRyoYSa.js.map
|