@dragonmastery/zinia-forms-core 0.3.15 → 0.3.17
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/dist/index.d.ts +11 -2
- package/dist/index.js +502 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1170,6 +1170,14 @@ interface DeleteModalProps<FormType = any> {
|
|
|
1170
1170
|
interface DataTableProps<FormType> {
|
|
1171
1171
|
class?: string;
|
|
1172
1172
|
name?: string;
|
|
1173
|
+
/**
|
|
1174
|
+
* Height behavior for the table container
|
|
1175
|
+
* - 'auto' (default): Table expands to fill available space with a minimum height to prevent squishing
|
|
1176
|
+
* - 'fixed': Uses fixed height (850px, max 90vh) - original behavior
|
|
1177
|
+
* - number: Fixed pixel height (e.g., 600)
|
|
1178
|
+
* - string: Custom CSS height value (e.g., '50vh', '600px')
|
|
1179
|
+
*/
|
|
1180
|
+
height?: 'auto' | 'fixed' | number | string;
|
|
1173
1181
|
}
|
|
1174
1182
|
|
|
1175
1183
|
/**
|
|
@@ -1508,7 +1516,7 @@ declare function useForm<T extends z.ZodObject<any>, CalcType = (values: z.infer
|
|
|
1508
1516
|
timestamp: number;
|
|
1509
1517
|
timeoutId?: number;
|
|
1510
1518
|
}[]>;
|
|
1511
|
-
fieldsMetadata: Record<string, FieldMetadata>;
|
|
1519
|
+
readonly fieldsMetadata: Record<string, FieldMetadata>;
|
|
1512
1520
|
validate: (options?: {
|
|
1513
1521
|
markErrorsAsTouched: boolean;
|
|
1514
1522
|
}) => boolean;
|
|
@@ -2048,9 +2056,10 @@ interface ColumnDefinition<TData, TField extends keyof TData> {
|
|
|
2048
2056
|
textWrap?: 'truncate' | 'wrap';
|
|
2049
2057
|
format?: (value: TData[TField], row: TData) => string;
|
|
2050
2058
|
render?: (value: TData[TField], row: TData) => any;
|
|
2051
|
-
filterType?: 'text' | 'select' | 'number' | 'boolean';
|
|
2059
|
+
filterType?: 'text' | 'select' | 'number' | 'boolean' | 'combobox';
|
|
2052
2060
|
filterOptions?: FilterOptionItem[];
|
|
2053
2061
|
filterOptionsLoader?: () => Promise<FilterOptionItem[]>;
|
|
2062
|
+
filterAllowCreate?: boolean;
|
|
2054
2063
|
sortLabels?: {
|
|
2055
2064
|
asc: string;
|
|
2056
2065
|
desc: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { watch, provide, ref, computed, unref, inject, getCurrentInstance,
|
|
1
|
+
import { reactive, watch, provide, ref, computed, unref, inject, getCurrentInstance, nextTick, Teleport } from 'vue';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'vue/jsx-runtime';
|
|
4
4
|
|
|
@@ -651,6 +651,12 @@ var SchemaCache = class {
|
|
|
651
651
|
if (debug) {
|
|
652
652
|
console.log(`[SchemaCache] More segments remaining, continuing to next segment`);
|
|
653
653
|
}
|
|
654
|
+
if (!(currentSchema instanceof z.ZodObject)) {
|
|
655
|
+
if (debug) {
|
|
656
|
+
console.log(`[SchemaCache] ERROR: Element schema is not a ZodObject after unwrap, cannot access nested fields`);
|
|
657
|
+
}
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
654
660
|
continue;
|
|
655
661
|
}
|
|
656
662
|
if (debug) {
|
|
@@ -1058,6 +1064,11 @@ function extractFieldMetadata(schema, path = "", parentSchema, schemaId) {
|
|
|
1058
1064
|
metadata.isArray = true;
|
|
1059
1065
|
if (schema._def.minLength) {
|
|
1060
1066
|
metadata.min = schema._def.minLength.value;
|
|
1067
|
+
if (schema._def.minLength.value > 0) ; else {
|
|
1068
|
+
metadata.isRequired = false;
|
|
1069
|
+
}
|
|
1070
|
+
} else {
|
|
1071
|
+
metadata.isRequired = false;
|
|
1061
1072
|
}
|
|
1062
1073
|
if (schema._def.maxLength) {
|
|
1063
1074
|
metadata.max = schema._def.maxLength.value;
|
|
@@ -1174,9 +1185,7 @@ function extractFieldMetadata(schema, path = "", parentSchema, schemaId) {
|
|
|
1174
1185
|
} else if (customMetadata.options) {
|
|
1175
1186
|
metadata.options = customMetadata.options;
|
|
1176
1187
|
} else {
|
|
1177
|
-
metadata.options = [
|
|
1178
|
-
{ value: "", label: "Select an option" }
|
|
1179
|
-
];
|
|
1188
|
+
metadata.options = [{ value: "", label: "Select an option" }];
|
|
1180
1189
|
}
|
|
1181
1190
|
}
|
|
1182
1191
|
}
|
|
@@ -1815,6 +1824,83 @@ function useFormValidation(schema, formState, options) {
|
|
|
1815
1824
|
validateField: validateField2
|
|
1816
1825
|
};
|
|
1817
1826
|
}
|
|
1827
|
+
|
|
1828
|
+
// src/metadata/resolveMetadataPath.ts
|
|
1829
|
+
function resolveMetadataPath(fieldsMetadata, path) {
|
|
1830
|
+
if (path in fieldsMetadata) {
|
|
1831
|
+
return fieldsMetadata[path];
|
|
1832
|
+
}
|
|
1833
|
+
return resolveMetadataPathRecursive(fieldsMetadata, path.split("."), 0);
|
|
1834
|
+
}
|
|
1835
|
+
function resolveMetadataPathRecursive(fieldsMetadata, segments, startIndex, currentMetadata) {
|
|
1836
|
+
if (startIndex >= segments.length) {
|
|
1837
|
+
return void 0;
|
|
1838
|
+
}
|
|
1839
|
+
if (currentMetadata) {
|
|
1840
|
+
const segment = segments[startIndex];
|
|
1841
|
+
if (!isNaN(Number(segment))) {
|
|
1842
|
+
if (currentMetadata.arrayOf) {
|
|
1843
|
+
return resolveMetadataPathRecursive(fieldsMetadata, segments, startIndex + 1, currentMetadata.arrayOf);
|
|
1844
|
+
}
|
|
1845
|
+
return void 0;
|
|
1846
|
+
} else {
|
|
1847
|
+
if (currentMetadata.children) {
|
|
1848
|
+
const childMetadata = currentMetadata.children[segment];
|
|
1849
|
+
if (childMetadata) {
|
|
1850
|
+
if (startIndex + 1 < segments.length) {
|
|
1851
|
+
return resolveMetadataPathRecursive(fieldsMetadata, segments, startIndex + 1, childMetadata);
|
|
1852
|
+
}
|
|
1853
|
+
return {
|
|
1854
|
+
...childMetadata,
|
|
1855
|
+
path: segments.join(".")
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
return void 0;
|
|
1860
|
+
}
|
|
1861
|
+
} else {
|
|
1862
|
+
const segment = segments[startIndex];
|
|
1863
|
+
const rootMetadata = fieldsMetadata[segment];
|
|
1864
|
+
if (!rootMetadata) {
|
|
1865
|
+
return void 0;
|
|
1866
|
+
}
|
|
1867
|
+
if (startIndex + 1 < segments.length) {
|
|
1868
|
+
return resolveMetadataPathRecursive(fieldsMetadata, segments, startIndex + 1, rootMetadata);
|
|
1869
|
+
}
|
|
1870
|
+
return {
|
|
1871
|
+
...rootMetadata,
|
|
1872
|
+
path: segments.join(".")
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
function createMetadataProxy(fieldsMetadata) {
|
|
1877
|
+
return new Proxy(fieldsMetadata, {
|
|
1878
|
+
get(target, prop) {
|
|
1879
|
+
if (typeof prop !== "string") {
|
|
1880
|
+
return Reflect.get(target, prop);
|
|
1881
|
+
}
|
|
1882
|
+
return resolveMetadataPath(fieldsMetadata, prop);
|
|
1883
|
+
},
|
|
1884
|
+
has(target, prop) {
|
|
1885
|
+
if (typeof prop !== "string") {
|
|
1886
|
+
return prop in target;
|
|
1887
|
+
}
|
|
1888
|
+
if (prop in target) {
|
|
1889
|
+
return true;
|
|
1890
|
+
}
|
|
1891
|
+
return resolveMetadataPath(fieldsMetadata, prop) !== void 0;
|
|
1892
|
+
},
|
|
1893
|
+
ownKeys(target) {
|
|
1894
|
+
return Reflect.ownKeys(target);
|
|
1895
|
+
},
|
|
1896
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
1897
|
+
if (prop in target) {
|
|
1898
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
1899
|
+
}
|
|
1900
|
+
return void 0;
|
|
1901
|
+
}
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1818
1904
|
function setupLocalStoragePersistence(formData, options) {
|
|
1819
1905
|
const { storeName, enabled = true, initialValues = {}, debug = false } = options;
|
|
1820
1906
|
const logger = Logger.getLogger("LocalStoragePersistence");
|
|
@@ -2059,7 +2145,11 @@ function useForm(schema, options) {
|
|
|
2059
2145
|
get pendingOperations() {
|
|
2060
2146
|
return formState.state.pendingOperations;
|
|
2061
2147
|
},
|
|
2062
|
-
fieldsMetadata
|
|
2148
|
+
// Create a Proxy for fieldsMetadata that automatically resolves nested array paths
|
|
2149
|
+
// This allows fieldsMetadata[path] to work for nested array paths like "items.0.fieldName"
|
|
2150
|
+
get fieldsMetadata() {
|
|
2151
|
+
return createMetadataProxy(fieldsMetadata);
|
|
2152
|
+
},
|
|
2063
2153
|
// Form methods
|
|
2064
2154
|
validate: validation.validate,
|
|
2065
2155
|
validateField: validation.validateField,
|
|
@@ -5261,7 +5351,7 @@ function createDaisyUIComboboxField() {
|
|
|
5261
5351
|
class: inputClass,
|
|
5262
5352
|
placeholder: isBeingPopulated.value ? "Loading..." : isLoadingOptions.value ? "Loading options..." : parentFieldName.value && !parentValue.value ? "Select parent field first" : props.placeholder || "Search or type new value",
|
|
5263
5353
|
disabled: isDisabled.value,
|
|
5264
|
-
autocomplete: "
|
|
5354
|
+
autocomplete: "nope",
|
|
5265
5355
|
"data-testid": `${formState.storeName}-combobox-field-${String(props.name)}`,
|
|
5266
5356
|
...inputProps
|
|
5267
5357
|
}
|
|
@@ -7749,6 +7839,8 @@ function getFilterType(field, column, fieldsMetadata) {
|
|
|
7749
7839
|
return "number";
|
|
7750
7840
|
case "checkbox":
|
|
7751
7841
|
return "boolean";
|
|
7842
|
+
case "combobox":
|
|
7843
|
+
return "combobox";
|
|
7752
7844
|
case "select":
|
|
7753
7845
|
case "radio":
|
|
7754
7846
|
return column.filterOptions || fieldMetadata?.options ? "select" : "text";
|
|
@@ -8242,6 +8334,366 @@ var BooleanFilter = (props) => {
|
|
|
8242
8334
|
}
|
|
8243
8335
|
);
|
|
8244
8336
|
};
|
|
8337
|
+
var comboboxState = reactive({});
|
|
8338
|
+
var ComboboxFilter = (props) => {
|
|
8339
|
+
if (!comboboxState[props.field]) {
|
|
8340
|
+
comboboxState[props.field] = {
|
|
8341
|
+
isOpen: false,
|
|
8342
|
+
selectedIndex: -1
|
|
8343
|
+
};
|
|
8344
|
+
}
|
|
8345
|
+
const state = comboboxState[props.field];
|
|
8346
|
+
const searchQuery = computed(() => props.filterInputValues.value[props.field] || "");
|
|
8347
|
+
const selectedOption = computed(() => {
|
|
8348
|
+
if (!props.value) return "";
|
|
8349
|
+
return props.options.find((opt) => opt.value === props.value)?.label || String(props.value);
|
|
8350
|
+
});
|
|
8351
|
+
if (!(props.field in props.filterInputValues.value) && props.value) {
|
|
8352
|
+
const label = selectedOption.value;
|
|
8353
|
+
if (label) {
|
|
8354
|
+
props.filterInputValues.value[props.field] = label;
|
|
8355
|
+
}
|
|
8356
|
+
}
|
|
8357
|
+
const filteredOptions = computed(() => {
|
|
8358
|
+
const query = searchQuery.value.trim().toLowerCase();
|
|
8359
|
+
if (!query) {
|
|
8360
|
+
return props.options;
|
|
8361
|
+
}
|
|
8362
|
+
return props.options.filter((opt) => opt.label.toLowerCase().includes(query));
|
|
8363
|
+
});
|
|
8364
|
+
const isNewValue = computed(() => {
|
|
8365
|
+
if (!props.allowCreate || !searchQuery.value.trim()) return false;
|
|
8366
|
+
const query = searchQuery.value.trim();
|
|
8367
|
+
return !props.options.some((opt) => opt.label.toLowerCase() === query.toLowerCase());
|
|
8368
|
+
});
|
|
8369
|
+
const isInvalidValue = computed(() => {
|
|
8370
|
+
if (!searchQuery.value.trim()) return false;
|
|
8371
|
+
if (props.allowCreate) return false;
|
|
8372
|
+
const query = searchQuery.value.trim();
|
|
8373
|
+
return !props.options.some((opt) => opt.label.toLowerCase() === query.toLowerCase());
|
|
8374
|
+
});
|
|
8375
|
+
const handleInput = (e) => {
|
|
8376
|
+
const value = e.target.value;
|
|
8377
|
+
props.filterInputValues.value[props.field] = value;
|
|
8378
|
+
state.isOpen = true;
|
|
8379
|
+
state.selectedIndex = -1;
|
|
8380
|
+
const exactMatch = props.options.find((opt) => opt.label.toLowerCase() === value.toLowerCase().trim());
|
|
8381
|
+
if (exactMatch) {
|
|
8382
|
+
props.onFilterChange(props.field, exactMatch.value, "eq");
|
|
8383
|
+
}
|
|
8384
|
+
};
|
|
8385
|
+
const handleSelectOption = (option) => {
|
|
8386
|
+
props.filterInputValues.value[props.field] = option.label;
|
|
8387
|
+
props.onFilterChange(props.field, option.value, "eq");
|
|
8388
|
+
state.isOpen = false;
|
|
8389
|
+
state.selectedIndex = -1;
|
|
8390
|
+
};
|
|
8391
|
+
const handleSelectNewValue = () => {
|
|
8392
|
+
const newValue = searchQuery.value.trim();
|
|
8393
|
+
if (newValue) {
|
|
8394
|
+
props.onFilterChange(props.field, newValue, "eq");
|
|
8395
|
+
state.isOpen = false;
|
|
8396
|
+
state.selectedIndex = -1;
|
|
8397
|
+
}
|
|
8398
|
+
};
|
|
8399
|
+
const handleKeyDown = (e) => {
|
|
8400
|
+
if (e.key === "Escape") {
|
|
8401
|
+
e.preventDefault();
|
|
8402
|
+
e.stopPropagation();
|
|
8403
|
+
state.isOpen = false;
|
|
8404
|
+
state.selectedIndex = -1;
|
|
8405
|
+
if (props.value) {
|
|
8406
|
+
props.filterInputValues.value[props.field] = selectedOption.value;
|
|
8407
|
+
} else {
|
|
8408
|
+
props.filterInputValues.value[props.field] = "";
|
|
8409
|
+
}
|
|
8410
|
+
return;
|
|
8411
|
+
}
|
|
8412
|
+
if (e.key === "Enter") {
|
|
8413
|
+
e.preventDefault();
|
|
8414
|
+
e.stopPropagation();
|
|
8415
|
+
if (state.selectedIndex >= 0 && state.selectedIndex < filteredOptions.value.length) {
|
|
8416
|
+
handleSelectOption(filteredOptions.value[state.selectedIndex]);
|
|
8417
|
+
return;
|
|
8418
|
+
}
|
|
8419
|
+
if (state.selectedIndex === filteredOptions.value.length && isNewValue.value && props.allowCreate) {
|
|
8420
|
+
handleSelectNewValue();
|
|
8421
|
+
return;
|
|
8422
|
+
}
|
|
8423
|
+
if (searchQuery.value.trim() === "") {
|
|
8424
|
+
state.isOpen = false;
|
|
8425
|
+
state.selectedIndex = -1;
|
|
8426
|
+
if (props.value) {
|
|
8427
|
+
props.onFilterChange(props.field, "", "eq");
|
|
8428
|
+
props.filterInputValues.value[props.field] = "";
|
|
8429
|
+
}
|
|
8430
|
+
return;
|
|
8431
|
+
}
|
|
8432
|
+
const currentLabel = selectedOption.value;
|
|
8433
|
+
const queryMatchesCurrentValue = currentLabel && searchQuery.value.trim().toLowerCase() === currentLabel.toLowerCase();
|
|
8434
|
+
if (queryMatchesCurrentValue) {
|
|
8435
|
+
state.isOpen = false;
|
|
8436
|
+
state.selectedIndex = -1;
|
|
8437
|
+
return;
|
|
8438
|
+
}
|
|
8439
|
+
if (isInvalidValue.value) {
|
|
8440
|
+
state.isOpen = false;
|
|
8441
|
+
state.selectedIndex = -1;
|
|
8442
|
+
const currentLabel2 = selectedOption.value;
|
|
8443
|
+
if (currentLabel2) {
|
|
8444
|
+
props.filterInputValues.value[props.field] = currentLabel2;
|
|
8445
|
+
} else {
|
|
8446
|
+
props.filterInputValues.value[props.field] = "";
|
|
8447
|
+
}
|
|
8448
|
+
return;
|
|
8449
|
+
}
|
|
8450
|
+
if (isNewValue.value && state.selectedIndex < 0 && props.allowCreate) {
|
|
8451
|
+
handleSelectNewValue();
|
|
8452
|
+
return;
|
|
8453
|
+
}
|
|
8454
|
+
const matchingOption = props.options.find(
|
|
8455
|
+
(opt) => opt.label.toLowerCase() === searchQuery.value.trim().toLowerCase()
|
|
8456
|
+
);
|
|
8457
|
+
if (matchingOption) {
|
|
8458
|
+
handleSelectOption(matchingOption);
|
|
8459
|
+
return;
|
|
8460
|
+
}
|
|
8461
|
+
state.isOpen = false;
|
|
8462
|
+
state.selectedIndex = -1;
|
|
8463
|
+
return;
|
|
8464
|
+
}
|
|
8465
|
+
if (e.key === "ArrowDown") {
|
|
8466
|
+
e.preventDefault();
|
|
8467
|
+
e.stopPropagation();
|
|
8468
|
+
state.isOpen = true;
|
|
8469
|
+
const totalOptions = filteredOptions.value.length + (isNewValue.value && props.allowCreate ? 1 : 0);
|
|
8470
|
+
if (totalOptions > 0) {
|
|
8471
|
+
const currentIndex = state.selectedIndex;
|
|
8472
|
+
const newIndex = currentIndex < 0 ? 0 : (currentIndex + 1) % totalOptions;
|
|
8473
|
+
state.selectedIndex = newIndex;
|
|
8474
|
+
nextTick(() => {
|
|
8475
|
+
scrollToSelectedOption(newIndex);
|
|
8476
|
+
});
|
|
8477
|
+
}
|
|
8478
|
+
return;
|
|
8479
|
+
}
|
|
8480
|
+
if (e.key === "ArrowUp") {
|
|
8481
|
+
e.preventDefault();
|
|
8482
|
+
e.stopPropagation();
|
|
8483
|
+
state.isOpen = true;
|
|
8484
|
+
const totalOptions = filteredOptions.value.length + (isNewValue.value && props.allowCreate ? 1 : 0);
|
|
8485
|
+
if (totalOptions > 0) {
|
|
8486
|
+
const currentIndex = state.selectedIndex;
|
|
8487
|
+
const newIndex = currentIndex < 0 ? totalOptions - 1 : (currentIndex - 1 + totalOptions) % totalOptions;
|
|
8488
|
+
state.selectedIndex = newIndex;
|
|
8489
|
+
nextTick(() => {
|
|
8490
|
+
scrollToSelectedOption(newIndex);
|
|
8491
|
+
});
|
|
8492
|
+
}
|
|
8493
|
+
return;
|
|
8494
|
+
}
|
|
8495
|
+
};
|
|
8496
|
+
const handleFocus = () => {
|
|
8497
|
+
state.isOpen = true;
|
|
8498
|
+
};
|
|
8499
|
+
const scrollToSelectedOption = (index) => {
|
|
8500
|
+
const container = document.querySelector(`[data-combobox-dropdown="${props.field}"]`);
|
|
8501
|
+
if (!container) return;
|
|
8502
|
+
const optionId = index === filteredOptions.value.length ? "option-new" : `option-${index}`;
|
|
8503
|
+
const selectedElement = container.querySelector(`#${optionId}`);
|
|
8504
|
+
if (!selectedElement) return;
|
|
8505
|
+
const elementTop = selectedElement.offsetTop;
|
|
8506
|
+
const elementHeight = selectedElement.offsetHeight;
|
|
8507
|
+
const containerHeight = container.clientHeight;
|
|
8508
|
+
const containerScrollTop = container.scrollTop;
|
|
8509
|
+
if (elementTop < containerScrollTop) {
|
|
8510
|
+
container.scrollTop = elementTop;
|
|
8511
|
+
} else if (elementTop + elementHeight > containerScrollTop + containerHeight) {
|
|
8512
|
+
container.scrollTop = elementTop + elementHeight - containerHeight;
|
|
8513
|
+
}
|
|
8514
|
+
};
|
|
8515
|
+
const handleBlur = (e) => {
|
|
8516
|
+
const relatedTarget = e.relatedTarget || document.activeElement;
|
|
8517
|
+
const container = document.querySelector(`[data-combobox-container="${props.field}"]`);
|
|
8518
|
+
if (container && container.contains(relatedTarget)) {
|
|
8519
|
+
return;
|
|
8520
|
+
}
|
|
8521
|
+
state.isOpen = false;
|
|
8522
|
+
const currentQuery = searchQuery.value.trim();
|
|
8523
|
+
const currentValue = props.value;
|
|
8524
|
+
const currentLabel = selectedOption.value;
|
|
8525
|
+
if (currentQuery === "") {
|
|
8526
|
+
if (currentValue) {
|
|
8527
|
+
props.onFilterChange(props.field, "", "eq");
|
|
8528
|
+
props.filterInputValues.value[props.field] = "";
|
|
8529
|
+
}
|
|
8530
|
+
} else {
|
|
8531
|
+
const queryMatchesCurrentValue = currentLabel && currentQuery.toLowerCase() === currentLabel.toLowerCase();
|
|
8532
|
+
if (isInvalidValue.value) {
|
|
8533
|
+
if (currentLabel) {
|
|
8534
|
+
props.filterInputValues.value[props.field] = currentLabel;
|
|
8535
|
+
} else {
|
|
8536
|
+
props.filterInputValues.value[props.field] = "";
|
|
8537
|
+
}
|
|
8538
|
+
return;
|
|
8539
|
+
}
|
|
8540
|
+
if (!queryMatchesCurrentValue) {
|
|
8541
|
+
const matchingOption = props.options.find((opt) => opt.label.toLowerCase() === currentQuery.toLowerCase());
|
|
8542
|
+
if (matchingOption) {
|
|
8543
|
+
props.onFilterChange(props.field, matchingOption.value, "eq");
|
|
8544
|
+
} else if (props.allowCreate) {
|
|
8545
|
+
props.onFilterChange(props.field, currentQuery, "eq");
|
|
8546
|
+
} else {
|
|
8547
|
+
if (currentLabel) {
|
|
8548
|
+
props.filterInputValues.value[props.field] = currentLabel;
|
|
8549
|
+
}
|
|
8550
|
+
}
|
|
8551
|
+
} else {
|
|
8552
|
+
if (currentLabel && currentQuery !== currentLabel) {
|
|
8553
|
+
props.filterInputValues.value[props.field] = currentLabel;
|
|
8554
|
+
}
|
|
8555
|
+
}
|
|
8556
|
+
}
|
|
8557
|
+
};
|
|
8558
|
+
return /* @__PURE__ */ jsxs("div", { class: "relative w-full", "data-combobox-container": props.field, children: [
|
|
8559
|
+
/* @__PURE__ */ jsx(
|
|
8560
|
+
"input",
|
|
8561
|
+
{
|
|
8562
|
+
type: "text",
|
|
8563
|
+
value: searchQuery.value,
|
|
8564
|
+
onInput: handleInput,
|
|
8565
|
+
onKeydown: handleKeyDown,
|
|
8566
|
+
onFocus: handleFocus,
|
|
8567
|
+
onBlur: handleBlur,
|
|
8568
|
+
placeholder: props.isOptionsLoading ? "Loading options..." : `Search ${props.label}`,
|
|
8569
|
+
class: "input input-bordered input-sm w-full",
|
|
8570
|
+
disabled: props.isLoading || props.isOptionsLoading,
|
|
8571
|
+
"data-testid": `datatable-filter-${props.field}-input`
|
|
8572
|
+
}
|
|
8573
|
+
),
|
|
8574
|
+
/* @__PURE__ */ jsx("div", { class: "absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none", children: /* @__PURE__ */ jsx(
|
|
8575
|
+
"svg",
|
|
8576
|
+
{
|
|
8577
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
8578
|
+
class: "h-4 w-4 text-base-content/50",
|
|
8579
|
+
fill: "none",
|
|
8580
|
+
viewBox: "0 0 24 24",
|
|
8581
|
+
stroke: "currentColor",
|
|
8582
|
+
"stroke-width": "2",
|
|
8583
|
+
children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M8 9l4-4 4 4m0 6l-4 4-4-4" })
|
|
8584
|
+
}
|
|
8585
|
+
) }),
|
|
8586
|
+
state.isOpen && /* @__PURE__ */ jsx(
|
|
8587
|
+
"div",
|
|
8588
|
+
{
|
|
8589
|
+
"data-combobox-dropdown": props.field,
|
|
8590
|
+
class: "absolute z-50 mt-1 bg-base-100 border border-base-300 rounded-box shadow-lg max-h-60 overflow-auto w-full",
|
|
8591
|
+
children: /* @__PURE__ */ jsx("ul", { class: "menu w-full", role: "listbox", id: `combobox-listbox-${props.field}`, children: props.isOptionsLoading ? /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70 p-2", children: "Loading options..." }) }) : filteredOptions.value.length === 0 && !isNewValue.value && !isInvalidValue.value ? /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70 p-2", children: "No options available" }) }) : isInvalidValue.value ? /* @__PURE__ */ jsx("li", { class: "bg-error/10 border-l-4 border-error", children: /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
|
|
8592
|
+
/* @__PURE__ */ jsx(
|
|
8593
|
+
"svg",
|
|
8594
|
+
{
|
|
8595
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
8596
|
+
class: "h-4 w-4 text-error flex-shrink-0",
|
|
8597
|
+
fill: "none",
|
|
8598
|
+
viewBox: "0 0 24 24",
|
|
8599
|
+
stroke: "currentColor",
|
|
8600
|
+
"stroke-width": "2",
|
|
8601
|
+
children: /* @__PURE__ */ jsx(
|
|
8602
|
+
"path",
|
|
8603
|
+
{
|
|
8604
|
+
"stroke-linecap": "round",
|
|
8605
|
+
"stroke-linejoin": "round",
|
|
8606
|
+
d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
8607
|
+
}
|
|
8608
|
+
)
|
|
8609
|
+
}
|
|
8610
|
+
),
|
|
8611
|
+
/* @__PURE__ */ jsxs("div", { class: "text-sm", children: [
|
|
8612
|
+
/* @__PURE__ */ jsx("p", { class: "font-medium text-error", children: "Invalid value" }),
|
|
8613
|
+
/* @__PURE__ */ jsxs("p", { class: "text-error/80", children: [
|
|
8614
|
+
'"',
|
|
8615
|
+
searchQuery.value,
|
|
8616
|
+
'" is not a valid option. Please select from the list.'
|
|
8617
|
+
] })
|
|
8618
|
+
] })
|
|
8619
|
+
] }) }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8620
|
+
filteredOptions.value.map((option, index) => /* @__PURE__ */ jsx(
|
|
8621
|
+
"li",
|
|
8622
|
+
{
|
|
8623
|
+
id: `option-${index}`,
|
|
8624
|
+
role: "option",
|
|
8625
|
+
"aria-selected": index === state.selectedIndex,
|
|
8626
|
+
class: index === state.selectedIndex ? "bg-base-200" : "",
|
|
8627
|
+
children: /* @__PURE__ */ jsx(
|
|
8628
|
+
"a",
|
|
8629
|
+
{
|
|
8630
|
+
href: "#",
|
|
8631
|
+
tabindex: 0,
|
|
8632
|
+
onClick: (e) => {
|
|
8633
|
+
e.preventDefault();
|
|
8634
|
+
e.stopPropagation();
|
|
8635
|
+
handleSelectOption(option);
|
|
8636
|
+
},
|
|
8637
|
+
onMousedown: (e) => {
|
|
8638
|
+
e.preventDefault();
|
|
8639
|
+
},
|
|
8640
|
+
class: "w-full",
|
|
8641
|
+
children: option.label
|
|
8642
|
+
}
|
|
8643
|
+
)
|
|
8644
|
+
},
|
|
8645
|
+
option.value
|
|
8646
|
+
)),
|
|
8647
|
+
isNewValue.value && props.allowCreate && /* @__PURE__ */ jsx(
|
|
8648
|
+
"li",
|
|
8649
|
+
{
|
|
8650
|
+
id: "option-new",
|
|
8651
|
+
role: "option",
|
|
8652
|
+
"aria-selected": state.selectedIndex === filteredOptions.value.length,
|
|
8653
|
+
class: state.selectedIndex === filteredOptions.value.length ? "bg-base-200" : "",
|
|
8654
|
+
children: /* @__PURE__ */ jsx(
|
|
8655
|
+
"a",
|
|
8656
|
+
{
|
|
8657
|
+
href: "#",
|
|
8658
|
+
tabindex: 0,
|
|
8659
|
+
onClick: (e) => {
|
|
8660
|
+
e.preventDefault();
|
|
8661
|
+
e.stopPropagation();
|
|
8662
|
+
handleSelectNewValue();
|
|
8663
|
+
},
|
|
8664
|
+
onMousedown: (e) => {
|
|
8665
|
+
e.preventDefault();
|
|
8666
|
+
},
|
|
8667
|
+
class: "w-full",
|
|
8668
|
+
children: /* @__PURE__ */ jsxs("div", { class: "flex items-center gap-2", children: [
|
|
8669
|
+
/* @__PURE__ */ jsx(
|
|
8670
|
+
"svg",
|
|
8671
|
+
{
|
|
8672
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
8673
|
+
class: "h-4 w-4 text-success",
|
|
8674
|
+
fill: "none",
|
|
8675
|
+
viewBox: "0 0 24 24",
|
|
8676
|
+
stroke: "currentColor",
|
|
8677
|
+
"stroke-width": "2",
|
|
8678
|
+
children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M12 4v16m8-8H4" })
|
|
8679
|
+
}
|
|
8680
|
+
),
|
|
8681
|
+
/* @__PURE__ */ jsxs("span", { class: "text-sm", children: [
|
|
8682
|
+
/* @__PURE__ */ jsx("span", { class: "font-medium text-success", children: "New value:" }),
|
|
8683
|
+
' "',
|
|
8684
|
+
searchQuery.value,
|
|
8685
|
+
'"'
|
|
8686
|
+
] })
|
|
8687
|
+
] })
|
|
8688
|
+
}
|
|
8689
|
+
)
|
|
8690
|
+
}
|
|
8691
|
+
)
|
|
8692
|
+
] }) })
|
|
8693
|
+
}
|
|
8694
|
+
)
|
|
8695
|
+
] });
|
|
8696
|
+
};
|
|
8245
8697
|
var FilterDrawer = (props) => {
|
|
8246
8698
|
const injectedFilterOptionsState = inject(
|
|
8247
8699
|
ZINIA_DATA_TABLE_FILTER_OPTIONS_STATE_KEY,
|
|
@@ -8270,8 +8722,7 @@ var FilterDrawer = (props) => {
|
|
|
8270
8722
|
/* @__PURE__ */ jsxs(
|
|
8271
8723
|
"aside",
|
|
8272
8724
|
{
|
|
8273
|
-
class: "absolute top-0 left-0 h-full w-full md:w-80 bg-base-100 flex flex-col shadow-xl transform transition-transform duration-300 ease-out translate-x-0 pointer-events-auto",
|
|
8274
|
-
style: { maxHeight: "100%" },
|
|
8725
|
+
class: "absolute top-0 left-0 h-full h-[600px] max-h-[90vh] w-full md:w-80 bg-base-100 flex flex-col shadow-xl transform transition-transform duration-300 ease-out translate-x-0 pointer-events-auto",
|
|
8275
8726
|
onClick: (e) => e.stopPropagation(),
|
|
8276
8727
|
"data-testid": `${props.tableName || "datatable"}-filter-drawer`,
|
|
8277
8728
|
children: [
|
|
@@ -8388,6 +8839,25 @@ var FilterDrawer = (props) => {
|
|
|
8388
8839
|
isLoading: props.isLoading,
|
|
8389
8840
|
onFilterChange: props.onFilterChange
|
|
8390
8841
|
}
|
|
8842
|
+
),
|
|
8843
|
+
filterType === "combobox" && /* @__PURE__ */ jsx(
|
|
8844
|
+
ComboboxFilter,
|
|
8845
|
+
{
|
|
8846
|
+
field,
|
|
8847
|
+
value: currentValue,
|
|
8848
|
+
options: getFilterOptions(
|
|
8849
|
+
field,
|
|
8850
|
+
column,
|
|
8851
|
+
props.fieldsMetadata,
|
|
8852
|
+
filterOptionsState?.value || {}
|
|
8853
|
+
),
|
|
8854
|
+
label: column.label,
|
|
8855
|
+
isLoading: props.isLoading,
|
|
8856
|
+
isOptionsLoading: filterOptionsLoading?.value?.[field] ?? false,
|
|
8857
|
+
allowCreate: column.filterAllowCreate ?? false,
|
|
8858
|
+
filterInputValues: props.filterInputValues,
|
|
8859
|
+
onFilterChange: props.onFilterChange
|
|
8860
|
+
}
|
|
8391
8861
|
)
|
|
8392
8862
|
]
|
|
8393
8863
|
},
|
|
@@ -9014,6 +9484,27 @@ function createDaisyUIDataTable() {
|
|
|
9014
9484
|
});
|
|
9015
9485
|
const selectionMode = computed(() => options.selection?.mode ?? "none");
|
|
9016
9486
|
const hasSelection = computed(() => selectionMode.value !== "none");
|
|
9487
|
+
const containerHeightClasses = computed(() => {
|
|
9488
|
+
const height = props.height ?? "auto";
|
|
9489
|
+
if (height === "fixed") {
|
|
9490
|
+
return "relative h-[850px] max-h-[90vh] flex flex-col";
|
|
9491
|
+
} else if (height === "auto") {
|
|
9492
|
+
return "relative flex-1 min-h-[670px] flex flex-col";
|
|
9493
|
+
} else if (typeof height === "number") {
|
|
9494
|
+
return `relative flex flex-col`;
|
|
9495
|
+
} else {
|
|
9496
|
+
return "relative flex flex-col";
|
|
9497
|
+
}
|
|
9498
|
+
});
|
|
9499
|
+
const containerHeightStyle = computed(() => {
|
|
9500
|
+
const height = props.height;
|
|
9501
|
+
if (typeof height === "number") {
|
|
9502
|
+
return { height: `${height}px` };
|
|
9503
|
+
} else if (typeof height === "string" && height !== "auto" && height !== "fixed") {
|
|
9504
|
+
return { height };
|
|
9505
|
+
}
|
|
9506
|
+
return {};
|
|
9507
|
+
});
|
|
9017
9508
|
if (filterInputValues && Object.keys(filterInputValues.value).length === 0) {
|
|
9018
9509
|
Object.entries(columns).forEach(([field, column]) => {
|
|
9019
9510
|
if (column?.filterable) {
|
|
@@ -9065,7 +9556,7 @@ function createDaisyUIDataTable() {
|
|
|
9065
9556
|
triggerBulkAction: table.triggerBulkAction
|
|
9066
9557
|
}
|
|
9067
9558
|
),
|
|
9068
|
-
/* @__PURE__ */ jsxs("div", { class:
|
|
9559
|
+
/* @__PURE__ */ jsxs("div", { class: containerHeightClasses.value, style: containerHeightStyle.value, children: [
|
|
9069
9560
|
Object.values(columns).some((col) => col?.filterable) && filterInputValues && filterOperators && /* @__PURE__ */ jsx(
|
|
9070
9561
|
FiltersRow,
|
|
9071
9562
|
{
|
|
@@ -9086,7 +9577,7 @@ function createDaisyUIDataTable() {
|
|
|
9086
9577
|
onCloseFilterDrawer: () => table.ui.closeFilterDrawer()
|
|
9087
9578
|
}
|
|
9088
9579
|
),
|
|
9089
|
-
/* @__PURE__ */ jsx("div", { class: "w-full
|
|
9580
|
+
/* @__PURE__ */ jsx("div", { class: "w-full flex-1 min-h-0 overflow-auto", children: table.isLoading ? /* @__PURE__ */ jsx(
|
|
9090
9581
|
LoadingSkeletons,
|
|
9091
9582
|
{
|
|
9092
9583
|
pageSize: table.pagination.pageSize,
|
|
@@ -9206,7 +9697,7 @@ function createDaisyUIDataTable() {
|
|
|
9206
9697
|
] })
|
|
9207
9698
|
] });
|
|
9208
9699
|
};
|
|
9209
|
-
DaisyUIDataTable.props = ["class"];
|
|
9700
|
+
DaisyUIDataTable.props = ["class", "name", "height"];
|
|
9210
9701
|
return DaisyUIDataTable;
|
|
9211
9702
|
}
|
|
9212
9703
|
|