@dragonmastery/zinia-forms-core 0.5.3 → 0.5.5

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 CHANGED
@@ -2864,6 +2864,7 @@ interface UrlSyncOptions {
2864
2864
  }
2865
2865
  interface DataTable {
2866
2866
  setFilter: (field: any, filter: any) => Promise<void>;
2867
+ clearFilter: (field: any) => Promise<void>;
2867
2868
  clearAllFilters: () => Promise<void>;
2868
2869
  setFiltersFromQueryParams: (params: Record<string, string | string[]>) => Promise<void>;
2869
2870
  load: () => Promise<void>;
package/dist/index.js CHANGED
@@ -8218,6 +8218,14 @@ function getFilterOptions(field, column, fieldsMetadata, filterOptionsState) {
8218
8218
  }
8219
8219
  return [];
8220
8220
  }
8221
+ function isBooleanOperator(operator) {
8222
+ if (!operator) return true;
8223
+ return OPERATORS_BY_TYPE.boolean.includes(operator);
8224
+ }
8225
+ function isEnumOperator(operator) {
8226
+ if (!operator) return true;
8227
+ return OPERATORS_BY_TYPE.enum.includes(operator);
8228
+ }
8221
8229
  function getSortLabels(field, column, fieldsMetadata) {
8222
8230
  if (column?.sortLabels) {
8223
8231
  return column.sortLabels;
@@ -8611,6 +8619,13 @@ var EnumMultiSelectFilter = (props) => {
8611
8619
  updateDropdownPosition();
8612
8620
  });
8613
8621
  };
8622
+ const closeDropdown = () => {
8623
+ applyPendingFilter();
8624
+ state.isOpen = false;
8625
+ state.searchQuery = "";
8626
+ state.selectedIndex = -1;
8627
+ cleanupEventListeners();
8628
+ };
8614
8629
  const removeSelected = (value) => {
8615
8630
  const currentValues = (Array.isArray(props.value) ? props.value : props.value ? [props.value] : []).filter(
8616
8631
  (v) => !valuesEqual(v, value)
@@ -8863,60 +8878,94 @@ var EnumMultiSelectFilter = (props) => {
8863
8878
  children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M19 9l-7 7-7-7" })
8864
8879
  }
8865
8880
  ) }),
8866
- state.isOpen && /* @__PURE__ */ jsx(Teleport, { to: "body", children: /* @__PURE__ */ jsx(
8881
+ state.isOpen && /* @__PURE__ */ jsx(Teleport, { to: "body", children: /* @__PURE__ */ jsxs(
8867
8882
  "div",
8868
8883
  {
8869
8884
  "data-enum-multiselect-dropdown": props.field,
8870
- class: "bg-base-100 border border-base-300 rounded-box shadow-lg overflow-auto",
8885
+ class: "bg-base-100 border border-base-300 rounded-box shadow-lg flex flex-col",
8871
8886
  style: dropdownStyle.value,
8872
8887
  onMousedown: (e) => {
8873
8888
  e.preventDefault();
8874
8889
  },
8875
- children: props.isOptionsLoading ? /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70", children: "Loading options..." }) }) : props.options.length === 0 ? /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70", children: "No options available" }) }) : filteredOptions.value.length === 0 ? /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsxs("span", { class: "text-sm text-base-content/70", children: [
8876
- 'No options found matching "',
8877
- state.searchQuery,
8878
- '"'
8879
- ] }) }) : /* @__PURE__ */ jsx("ul", { class: "menu menu-sm w-full p-2", role: "listbox", "aria-label": `${props.label} options`, children: filteredOptions.value.map((option, index) => {
8880
- const isSelected = selectedValues.some((v) => valuesEqual(v, option.value));
8881
- const isHighlighted = index === state.selectedIndex;
8882
- return /* @__PURE__ */ jsx(
8883
- "li",
8884
- {
8885
- "data-option-index": index,
8886
- role: "option",
8887
- "aria-selected": isSelected,
8888
- class: isHighlighted ? "bg-base-200 rounded" : "",
8889
- children: /* @__PURE__ */ jsxs(
8890
- "label",
8891
- {
8892
- class: "label cursor-pointer gap-2 p-2 rounded hover:bg-base-200",
8893
- onMousedown: (e) => {
8894
- e.preventDefault();
8895
- },
8896
- children: [
8897
- /* @__PURE__ */ jsx(
8898
- "input",
8899
- {
8900
- type: "checkbox",
8901
- checked: isSelected,
8902
- onChange: () => toggleOption(option),
8903
- class: "checkbox checkbox-sm checkbox-primary",
8904
- "data-testid": `datatable-filter-${props.field}-option-${option.value}`,
8905
- tabindex: -1
8906
- }
8907
- ),
8908
- /* @__PURE__ */ jsx("span", { class: "label-text flex-1 truncate", title: option.label, children: option.label })
8909
- ]
8910
- }
8911
- )
8912
- },
8913
- String(option.value)
8914
- );
8915
- }) })
8890
+ children: [
8891
+ /* @__PURE__ */ jsxs("div", { class: "flex items-center justify-between p-2 border-b border-base-300 flex-shrink-0", children: [
8892
+ /* @__PURE__ */ jsx("span", { class: "text-xs font-semibold text-base-content/70", children: props.label }),
8893
+ /* @__PURE__ */ jsx(
8894
+ "button",
8895
+ {
8896
+ type: "button",
8897
+ onClick: (e) => {
8898
+ e.preventDefault();
8899
+ e.stopPropagation();
8900
+ closeDropdown();
8901
+ },
8902
+ onMousedown: (e) => {
8903
+ e.preventDefault();
8904
+ },
8905
+ class: "btn btn-ghost btn-xs p-0 h-5 w-5 min-h-0 rounded hover:bg-base-300",
8906
+ "aria-label": "Close dropdown",
8907
+ "data-testid": `datatable-filter-${props.field}-close`,
8908
+ children: /* @__PURE__ */ jsx(
8909
+ "svg",
8910
+ {
8911
+ xmlns: "http://www.w3.org/2000/svg",
8912
+ class: "h-4 w-4",
8913
+ fill: "none",
8914
+ viewBox: "0 0 24 24",
8915
+ stroke: "currentColor",
8916
+ "stroke-width": "2",
8917
+ children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M6 18L18 6M6 6l12 12" })
8918
+ }
8919
+ )
8920
+ }
8921
+ )
8922
+ ] }),
8923
+ /* @__PURE__ */ jsx("div", { class: "overflow-auto flex-1", children: props.isOptionsLoading ? /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70", children: "Loading options..." }) }) : props.options.length === 0 ? /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsx("span", { class: "text-sm text-base-content/70", children: "No options available" }) }) : filteredOptions.value.length === 0 ? /* @__PURE__ */ jsx("div", { class: "p-2", children: /* @__PURE__ */ jsxs("span", { class: "text-sm text-base-content/70", children: [
8924
+ 'No options found matching "',
8925
+ state.searchQuery,
8926
+ '"'
8927
+ ] }) }) : /* @__PURE__ */ jsx("ul", { class: "menu menu-sm w-full p-2", role: "listbox", "aria-label": `${props.label} options`, children: filteredOptions.value.map((option, index) => {
8928
+ const isSelected = selectedValues.some((v) => valuesEqual(v, option.value));
8929
+ const isHighlighted = index === state.selectedIndex;
8930
+ return /* @__PURE__ */ jsx(
8931
+ "li",
8932
+ {
8933
+ "data-option-index": index,
8934
+ role: "option",
8935
+ "aria-selected": isSelected,
8936
+ class: isHighlighted ? "bg-base-200 rounded" : "",
8937
+ children: /* @__PURE__ */ jsxs(
8938
+ "label",
8939
+ {
8940
+ class: "label cursor-pointer gap-2 p-2 rounded hover:bg-base-200",
8941
+ onMousedown: (e) => {
8942
+ e.preventDefault();
8943
+ },
8944
+ children: [
8945
+ /* @__PURE__ */ jsx(
8946
+ "input",
8947
+ {
8948
+ type: "checkbox",
8949
+ checked: isSelected,
8950
+ onChange: () => toggleOption(option),
8951
+ class: "checkbox checkbox-sm checkbox-primary",
8952
+ "data-testid": `datatable-filter-${props.field}-option-${option.value}`,
8953
+ tabindex: -1
8954
+ }
8955
+ ),
8956
+ /* @__PURE__ */ jsx("span", { class: "label-text flex-1 truncate", title: option.label, children: option.label })
8957
+ ]
8958
+ }
8959
+ )
8960
+ },
8961
+ String(option.value)
8962
+ );
8963
+ }) }) })
8964
+ ]
8916
8965
  }
8917
8966
  ) })
8918
8967
  ] }),
8919
- /* @__PURE__ */ jsx("div", { class: "text-xs text-base-content/60", children: props.operator === "isOneOf" ? "Select one or more values" : "Exclude one or more values" })
8968
+ /* @__PURE__ */ jsx("div", { class: "text-xs text-base-content/60", children: props.operator === OPERATORS.IS_ONE_OF ? "Select one or more values" : "Show rows that do not match these values" })
8920
8969
  ] });
8921
8970
  };
8922
8971
  var SelectFilter = (props) => {
@@ -10122,7 +10171,15 @@ var FilterDrawer = (props) => {
10122
10171
  fill: "none",
10123
10172
  viewBox: "0 0 24 24",
10124
10173
  stroke: "currentColor",
10125
- children: /* @__PURE__ */ jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", "stroke-width": "2", d: "M6 18L18 6M6 6l12 12" })
10174
+ children: /* @__PURE__ */ jsx(
10175
+ "path",
10176
+ {
10177
+ "stroke-linecap": "round",
10178
+ "stroke-linejoin": "round",
10179
+ "stroke-width": "2",
10180
+ d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
10181
+ }
10182
+ )
10126
10183
  }
10127
10184
  ),
10128
10185
  "Clear All"
@@ -10180,7 +10237,7 @@ var FilterDrawer = (props) => {
10180
10237
  isOptionsLoading: filterOptionsLoading?.value?.[field] ?? false,
10181
10238
  allOptionText: column.filterAllOptionText,
10182
10239
  showAllOption: column.filterShowAllOption,
10183
- operator: currentFilter?.operator,
10240
+ operator: isEnumOperator(currentFilter?.operator) ? currentFilter?.operator : void 0,
10184
10241
  fieldType: convertToDataType(props.fieldsMetadata[field]?.type || "enum"),
10185
10242
  onFilterChange: props.onFilterChange,
10186
10243
  onClearFilter: props.onClearFilter
@@ -10220,7 +10277,7 @@ var FilterDrawer = (props) => {
10220
10277
  isLoading: props.isLoading,
10221
10278
  allOptionText: column.filterAllOptionText,
10222
10279
  showAllOption: column.filterShowAllOption,
10223
- operator: currentFilter?.operator,
10280
+ operator: isBooleanOperator(currentFilter?.operator) ? currentFilter?.operator : void 0,
10224
10281
  fieldType: convertToDataType(props.fieldsMetadata[field]?.type || "boolean"),
10225
10282
  options: getFilterOptions(
10226
10283
  field,
@@ -11933,6 +11990,7 @@ function useDataTableUrlSync(table, router, options = {}) {
11933
11990
  const { loadOnMount = true } = options;
11934
11991
  const isUpdatingFromRoute = ref(false);
11935
11992
  const originalSetFilter = table.setFilter.bind(table);
11993
+ const originalClearFilter = table.clearFilter.bind(table);
11936
11994
  const originalClearAllFilters = table.clearAllFilters.bind(table);
11937
11995
  const extractFilterParams = (query) => {
11938
11996
  const filterParams = {};
@@ -11956,12 +12014,22 @@ function useDataTableUrlSync(table, router, options = {}) {
11956
12014
  router.push({ query });
11957
12015
  };
11958
12016
  table.setFilter = async (field, filter) => {
11959
- await originalSetFilter(field, filter);
12017
+ const filterPromise = originalSetFilter(field, filter);
12018
+ await nextTick();
12019
+ updateUrlFromFilters();
12020
+ await filterPromise;
12021
+ };
12022
+ table.clearFilter = async (field) => {
12023
+ const filterPromise = originalClearFilter(field);
12024
+ await nextTick();
11960
12025
  updateUrlFromFilters();
12026
+ await filterPromise;
11961
12027
  };
11962
12028
  table.clearAllFilters = async () => {
11963
- await originalClearAllFilters();
12029
+ const filterPromise = originalClearAllFilters();
12030
+ await nextTick();
11964
12031
  updateUrlFromFilters();
12032
+ await filterPromise;
11965
12033
  };
11966
12034
  watch(
11967
12035
  () => router.currentRoute.value.query,