@astryx-vue/core 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/AppShell/index.js +1 -1
  2. package/dist/{AppShell-1wNIEtK_.js → AppShell-Cb41gIAj.js} +2 -2
  3. package/dist/AvatarGroup/index.d.ts +1 -1
  4. package/dist/Badge/index.d.ts +2 -1
  5. package/dist/Banner/index.d.ts +1 -1
  6. package/dist/Breadcrumbs/index.js +1 -1
  7. package/dist/{Breadcrumbs-C97HmjkC.js → Breadcrumbs-CTQ7fjDn.js} +2 -2
  8. package/dist/Button/index.d.ts +1 -1
  9. package/dist/ButtonGroup/index.d.ts +1 -1
  10. package/dist/Calendar/index.js +1 -1
  11. package/dist/{Calendar-DqC3EDN1.js → Calendar-BFaI5AMv.js} +1 -1
  12. package/dist/Carousel/index.js +1 -1
  13. package/dist/{Carousel-BGUnskjo.js → Carousel-X0cuQkvg.js} +2 -2
  14. package/dist/Chat/index.d.ts +2 -2
  15. package/dist/Chat/index.js +2 -2
  16. package/dist/Chat-M0tiGrNT.js +3148 -0
  17. package/dist/CheckboxInput/index.d.ts +1 -1
  18. package/dist/CheckboxList/index.d.ts +1 -1
  19. package/dist/Citation/index.js +1 -1
  20. package/dist/{Citation-DunoAqVH.js → Citation-C1veUk5p.js} +2 -2
  21. package/dist/ClickableCard/index.d.ts +1 -1
  22. package/dist/Code/index.js +1 -1
  23. package/dist/{CodeBlock-CAF-VJnh.js → CodeBlock-DesTJAkm.js} +1 -1
  24. package/dist/Collapsible/index.js +1 -1
  25. package/dist/{Collapsible-DvMiYJp7.js → Collapsible-BestK35V.js} +1 -1
  26. package/dist/CommandPalette/index.js +1 -1
  27. package/dist/{CommandPalette-xfm9ldUI.js → CommandPalette-BArt97V8.js} +1 -1
  28. package/dist/ComplexSelector/index.d.ts +1 -1
  29. package/dist/ComplexSelector/index.js +1 -1
  30. package/dist/{ComplexSelector-B6lBTRhP.js → ComplexSelector-CAoig1RK.js} +2 -2
  31. package/dist/ContextMenu/index.d.ts +1 -1
  32. package/dist/ContextMenu/index.js +1 -1
  33. package/dist/{ContextMenu-DUkED3Z3.js → ContextMenu-9Im6i43E.js} +1 -1
  34. package/dist/DateInput/index.d.ts +1 -1
  35. package/dist/DateInput/index.js +1 -1
  36. package/dist/{DateInput-Crcg-CCj.js → DateInput-BLocxqC3.js} +2 -2
  37. package/dist/DateRangeInput/index.d.ts +1 -1
  38. package/dist/DateRangeInput/index.js +1 -1
  39. package/dist/{DateRangeInput-e9KSxBBK.js → DateRangeInput-DwDy3eRo.js} +2 -2
  40. package/dist/DateTimeInput/index.d.ts +1 -1
  41. package/dist/DateTimeInput/index.js +1 -1
  42. package/dist/{DateTimeInput-fSOfuLex.js → DateTimeInput-BYiaC9bn.js} +3 -3
  43. package/dist/Divider/index.d.ts +1 -1
  44. package/dist/DropdownMenu/index.js +2 -2
  45. package/dist/{DropdownMenu-XvW4BJob.js → DropdownMenu-Ddfr-aEC.js} +2 -2
  46. package/dist/{DropdownMenu-8G0B1UND.js → DropdownMenu-Dh-WAHKb.js} +1 -1
  47. package/dist/FileInput/index.d.ts +1 -1
  48. package/dist/FileInput/index.js +1 -1
  49. package/dist/{FileInput-D-fchyQH.js → FileInput-DLO6V12n.js} +2 -2
  50. package/dist/Icon/index.d.ts +2 -2
  51. package/dist/Icon/index.js +1 -1
  52. package/dist/{Icon-Bku25g_K.js → Icon-CJKjdJy-.js} +6 -1
  53. package/dist/Lightbox/index.js +1 -1
  54. package/dist/{Lightbox-uuVGgHxW.js → Lightbox-CdFCS_EA.js} +2 -2
  55. package/dist/List/index.d.ts +1 -1
  56. package/dist/Markdown/index.js +1 -1
  57. package/dist/{Markdown-DLICa3db.js → Markdown-BqKloI3w.js} +2 -2
  58. package/dist/MetadataList/index.d.ts +1 -1
  59. package/dist/MetadataList/index.js +1 -1
  60. package/dist/{MetadataList-h492rqEN.js → MetadataList-CvZkmisf.js} +1 -1
  61. package/dist/MobileNav/index.js +1 -1
  62. package/dist/{MobileNavToggle-BMj3Wtuq.js → MobileNavToggle-Bwi0qXXM.js} +1 -1
  63. package/dist/MoreMenu/index.d.ts +1 -1
  64. package/dist/MoreMenu/index.js +1 -1
  65. package/dist/{MoreMenu-DkYi5az5.js → MoreMenu-BwJaJrkB.js} +1 -1
  66. package/dist/MultiSelector/index.d.ts +1 -1
  67. package/dist/MultiSelector/index.js +1 -1
  68. package/dist/{MultiSelector-C2IS-EaU.js → MultiSelector-C-ETfFy_.js} +2 -2
  69. package/dist/NavItem/index.d.ts +1 -1
  70. package/dist/NumberInput/index.d.ts +1 -1
  71. package/dist/NumberInput/index.js +1 -1
  72. package/dist/{NumberInput-CjfAsFwj.js → NumberInput-DjetVB8O.js} +1 -1
  73. package/dist/Outline/index.js +1 -1
  74. package/dist/{Outline-BTmrtvXR.js → Outline-Bz9c-u5y.js} +1 -1
  75. package/dist/OverflowList/index.d.ts +1 -1
  76. package/dist/OverflowList/index.js +1 -1
  77. package/dist/{OverflowList-CRE8BE7V.js → OverflowList-ED-KN9Y5.js} +1 -1
  78. package/dist/Pagination/index.js +1 -1
  79. package/dist/{Pagination-BpGXPmc7.js → Pagination-Cb66HMEf.js} +2 -2
  80. package/dist/PowerSearch/index.d.ts +2 -0
  81. package/dist/PowerSearch/index.js +2 -0
  82. package/dist/PowerSearch-CjU8y4mi.js +2386 -0
  83. package/dist/Radio/index.d.ts +1 -1
  84. package/dist/RadioList/index.d.ts +1 -1
  85. package/dist/Resizable/index.d.ts +1 -1
  86. package/dist/Resizable/index.js +1 -1
  87. package/dist/{Resizable-CE8XQDL2.js → Resizable-D-TBCg0Y.js} +1 -1
  88. package/dist/ScrollableArea/index.d.ts +1 -1
  89. package/dist/SegmentedControl/index.d.ts +1 -1
  90. package/dist/SelectableCard/index.d.ts +1 -1
  91. package/dist/Selector/index.d.ts +1 -1
  92. package/dist/Selector/index.js +1 -1
  93. package/dist/{Selector-DkJOLZSR.js → Selector-DE2IEFML.js} +1 -1
  94. package/dist/SideNav/index.d.ts +1 -1
  95. package/dist/SideNav/index.js +1 -1
  96. package/dist/{SideNav-DcDWBnXJ.js → SideNav-DonEfiAx.js} +2 -2
  97. package/dist/Stepper/index.d.ts +1 -1
  98. package/dist/Stepper/index.js +1 -1
  99. package/dist/{Stepper-DZKaqEoz.js → Stepper-D2ZIcUNx.js} +1 -1
  100. package/dist/Switch/index.d.ts +1 -1
  101. package/dist/TabList/index.js +1 -1
  102. package/dist/{TabList-hm06QPiW.js → TabList-D3F-stq-.js} +1 -1
  103. package/dist/Table/index.d.ts +3 -3
  104. package/dist/Table/index.js +2 -2
  105. package/dist/Table-CrP2Uffq.js +1982 -0
  106. package/dist/TextArea/index.d.ts +1 -1
  107. package/dist/TextInput/index.d.ts +1 -1
  108. package/dist/Thumbnail/index.js +1 -1
  109. package/dist/{Thumbnail-CAOYds8t.js → Thumbnail-BC5JGPGZ.js} +2 -2
  110. package/dist/{TimeField-BGbxCoKU.js → TimeField-DpHFrNv0.js} +2 -2
  111. package/dist/TimeInput/index.d.ts +1 -1
  112. package/dist/TimeInput/index.js +1 -1
  113. package/dist/{TimeInput-DJP3l4ZS.js → TimeInput-DJLV0_4z.js} +1 -1
  114. package/dist/Timestamp/index.d.ts +1 -1
  115. package/dist/Timestamp/index.js +1 -1
  116. package/dist/{Timestamp-BzRp8uWc.js → Timestamp-GKNjjt5g.js} +3 -3
  117. package/dist/ToggleButton/index.d.ts +1 -1
  118. package/dist/Token/index.js +1 -1
  119. package/dist/{Token-CjocuhzE.js → Token-Chu_eCVs.js} +1 -1
  120. package/dist/Tokenizer/index.js +1 -1
  121. package/dist/{Tokenizer-mYES5SPM.js → Tokenizer-DRDpvQ_l.js} +3 -3
  122. package/dist/Toolbar/index.d.ts +1 -1
  123. package/dist/TopNav/index.d.ts +1 -1
  124. package/dist/TopNav/index.js +1 -1
  125. package/dist/{TopNav-C2t6JkZb.js → TopNav-CEyWddtA.js} +3 -3
  126. package/dist/TreeList/index.d.ts +1 -1
  127. package/dist/TreeList/index.js +1 -1
  128. package/dist/{TreeList-THJ0KamE.js → TreeList-COS8US8e.js} +2 -2
  129. package/dist/Typeahead/index.js +1 -1
  130. package/dist/{Typeahead-D7VnvRpK.js → Typeahead-P7cCqtaQ.js} +3 -3
  131. package/dist/{useTypeaheadMenu-Ba7XpcZl.js → TypeaheadMenu-CGvo0Tud.js} +107 -107
  132. package/dist/composables/index.d.ts +3 -3
  133. package/dist/{context-DzcK4T_C.js → context-CiKncNSH.js} +180 -4
  134. package/dist/{index-SMh42NI8.d.ts → index-B1TG2GPS.d.ts} +2 -2
  135. package/dist/index-B9WzWqzk.d.ts +18 -0
  136. package/dist/{index-Z_onS2lR.d.ts → index-C7mxUcDR.d.ts} +2 -2
  137. package/dist/{index-cG1E0U2s.d.ts → index-CVn0GBdB.d.ts} +1 -1
  138. package/dist/{index-DnEh-HA0.d.ts → index-C_2Z65Rp.d.ts} +1 -1
  139. package/dist/{index-DXSs3rwa.d.ts → index-CngORuiq.d.ts} +137 -2
  140. package/dist/index-Cs5pcwY3.d.ts +416 -0
  141. package/dist/{index-DnSrjbjP.d.ts → index-D-ZuubCK.d.ts} +1 -1
  142. package/dist/{index-DAiGhkNZ.d.ts → index-D4I_obqR.d.ts} +1 -1
  143. package/dist/{index-I4J7gwa1.d.ts → index-DGXviOlp.d.ts} +1 -1
  144. package/dist/{index-BLOEjvaM.d.ts → index-DN7MXPHM.d.ts} +1 -1
  145. package/dist/{index-DeOftUMq.d.ts → index-DNRBbwp_.d.ts} +37 -36
  146. package/dist/{index-DQAnGHu7.d.ts → index-DOUEn7V0.d.ts} +2 -2
  147. package/dist/{index-CBym0hSq.d.ts → index-DWH_HzXi.d.ts} +1 -1
  148. package/dist/{index-Byar3h1e.d.ts → index-HV6W3xCx.d.ts} +1 -1
  149. package/dist/{index-D2bSSSBP.d.ts → index-fa72tWIU.d.ts} +1 -1
  150. package/dist/{index-COxy6LEW.d.ts → index-gW0HW02U.d.ts} +1 -1
  151. package/dist/index-kVhSuA9t.d.ts +902 -0
  152. package/dist/{index-1uRMrk63.d.ts → index-nCEmW6wa.d.ts} +1 -1
  153. package/dist/{index-Clmz00IK.d.ts → index-qiZtHnGK.d.ts} +24 -0
  154. package/dist/{index-3p2BDVHq.d.ts → index-u5ozu0G7.d.ts} +2 -2
  155. package/dist/{index-NOXYEdOI.d.ts → index-utZGF4GR.d.ts} +1 -1
  156. package/dist/index.d.ts +73 -71
  157. package/dist/index.js +106 -98
  158. package/dist/locale/index.d.ts +1 -1
  159. package/dist/locale/index.js +1 -1
  160. package/dist/power-search-DrDfcoL1.d.ts +68 -0
  161. package/dist/{types-JktRxujg.d.ts → types-Cp4liug-.d.ts} +66 -3
  162. package/dist/types-DIYwbkpe.d.ts +33 -0
  163. package/dist/{types-BKcxXW--.d.ts → types-pnljWjEE.d.ts} +1 -1
  164. package/dist/{useResizable-CeESZS1v.d.ts → useResizable-CUoNPmUw.d.ts} +1 -1
  165. package/package.json +5 -1
  166. package/styles/chat.css +469 -1
  167. package/styles/icon.css +20 -0
  168. package/styles/power-search.css +303 -0
  169. package/styles/table.css +304 -1
  170. package/styles.css +1 -0
  171. package/dist/Chat-DCjXRiOF.js +0 -1051
  172. package/dist/Table-DwehtMap.js +0 -967
  173. package/dist/index-CuFLztiI.d.ts +0 -49
  174. package/dist/index-DJo-BmXZ.d.ts +0 -431
@@ -0,0 +1,2386 @@
1
+ import { t as _sfc_main$5 } from "./Button-DrqeomlE.js";
2
+ import { t as useAnnounce } from "./announce-Cnio10Wk.js";
3
+ import { t as createStaticSource } from "./useAsyncSource-Gk0VtE7_.js";
4
+ import { t as useDismiss } from "./useDismiss-CAiHU6QD.js";
5
+ import { n as useOverflow } from "./useOverflow-VrwF5oek.js";
6
+ import { a as useAstryxMessages, i as useAstryxLocale } from "./context-CiKncNSH.js";
7
+ import { t as _sfc_main$6 } from "./Tooltip-mp0NMh_Y.js";
8
+ import { t as _sfc_main$7 } from "./Icon-CJKjdJy-.js";
9
+ import { t as _sfc_main$8 } from "./Field-8zRxzDHE.js";
10
+ import { t as _sfc_main$9 } from "./DateInput-BLocxqC3.js";
11
+ import { t as _sfc_main$10 } from "./DateRangeInput-DwDy3eRo.js";
12
+ import { t as _sfc_main$11 } from "./DateTimeInput-BYiaC9bn.js";
13
+ import { t as _sfc_main$12 } from "./Token-Chu_eCVs.js";
14
+ import { n as useAnchoredListbox, t as scrollOptionIntoView } from "./useAnchoredListbox-7W90Ny-9.js";
15
+ import { t as _sfc_main$13 } from "./MultiSelector-C-ETfFy_.js";
16
+ import { t as _sfc_main$14 } from "./NumberInput-DjetVB8O.js";
17
+ import { t as _sfc_main$15 } from "./Selector-DE2IEFML.js";
18
+ import { n as useTypeaheadMenu } from "./TypeaheadMenu-CGvo0Tud.js";
19
+ import { t as _sfc_main$16 } from "./TextInput-BasnjVvy.js";
20
+ import { t as _sfc_main$17 } from "./TimeInput-DJLV0_4z.js";
21
+ import { t as _sfc_main$18 } from "./Tokenizer-DRDpvQ_l.js";
22
+ import { t as _sfc_main$19 } from "./Typeahead-P7cCqtaQ.js";
23
+ import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, toDisplayString, unref, useId, useSlots, useTemplateRef, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
24
+ import "../styles/visually-hidden-utility.css";
25
+ import "../styles/typeahead.css";
26
+ import "../styles/power-search.css";
27
+ //#region src/PowerSearch/complete.ts
28
+ function nestedChildren(partial) {
29
+ if (partial.children != null) return partial.children;
30
+ if (partial.value?.type === "nested") return partial.value.value;
31
+ return [];
32
+ }
33
+ function isFilled(value) {
34
+ switch (value.type) {
35
+ case "empty": return true;
36
+ case "string":
37
+ case "date_relative":
38
+ case "time":
39
+ case "enum":
40
+ case "custom": return value.value.trim() !== "";
41
+ case "string_list":
42
+ case "enum_list":
43
+ case "entity_list": return value.value.length > 0;
44
+ case "integer":
45
+ case "float": return Number.isFinite(value.value);
46
+ case "date_absolute": return Number.isFinite(value.unixSeconds);
47
+ case "date_range": return value.value.start != null && value.value.end != null;
48
+ case "nested": return value.value.length > 0;
49
+ }
50
+ }
51
+ /** 条件齐全才返回可保存的筛选。嵌套里有没填完的子条件时返回空。 */
52
+ function completePowerSearchFilter(partial, lookup) {
53
+ if (partial.field === "" || partial.operator == null || partial.operator === "") return null;
54
+ const operator = lookup.getOperator(partial.field, partial.operator);
55
+ if (operator == null) return null;
56
+ if (operator.value.type === "empty") return {
57
+ field: partial.field,
58
+ operator: partial.operator,
59
+ value: { type: "empty" },
60
+ isReadOnly: partial.isReadOnly
61
+ };
62
+ if (operator.value.type === "nested") {
63
+ const children = nestedChildren(partial);
64
+ if (children.length === 0) return null;
65
+ const complete = children.map((child) => completePowerSearchFilter(child, lookup));
66
+ if (complete.some((child) => child == null)) return null;
67
+ return {
68
+ field: partial.field,
69
+ operator: partial.operator,
70
+ value: {
71
+ type: "nested",
72
+ value: complete.filter((child) => child != null)
73
+ },
74
+ isReadOnly: partial.isReadOnly
75
+ };
76
+ }
77
+ if (partial.value == null || partial.value.type !== operator.value.type || !isFilled(partial.value)) return null;
78
+ return {
79
+ field: partial.field,
80
+ operator: partial.operator,
81
+ value: partial.value,
82
+ isReadOnly: partial.isReadOnly
83
+ };
84
+ }
85
+ //#endregion
86
+ //#region src/PowerSearch/config.ts
87
+ function createPowerSearchLookup(config) {
88
+ const fieldMap = /* @__PURE__ */ new Map();
89
+ const operatorMap = /* @__PURE__ */ new Map();
90
+ for (const field of config.fields) {
91
+ fieldMap.set(field.key, field);
92
+ const operators = /* @__PURE__ */ new Map();
93
+ for (const operator of field.operators) operators.set(operator.key, operator);
94
+ operatorMap.set(field.key, operators);
95
+ }
96
+ return {
97
+ config,
98
+ getField(key) {
99
+ return fieldMap.get(key);
100
+ },
101
+ getOperator(fieldKey, operatorKey) {
102
+ return operatorMap.get(fieldKey)?.get(operatorKey);
103
+ },
104
+ getDefaultOperator(fieldKey) {
105
+ const field = fieldMap.get(fieldKey);
106
+ if (field == null) return void 0;
107
+ if (field.defaultOperator) return operatorMap.get(fieldKey)?.get(field.defaultOperator) ?? field.operators[0];
108
+ return field.operators[0];
109
+ },
110
+ getVisibleFields() {
111
+ return config.fields;
112
+ },
113
+ getVisibleOperators(fieldKey) {
114
+ return fieldMap.get(fieldKey)?.operators ?? [];
115
+ }
116
+ };
117
+ }
118
+ //#endregion
119
+ //#region src/PowerSearch/format.ts
120
+ function truncate(value, maxLength) {
121
+ const chars = Array.from(value);
122
+ if (chars.length <= maxLength) return value;
123
+ return `${chars.slice(0, Math.max(0, maxLength)).join("")}…`;
124
+ }
125
+ function enumLabel(value, values) {
126
+ return values.find((item) => item.value === value)?.label ?? value;
127
+ }
128
+ function formatNumber(value, locale, units) {
129
+ const formatted = new Intl.NumberFormat(locale).format(value);
130
+ return units ? `${formatted} ${units}` : formatted;
131
+ }
132
+ function formatDateAbsolute(unixSeconds, locale, timeZone) {
133
+ return new Intl.DateTimeFormat(locale, {
134
+ year: "numeric",
135
+ month: "short",
136
+ day: "numeric",
137
+ hour: "numeric",
138
+ minute: "2-digit",
139
+ ...timeZone ? { timeZone } : {},
140
+ calendar: "gregory"
141
+ }).format(unixSeconds * 1e3);
142
+ }
143
+ function formatDateAbsoluteCompact(unixSeconds, locale, timeZone) {
144
+ return new Intl.DateTimeFormat(locale, {
145
+ year: "numeric",
146
+ month: "short",
147
+ day: "numeric",
148
+ ...timeZone ? { timeZone } : {},
149
+ calendar: "gregory"
150
+ }).format(unixSeconds * 1e3);
151
+ }
152
+ function joinOrCount(labels, maxLength, countLabel) {
153
+ if (labels.length === 0) return "";
154
+ if (labels.length === 1) return truncate(labels[0] ?? "", maxLength);
155
+ const joined = labels.join(", ");
156
+ if (Array.from(joined).length <= maxLength) return joined;
157
+ return countLabel(labels.length);
158
+ }
159
+ function formatFilterValue(operatorValue, filterValue, maxLength, messages, locale, timeZone) {
160
+ switch (filterValue.type) {
161
+ case "empty": return "";
162
+ case "string": return truncate(filterValue.value, maxLength);
163
+ case "integer": return formatNumber(filterValue.value, locale, operatorValue.type === "integer" ? operatorValue.units : void 0);
164
+ case "float": return formatNumber(filterValue.value, locale, operatorValue.type === "float" ? operatorValue.units : void 0);
165
+ case "enum": return truncate(operatorValue.type === "enum" ? enumLabel(filterValue.value, operatorValue.values) : filterValue.value, maxLength);
166
+ case "string_list": return joinOrCount(filterValue.value, maxLength, messages.itemsCount);
167
+ case "enum_list": return joinOrCount(operatorValue.type === "enum_list" ? filterValue.value.map((value) => enumLabel(value, operatorValue.values)) : filterValue.value, maxLength, messages.itemsCount);
168
+ case "entity_list": return joinOrCount(filterValue.value.map((entity) => entity.label), maxLength, messages.entitiesCount);
169
+ case "time": return filterValue.value;
170
+ case "date_absolute": return truncate(operatorValue.type === "date_absolute" && operatorValue.isDateOnly ? formatDateAbsoluteCompact(filterValue.unixSeconds, locale, timeZone) : formatDateAbsolute(filterValue.unixSeconds, locale, timeZone), maxLength);
171
+ case "date_relative": return filterValue.value;
172
+ case "date_range": return messages.dateRange;
173
+ case "custom": return truncate(operatorValue.type === "custom" ? operatorValue.getString(filterValue.value) : filterValue.value, maxLength);
174
+ case "nested": return messages.filtersCount(filterValue.value.length);
175
+ }
176
+ }
177
+ //#endregion
178
+ //#region src/PowerSearch/operators.ts
179
+ const OPERATOR_MESSAGE_KEYS = {
180
+ contains: "contains",
181
+ notContains: "notContains",
182
+ not_contains: "notContains",
183
+ startsWith: "startsWith",
184
+ starts_with: "startsWith",
185
+ notStartsWith: "notStartsWith",
186
+ not_starts_with: "notStartsWith",
187
+ endsWith: "endsWith",
188
+ ends_with: "endsWith",
189
+ notEndsWith: "notEndsWith",
190
+ not_ends_with: "notEndsWith",
191
+ is: "is",
192
+ isNot: "isNot",
193
+ is_not: "isNot",
194
+ equals: "equals",
195
+ notEquals: "notEquals",
196
+ not_equals: "notEquals",
197
+ greaterThan: "greaterThan",
198
+ greater_than: "greaterThan",
199
+ lessThan: "lessThan",
200
+ less_than: "lessThan",
201
+ greaterThanOrEqual: "greaterThanOrEqual",
202
+ greater_than_or_equal: "greaterThanOrEqual",
203
+ lessThanOrEqual: "lessThanOrEqual",
204
+ less_than_or_equal: "lessThanOrEqual",
205
+ before: "before",
206
+ after: "after",
207
+ between: "between",
208
+ isTrue: "isTrue",
209
+ is_true: "isTrue",
210
+ isFalse: "isFalse",
211
+ is_false: "isFalse",
212
+ isAnyOf: "isAnyOf",
213
+ is_any_of: "isAnyOf",
214
+ isNoneOf: "isNoneOf",
215
+ is_none_of: "isNoneOf"
216
+ };
217
+ function resolveOperatorLabel(operator, messages) {
218
+ if ("label" in operator && operator.label != null) return operator.label;
219
+ const raw = operator.i18nKey ?? "";
220
+ const leaf = raw.split(".").pop() ?? raw;
221
+ const key = OPERATOR_MESSAGE_KEYS[leaf] ?? OPERATOR_MESSAGE_KEYS[raw];
222
+ return key ? messages.operators[key] : leaf;
223
+ }
224
+ /**
225
+ * 编辑器宽度取外层宽度,再夹在 400 到 720 之间。
226
+ * 视口放不下 400 时,下限让给视口。只有被 720 压窄时,才改贴打开控件更近的外缘。
227
+ */
228
+ function resolveEditorPlacement(input) {
229
+ const inset = input.viewportInset ?? 8;
230
+ const available = Math.max(0, input.viewportWidth - inset * 2);
231
+ const floor = Math.min(400, available);
232
+ const ceiling = Math.min(720, available);
233
+ let width = input.outer.width;
234
+ if (width < floor) width = floor;
235
+ if (width > ceiling) width = ceiling;
236
+ const capped = width + .5 < input.outer.width;
237
+ let edge;
238
+ if (!capped) edge = input.direction === "rtl" ? "right" : "left";
239
+ else {
240
+ const gapLeft = input.control.left - input.outer.left;
241
+ const gapRight = input.outer.right - input.control.right;
242
+ if (gapLeft < gapRight) edge = "left";
243
+ else if (gapRight < gapLeft) edge = "right";
244
+ else edge = input.direction === "rtl" ? "right" : "left";
245
+ }
246
+ let left = edge === "left" ? input.outer.left : input.outer.right - width;
247
+ const maxLeft = input.viewportWidth - inset - width;
248
+ if (left < inset) left = inset;
249
+ if (left > maxLeft) left = Math.max(inset, maxLeft);
250
+ const gap = 4;
251
+ const estimatedHeight = 280;
252
+ let top = input.anchorBottom + gap;
253
+ if (top + estimatedHeight > input.viewportHeight - inset && input.anchorTop - gap - estimatedHeight > inset) top = input.anchorTop - gap - estimatedHeight;
254
+ return {
255
+ width,
256
+ capped,
257
+ edge,
258
+ top,
259
+ left
260
+ };
261
+ }
262
+ //#endregion
263
+ //#region src/PowerSearch/range.ts
264
+ const SECONDS_BY_UNIT = {
265
+ second: 1,
266
+ minute: 60,
267
+ hour: 3600,
268
+ day: 86400,
269
+ week: 604800,
270
+ month: 2592e3,
271
+ year: 31536e3
272
+ };
273
+ /** 把绝对、当前和相对的区间端点折成同一时刻上的 Unix 秒。 */
274
+ function resolveDateTimeRangePart(part, nowSeconds = Date.now() / 1e3) {
275
+ switch (part.type) {
276
+ case "NOW": return Math.floor(nowSeconds);
277
+ case "ABSOLUTE": return part.unixSeconds;
278
+ case "RELATIVE": return Math.floor(nowSeconds - part.backValue * SECONDS_BY_UNIT[part.unit]);
279
+ }
280
+ }
281
+ //#endregion
282
+ //#region src/PowerSearch/dates.ts
283
+ function pad(value) {
284
+ return String(value).padStart(2, "0");
285
+ }
286
+ function unixToIsoDate(unixSeconds, timeZone) {
287
+ const date = /* @__PURE__ */ new Date(unixSeconds * 1e3);
288
+ if (!timeZone) return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
289
+ const parts = new Intl.DateTimeFormat("en-US", {
290
+ timeZone,
291
+ year: "numeric",
292
+ month: "2-digit",
293
+ day: "2-digit"
294
+ }).formatToParts(date);
295
+ return `${parts.find((part) => part.type === "year")?.value ?? "1970"}-${parts.find((part) => part.type === "month")?.value ?? "01"}-${parts.find((part) => part.type === "day")?.value ?? "01"}`;
296
+ }
297
+ function unixToDateTimeLocal(unixSeconds, timeZone) {
298
+ const date = /* @__PURE__ */ new Date(unixSeconds * 1e3);
299
+ if (!timeZone) return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
300
+ const parts = new Intl.DateTimeFormat("en-US", {
301
+ timeZone,
302
+ year: "numeric",
303
+ month: "2-digit",
304
+ day: "2-digit",
305
+ hour: "2-digit",
306
+ minute: "2-digit",
307
+ hourCycle: "h23"
308
+ }).formatToParts(date);
309
+ const read = (type) => parts.find((part) => part.type === type)?.value ?? "00";
310
+ return `${read("year")}-${read("month")}-${read("day")}T${read("hour")}:${read("minute")}`;
311
+ }
312
+ function isoDateToUnix(value) {
313
+ const [year, month, day] = value.split("-").map(Number);
314
+ return Math.floor(Date.UTC(year ?? 1970, (month ?? 1) - 1, day ?? 1) / 1e3);
315
+ }
316
+ function dateTimeLocalToUnix(value, timeZone) {
317
+ if (!timeZone) return Math.floor(new Date(value).getTime() / 1e3);
318
+ const [datePart, timePart] = value.split("T");
319
+ const [year, month, day] = (datePart ?? "").split("-").map(Number);
320
+ const [hour, minute] = (timePart ?? "00:00").split(":").map(Number);
321
+ const utcGuess = Date.UTC(year ?? 1970, (month ?? 1) - 1, day ?? 1, hour ?? 0, minute ?? 0);
322
+ const offset = timeZoneOffset(new Date(utcGuess), timeZone);
323
+ return Math.floor((utcGuess - offset) / 1e3);
324
+ }
325
+ function timeZoneOffset(date, timeZone) {
326
+ const parts = new Intl.DateTimeFormat("en-US", {
327
+ timeZone,
328
+ year: "numeric",
329
+ month: "2-digit",
330
+ day: "2-digit",
331
+ hour: "2-digit",
332
+ minute: "2-digit",
333
+ second: "2-digit",
334
+ hourCycle: "h23"
335
+ }).formatToParts(date);
336
+ const read = (type) => Number(parts.find((part) => part.type === type)?.value ?? 0);
337
+ return Date.UTC(read("year"), read("month") - 1, read("day"), read("hour"), read("minute"), read("second")) - date.getTime();
338
+ }
339
+ function rangePartToIso(part, timeZone, nowSeconds = Date.now() / 1e3) {
340
+ return unixToIsoDate(resolveDateTimeRangePart(part, nowSeconds), timeZone);
341
+ }
342
+ function absoluteRange(start, end) {
343
+ return {
344
+ start: {
345
+ type: "ABSOLUTE",
346
+ unixSeconds: isoDateToUnix(start)
347
+ },
348
+ end: {
349
+ type: "ABSOLUTE",
350
+ unixSeconds: isoDateToUnix(end) + 86399
351
+ }
352
+ };
353
+ }
354
+ //#endregion
355
+ //#region src/PowerSearch/PowerSearchValueField.vue
356
+ const _hoisted_1$4 = {
357
+ key: 7,
358
+ class: "astryx-power-search-value__stack"
359
+ };
360
+ const _hoisted_2$3 = {
361
+ key: 8,
362
+ class: "astryx-power-search-value__stack"
363
+ };
364
+ const _hoisted_3$3 = ["aria-label"];
365
+ const _hoisted_4$2 = ["disabled", "onClick"];
366
+ const _sfc_main$4 = /*@__PURE__*/ defineComponent({
367
+ name: "AstryxPowerSearchValueField",
368
+ __name: "PowerSearchValueField",
369
+ props: {
370
+ operatorValue: {},
371
+ filterValue: {},
372
+ messages: {},
373
+ disabled: { type: Boolean },
374
+ timeZone: {},
375
+ maxMenuItems: {}
376
+ },
377
+ emits: ["change"],
378
+ setup(__props, { emit: __emit }) {
379
+ const props = __props;
380
+ const emit = __emit;
381
+ const text = computed(() => props.messages.value);
382
+ const stringValue = computed(() => props.filterValue?.type === "string" ? props.filterValue.value : "");
383
+ const numberValue = computed(() => props.filterValue?.type === "integer" || props.filterValue?.type === "float" ? props.filterValue.value : null);
384
+ const timeValue = computed(() => props.filterValue?.type === "time" ? props.filterValue.value : null);
385
+ const enumValue = computed(() => props.filterValue?.type === "enum" ? props.filterValue.value : null);
386
+ const enumList = computed(() => props.filterValue?.type === "enum_list" ? [...props.filterValue.value] : []);
387
+ const relativeValue = computed(() => props.filterValue?.type === "date_relative" ? props.filterValue.value : "");
388
+ const customValue = computed(() => props.filterValue?.type === "custom" ? props.filterValue.value : "");
389
+ const stringItems = computed(() => {
390
+ if (props.filterValue?.type !== "string_list") return [];
391
+ return props.filterValue.value.map((value) => ({
392
+ id: value,
393
+ label: value
394
+ }));
395
+ });
396
+ const entityItems = computed(() => {
397
+ if (props.filterValue?.type !== "entity_list") return [];
398
+ return props.filterValue.value.map((entity) => ({
399
+ id: entity.id,
400
+ label: entity.label,
401
+ auxiliaryData: entity
402
+ }));
403
+ });
404
+ const selectedStringItem = computed(() => stringValue.value ? {
405
+ id: stringValue.value,
406
+ label: stringValue.value
407
+ } : null);
408
+ const enumOptions = computed(() => {
409
+ const value = props.operatorValue;
410
+ if (value.type !== "enum" && value.type !== "enum_list") return [];
411
+ return value.values.map((item) => ({
412
+ value: item.value,
413
+ label: item.label,
414
+ icon: item.icon
415
+ }));
416
+ });
417
+ const relativeOptions = computed(() => props.operatorValue.type === "date_relative" ? [] : props.operatorValue.type === "date_range" ? (props.operatorValue.relativeDatePresets ?? []).map((preset) => ({
418
+ value: preset.value,
419
+ label: preset.label
420
+ })) : []);
421
+ const dateOnly = computed(() => props.operatorValue.type === "date_absolute" && props.operatorValue.isDateOnly === true);
422
+ const absoluteDate = computed(() => {
423
+ if (props.filterValue?.type !== "date_absolute") return null;
424
+ return /* @__PURE__ */ new Date(props.filterValue.unixSeconds * 1e3);
425
+ });
426
+ const absoluteLocal = computed(() => props.filterValue?.type === "date_absolute" ? unixToDateTimeLocal(props.filterValue.unixSeconds, props.timeZone) : null);
427
+ const rangeModel = computed(() => {
428
+ if (props.filterValue?.type !== "date_range") return null;
429
+ return {
430
+ start: rangePartToIso(props.filterValue.value.start, props.timeZone),
431
+ end: rangePartToIso(props.filterValue.value.end, props.timeZone)
432
+ };
433
+ });
434
+ const stringSource = computed(() => props.operatorValue.type === "string" || props.operatorValue.type === "string_list" ? props.operatorValue.searchSource ?? createStaticSource([]) : createStaticSource([]));
435
+ const entitySource = computed(() => props.operatorValue.type === "entity_list" ? props.operatorValue.searchSource ?? createStaticSource([]) : createStaticSource([]));
436
+ const stringCreatable = computed(() => {
437
+ const value = props.operatorValue;
438
+ if (value.type !== "string_list" && value.type !== "entity_list") return false;
439
+ return value.isArbitraryStringAllowed === true || value.searchSource == null;
440
+ });
441
+ function commitStringList(items) {
442
+ emit("change", {
443
+ type: "string_list",
444
+ value: items.map((item) => item.label)
445
+ });
446
+ }
447
+ function commitEntities(items) {
448
+ const entities = items.map((item) => ({
449
+ id: item.id,
450
+ label: item.label,
451
+ photo: typeof item.auxiliaryData === "object" && item.auxiliaryData && "photo" in item.auxiliaryData ? String(item.auxiliaryData.photo ?? "") : void 0
452
+ }));
453
+ emit("change", {
454
+ type: "entity_list",
455
+ value: entities
456
+ });
457
+ }
458
+ function onPaste(event) {
459
+ const value = props.operatorValue;
460
+ if (value.type !== "string_list" && value.type !== "entity_list") return;
461
+ const pattern = value.tokenization?.regex;
462
+ if (!pattern) return;
463
+ const pasted = event.clipboardData?.getData("text") ?? "";
464
+ if (!pasted) return;
465
+ let pieces = [];
466
+ try {
467
+ pieces = pasted.match(new RegExp(pattern, "g")) ?? [];
468
+ } catch {
469
+ return;
470
+ }
471
+ if (pieces.length === 0) return;
472
+ event.preventDefault();
473
+ if (value.tokenization?.sort) pieces.sort((left, right) => left.localeCompare(right));
474
+ if (value.type === "string_list") {
475
+ const current = stringItems.value.map((item) => item.label);
476
+ emit("change", {
477
+ type: "string_list",
478
+ value: [...current, ...pieces]
479
+ });
480
+ return;
481
+ }
482
+ const current = entityItems.value.map((item) => ({
483
+ id: item.id,
484
+ label: item.label
485
+ }));
486
+ emit("change", {
487
+ type: "entity_list",
488
+ value: [...current, ...pieces.map((piece) => ({
489
+ id: piece,
490
+ label: piece
491
+ }))]
492
+ });
493
+ }
494
+ function onRange(value) {
495
+ if (value == null || typeof value !== "object" || !("start" in value) || !("end" in value)) return;
496
+ const start = value.start;
497
+ const end = value.end;
498
+ if (typeof start !== "string" || typeof end !== "string") return;
499
+ emit("change", {
500
+ type: "date_range",
501
+ value: absoluteRange(start, end)
502
+ });
503
+ }
504
+ function onTime(value) {
505
+ if (typeof value === "string" && value !== "") emit("change", {
506
+ type: "time",
507
+ value
508
+ });
509
+ }
510
+ function onAbsoluteDate(value) {
511
+ if (!(value instanceof Date)) return;
512
+ emit("change", {
513
+ type: "date_absolute",
514
+ unixSeconds: isoDateToUnix(unixToIsoDate(Math.floor(value.getTime() / 1e3), props.timeZone))
515
+ });
516
+ }
517
+ function onAbsoluteDateTime(value) {
518
+ if (typeof value !== "string" || value === "") return;
519
+ emit("change", {
520
+ type: "date_absolute",
521
+ unixSeconds: dateTimeLocalToUnix(value, props.timeZone)
522
+ });
523
+ }
524
+ function onCustomValue(value) {
525
+ emit("change", {
526
+ type: "custom",
527
+ value: value == null ? "" : String(value)
528
+ });
529
+ }
530
+ function applyPreset(range) {
531
+ emit("change", {
532
+ type: "date_range",
533
+ value: range
534
+ }, true);
535
+ }
536
+ return (_ctx, _cache) => {
537
+ return openBlock(), createElementBlock("div", {
538
+ class: "astryx-power-search-value",
539
+ onPaste
540
+ }, [__props.operatorValue.type === "string" && __props.operatorValue.searchSource ? (openBlock(), createBlock(_sfc_main$19, {
541
+ key: 0,
542
+ label: text.value.value,
543
+ "label-hidden": "",
544
+ "search-source": stringSource.value,
545
+ "model-value": selectedStringItem.value,
546
+ placeholder: text.value.searchPlaceholder,
547
+ disabled: __props.disabled,
548
+ "max-menu-items": __props.maxMenuItems,
549
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = (item) => emit("change", {
550
+ type: "string",
551
+ value: item?.label ?? ""
552
+ }, Boolean(item)))
553
+ }, null, 8, [
554
+ "label",
555
+ "search-source",
556
+ "model-value",
557
+ "placeholder",
558
+ "disabled",
559
+ "max-menu-items"
560
+ ])) : __props.operatorValue.type === "string" ? (openBlock(), createBlock(_sfc_main$16, {
561
+ key: 1,
562
+ label: text.value.value,
563
+ "is-label-hidden": "",
564
+ "model-value": stringValue.value,
565
+ placeholder: text.value.enterValuePlaceholder,
566
+ disabled: __props.disabled,
567
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = (value) => emit("change", {
568
+ type: "string",
569
+ value: String(value ?? "")
570
+ }))
571
+ }, null, 8, [
572
+ "label",
573
+ "model-value",
574
+ "placeholder",
575
+ "disabled"
576
+ ])) : __props.operatorValue.type === "string_list" ? (openBlock(), createBlock(_sfc_main$18, {
577
+ key: 2,
578
+ label: text.value.values,
579
+ "label-hidden": "",
580
+ "search-source": stringSource.value,
581
+ "model-value": stringItems.value,
582
+ placeholder: text.value.addValuesPlaceholder,
583
+ disabled: __props.disabled,
584
+ creatable: stringCreatable.value,
585
+ "max-menu-items": __props.maxMenuItems,
586
+ "onUpdate:modelValue": commitStringList
587
+ }, null, 8, [
588
+ "label",
589
+ "search-source",
590
+ "model-value",
591
+ "placeholder",
592
+ "disabled",
593
+ "creatable",
594
+ "max-menu-items"
595
+ ])) : __props.operatorValue.type === "integer" || __props.operatorValue.type === "float" ? (openBlock(), createBlock(_sfc_main$14, {
596
+ key: 3,
597
+ label: text.value.value,
598
+ "is-label-hidden": "",
599
+ "model-value": numberValue.value,
600
+ placeholder: text.value.enterNumberPlaceholder,
601
+ disabled: __props.disabled,
602
+ min: __props.operatorValue.minValue,
603
+ max: __props.operatorValue.maxValue,
604
+ step: __props.operatorValue.type === "integer" ? 1 : void 0,
605
+ units: __props.operatorValue.units,
606
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = (value) => value != null && emit("change", {
607
+ type: __props.operatorValue.type === "integer" ? "integer" : "float",
608
+ value
609
+ }))
610
+ }, null, 8, [
611
+ "label",
612
+ "model-value",
613
+ "placeholder",
614
+ "disabled",
615
+ "min",
616
+ "max",
617
+ "step",
618
+ "units"
619
+ ])) : __props.operatorValue.type === "time" ? (openBlock(), createBlock(_sfc_main$17, {
620
+ key: 4,
621
+ label: text.value.time,
622
+ "is-label-hidden": "",
623
+ "model-value": timeValue.value,
624
+ min: __props.operatorValue.minValue,
625
+ max: __props.operatorValue.maxValue,
626
+ "is-disabled": __props.disabled,
627
+ "onUpdate:modelValue": onTime
628
+ }, null, 8, [
629
+ "label",
630
+ "model-value",
631
+ "min",
632
+ "max",
633
+ "is-disabled"
634
+ ])) : __props.operatorValue.type === "date_absolute" && dateOnly.value ? (openBlock(), createBlock(_sfc_main$9, {
635
+ key: 5,
636
+ label: text.value.date,
637
+ "is-label-hidden": "",
638
+ "model-value": absoluteDate.value,
639
+ "is-disabled": __props.disabled,
640
+ "onUpdate:modelValue": onAbsoluteDate
641
+ }, null, 8, [
642
+ "label",
643
+ "model-value",
644
+ "is-disabled"
645
+ ])) : __props.operatorValue.type === "date_absolute" ? (openBlock(), createBlock(_sfc_main$11, {
646
+ key: 6,
647
+ label: text.value.date,
648
+ "is-label-hidden": "",
649
+ "model-value": absoluteLocal.value,
650
+ "is-disabled": __props.disabled,
651
+ "onUpdate:modelValue": onAbsoluteDateTime
652
+ }, null, 8, [
653
+ "label",
654
+ "model-value",
655
+ "is-disabled"
656
+ ])) : __props.operatorValue.type === "date_relative" ? (openBlock(), createElementBlock("div", _hoisted_1$4, [relativeOptions.value.length > 0 ? (openBlock(), createBlock(_sfc_main$15, {
657
+ key: 0,
658
+ label: text.value.relativeDate,
659
+ "is-label-hidden": "",
660
+ options: relativeOptions.value,
661
+ "model-value": relativeValue.value,
662
+ placeholder: text.value.selectPlaceholder,
663
+ disabled: __props.disabled,
664
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = (value) => emit("change", {
665
+ type: "date_relative",
666
+ value: String(value ?? "")
667
+ }, true))
668
+ }, null, 8, [
669
+ "label",
670
+ "options",
671
+ "model-value",
672
+ "placeholder",
673
+ "disabled"
674
+ ])) : createCommentVNode("v-if", true), createVNode(_sfc_main$16, {
675
+ label: text.value.relativeDate,
676
+ "is-label-hidden": "",
677
+ "model-value": relativeValue.value,
678
+ placeholder: text.value.enterValuePlaceholder,
679
+ disabled: __props.disabled,
680
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = (value) => emit("change", {
681
+ type: "date_relative",
682
+ value: String(value ?? "")
683
+ }))
684
+ }, null, 8, [
685
+ "label",
686
+ "model-value",
687
+ "placeholder",
688
+ "disabled"
689
+ ])])) : __props.operatorValue.type === "date_range" ? (openBlock(), createElementBlock("div", _hoisted_2$3, [__props.operatorValue.intervalDatePresets?.length ? (openBlock(), createElementBlock("div", {
690
+ key: 0,
691
+ class: "astryx-power-search-presets",
692
+ role: "group",
693
+ "aria-label": text.value.date
694
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.operatorValue.intervalDatePresets, (preset) => {
695
+ return openBlock(), createElementBlock("button", {
696
+ key: preset.label,
697
+ type: "button",
698
+ class: "astryx-power-search-preset",
699
+ disabled: __props.disabled,
700
+ onClick: ($event) => applyPreset(preset.value)
701
+ }, toDisplayString(preset.label), 9, _hoisted_4$2);
702
+ }), 128))], 8, _hoisted_3$3)) : createCommentVNode("v-if", true), createVNode(_sfc_main$10, {
703
+ label: text.value.date,
704
+ "is-label-hidden": "",
705
+ "model-value": rangeModel.value,
706
+ "is-disabled": __props.disabled,
707
+ "onUpdate:modelValue": onRange
708
+ }, null, 8, [
709
+ "label",
710
+ "model-value",
711
+ "is-disabled"
712
+ ])])) : __props.operatorValue.type === "enum" ? (openBlock(), createBlock(_sfc_main$15, {
713
+ key: 9,
714
+ label: text.value.value,
715
+ "is-label-hidden": "",
716
+ options: enumOptions.value,
717
+ "model-value": enumValue.value,
718
+ placeholder: text.value.selectPlaceholder,
719
+ disabled: __props.disabled,
720
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = (value) => emit("change", {
721
+ type: "enum",
722
+ value: String(value ?? "")
723
+ }, true))
724
+ }, null, 8, [
725
+ "label",
726
+ "options",
727
+ "model-value",
728
+ "placeholder",
729
+ "disabled"
730
+ ])) : __props.operatorValue.type === "enum_list" ? (openBlock(), createBlock(_sfc_main$13, {
731
+ key: 10,
732
+ label: text.value.values,
733
+ "label-hidden": "",
734
+ options: enumOptions.value,
735
+ "model-value": enumList.value,
736
+ placeholder: text.value.selectValuesPlaceholder,
737
+ disabled: __props.disabled,
738
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = (value) => emit("change", {
739
+ type: "enum_list",
740
+ value: value.map(String)
741
+ }))
742
+ }, null, 8, [
743
+ "label",
744
+ "options",
745
+ "model-value",
746
+ "placeholder",
747
+ "disabled"
748
+ ])) : __props.operatorValue.type === "entity_list" ? (openBlock(), createBlock(_sfc_main$18, {
749
+ key: 11,
750
+ label: text.value.entities,
751
+ "label-hidden": "",
752
+ "search-source": entitySource.value,
753
+ "model-value": entityItems.value,
754
+ placeholder: text.value.searchPlaceholder,
755
+ disabled: __props.disabled,
756
+ creatable: stringCreatable.value,
757
+ "max-menu-items": __props.maxMenuItems,
758
+ "onUpdate:modelValue": commitEntities
759
+ }, null, 8, [
760
+ "label",
761
+ "search-source",
762
+ "model-value",
763
+ "placeholder",
764
+ "disabled",
765
+ "creatable",
766
+ "max-menu-items"
767
+ ])) : __props.operatorValue.type === "custom" ? (openBlock(), createBlock(resolveDynamicComponent(__props.operatorValue.Editor), {
768
+ key: 12,
769
+ "model-value": customValue.value,
770
+ value: customValue.value,
771
+ placeholder: text.value.enterValuePlaceholder,
772
+ disabled: __props.disabled,
773
+ "is-disabled": __props.disabled,
774
+ "onUpdate:modelValue": onCustomValue,
775
+ onChange: onCustomValue
776
+ }, null, 40, [
777
+ "model-value",
778
+ "value",
779
+ "placeholder",
780
+ "disabled",
781
+ "is-disabled"
782
+ ])) : createCommentVNode("v-if", true)], 32);
783
+ };
784
+ }
785
+ });
786
+ //#endregion
787
+ //#region src/PowerSearch/PowerSearchNestedRows.vue
788
+ const _hoisted_1$3 = { class: "astryx-power-search-nested" };
789
+ const _hoisted_2$2 = { class: "astryx-power-search-editor-row" };
790
+ const _hoisted_3$2 = ["aria-label", "onClick"];
791
+ const _sfc_main$3 = /*@__PURE__*/ defineComponent({
792
+ name: "AstryxPowerSearchNestedRows",
793
+ __name: "PowerSearchNestedRows",
794
+ props: {
795
+ config: {},
796
+ modelValue: {},
797
+ disabled: { type: Boolean },
798
+ timeZone: {},
799
+ maxMenuItems: {}
800
+ },
801
+ emits: ["update:modelValue"],
802
+ setup(__props, { emit: __emit }) {
803
+ const props = __props;
804
+ const emit = __emit;
805
+ const messages = useAstryxMessages();
806
+ const lookup = computed(() => createPowerSearchLookup(props.config));
807
+ const text = computed(() => messages.value.powerSearch);
808
+ const fieldOptions = computed(() => lookup.value.getVisibleFields().map((field) => ({
809
+ value: field.key,
810
+ label: field.label
811
+ })));
812
+ function operatorOptions(fieldKey) {
813
+ return lookup.value.getVisibleOperators(fieldKey).map((operator) => ({
814
+ value: operator.key,
815
+ label: resolveOperatorLabel(operator, messages.value.powerSearch)
816
+ }));
817
+ }
818
+ function operatorOf(row) {
819
+ if (row.operator == null) return void 0;
820
+ return lookup.value.getOperator(row.field, row.operator);
821
+ }
822
+ function replace(index, next) {
823
+ const rows = props.modelValue.map((row, rowIndex) => rowIndex === index ? next : row);
824
+ emit("update:modelValue", [...rows]);
825
+ }
826
+ function onField(index, fieldKey) {
827
+ const key = String(fieldKey ?? "");
828
+ if (key === "") return;
829
+ const operator = lookup.value.getDefaultOperator(key);
830
+ replace(index, {
831
+ field: key,
832
+ operator: operator?.key,
833
+ children: operator?.value.type === "nested" ? [] : void 0
834
+ });
835
+ }
836
+ function onOperator(index, row, operatorKey) {
837
+ const key = String(operatorKey ?? "");
838
+ const next = lookup.value.getOperator(row.field, key);
839
+ const previous = operatorOf(row);
840
+ const keep = next != null && previous != null && next.value.type === previous.value.type;
841
+ replace(index, {
842
+ field: row.field,
843
+ operator: key,
844
+ value: keep && next?.value.type !== "nested" ? row.value : void 0,
845
+ children: keep && next?.value.type === "nested" ? row.children ?? [] : next?.value.type === "nested" ? [] : void 0,
846
+ isReadOnly: row.isReadOnly
847
+ });
848
+ }
849
+ function onValue(index, row, value) {
850
+ replace(index, {
851
+ ...row,
852
+ value
853
+ });
854
+ }
855
+ function nestedRows(row) {
856
+ return [...row.children ?? []];
857
+ }
858
+ function onNested(index, row, rows) {
859
+ replace(index, {
860
+ ...row,
861
+ children: rows
862
+ });
863
+ }
864
+ function onNestedUpdate(index, row, rows) {
865
+ onNested(index, row, rows);
866
+ }
867
+ function add() {
868
+ const field = lookup.value.getVisibleFields()[0];
869
+ if (field == null) return;
870
+ const operator = lookup.value.getDefaultOperator(field.key);
871
+ emit("update:modelValue", [...props.modelValue, {
872
+ field: field.key,
873
+ operator: operator?.key,
874
+ children: operator?.value.type === "nested" ? [] : void 0
875
+ }]);
876
+ }
877
+ function remove(index) {
878
+ emit("update:modelValue", props.modelValue.filter((_, rowIndex) => rowIndex !== index));
879
+ }
880
+ return (_ctx, _cache) => {
881
+ const _component_PowerSearchNestedRows = resolveComponent("PowerSearchNestedRows", true);
882
+ return openBlock(), createElementBlock("div", _hoisted_1$3, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.modelValue, (row, index) => {
883
+ return openBlock(), createElementBlock("div", {
884
+ key: `${row.field}-${index}`,
885
+ class: "astryx-power-search-nested-row"
886
+ }, [createElementVNode("div", _hoisted_2$2, [
887
+ createVNode(_sfc_main$15, {
888
+ label: text.value.editor.field,
889
+ "is-label-hidden": "",
890
+ options: fieldOptions.value,
891
+ "model-value": row.field,
892
+ disabled: __props.disabled,
893
+ "onUpdate:modelValue": (value) => onField(index, value)
894
+ }, null, 8, [
895
+ "label",
896
+ "options",
897
+ "model-value",
898
+ "disabled",
899
+ "onUpdate:modelValue"
900
+ ]),
901
+ operatorOptions(row.field).length > 0 ? (openBlock(), createBlock(_sfc_main$15, {
902
+ key: 0,
903
+ label: text.value.editor.operator,
904
+ "is-label-hidden": "",
905
+ options: operatorOptions(row.field),
906
+ "model-value": row.operator ?? null,
907
+ disabled: __props.disabled,
908
+ "onUpdate:modelValue": (value) => onOperator(index, row, value)
909
+ }, null, 8, [
910
+ "label",
911
+ "options",
912
+ "model-value",
913
+ "disabled",
914
+ "onUpdate:modelValue"
915
+ ])) : createCommentVNode("v-if", true),
916
+ operatorOf(row) && operatorOf(row)?.value.type !== "empty" && operatorOf(row)?.value.type !== "nested" ? (openBlock(), createBlock(_sfc_main$4, {
917
+ key: `${row.field}:${row.operator ?? ""}`,
918
+ "operator-value": operatorOf(row).value,
919
+ "filter-value": row.value,
920
+ messages: unref(messages).powerSearch,
921
+ disabled: __props.disabled,
922
+ "time-zone": __props.timeZone,
923
+ "max-menu-items": __props.maxMenuItems,
924
+ onChange: (filterValue) => onValue(index, row, filterValue)
925
+ }, null, 8, [
926
+ "operator-value",
927
+ "filter-value",
928
+ "messages",
929
+ "disabled",
930
+ "time-zone",
931
+ "max-menu-items",
932
+ "onChange"
933
+ ])) : createCommentVNode("v-if", true),
934
+ !__props.disabled ? (openBlock(), createElementBlock("button", {
935
+ key: 2,
936
+ type: "button",
937
+ class: "astryx-power-search-icon-button",
938
+ "aria-label": text.value.editor.removeFilter,
939
+ onClick: ($event) => remove(index)
940
+ }, [createVNode(_sfc_main$7, {
941
+ icon: "close",
942
+ size: "sm"
943
+ })], 8, _hoisted_3$2)) : createCommentVNode("v-if", true)
944
+ ]), operatorOf(row)?.value.type === "nested" ? (openBlock(), createBlock(_component_PowerSearchNestedRows, {
945
+ key: 0,
946
+ config: __props.config,
947
+ "model-value": nestedRows(row),
948
+ disabled: __props.disabled,
949
+ "time-zone": __props.timeZone,
950
+ "max-menu-items": __props.maxMenuItems,
951
+ "onUpdate:modelValue": ($event) => onNestedUpdate(index, row, $event)
952
+ }, null, 8, [
953
+ "config",
954
+ "model-value",
955
+ "disabled",
956
+ "time-zone",
957
+ "max-menu-items",
958
+ "onUpdate:modelValue"
959
+ ])) : createCommentVNode("v-if", true)]);
960
+ }), 128)), !__props.disabled ? (openBlock(), createBlock(_sfc_main$5, {
961
+ key: 0,
962
+ label: text.value.editor.addFilter,
963
+ variant: "ghost",
964
+ size: "sm",
965
+ onClick: add
966
+ }, null, 8, ["label"])) : createCommentVNode("v-if", true)]);
967
+ };
968
+ }
969
+ });
970
+ //#endregion
971
+ //#region src/PowerSearch/PowerSearchEditor.vue
972
+ const _hoisted_1$2 = ["aria-label"];
973
+ const _hoisted_2$1 = { class: "astryx-power-search-editor-row" };
974
+ const _hoisted_3$1 = {
975
+ key: 0,
976
+ class: "astryx-power-search-editor-nested"
977
+ };
978
+ const _hoisted_4$1 = { class: "astryx-power-search-editor-group" };
979
+ const _hoisted_5$1 = {
980
+ key: 1,
981
+ class: "astryx-power-search-editor-footer"
982
+ };
983
+ const _hoisted_6$1 = { key: 1 };
984
+ const _hoisted_7$1 = { class: "astryx-power-search-editor-actions" };
985
+ const focusable = "input:not([disabled]), button:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
986
+ const _sfc_main$2 = /*@__PURE__*/ defineComponent({
987
+ name: "AstryxPowerSearchEditor",
988
+ __name: "PowerSearchEditor",
989
+ props: {
990
+ config: {},
991
+ filter: {},
992
+ mode: {},
993
+ saveLabel: {},
994
+ readOnly: { type: Boolean },
995
+ timeZone: {},
996
+ maxMenuItems: {},
997
+ onSave: { type: Function },
998
+ onCancel: { type: Function }
999
+ },
1000
+ setup(__props) {
1001
+ const props = __props;
1002
+ const messages = useAstryxMessages();
1003
+ const lookup = computed(() => createPowerSearchLookup(props.config));
1004
+ const text = computed(() => messages.value.powerSearch);
1005
+ const root = useTemplateRef("root");
1006
+ const valueRoot = useTemplateRef("valueRoot");
1007
+ const fieldKey = ref(props.filter.field);
1008
+ const operatorKey = ref(props.filter.operator ?? lookup.value.getDefaultOperator(props.filter.field)?.key ?? "");
1009
+ const draft = ref(props.filter.value?.type === "nested" ? void 0 : props.filter.value);
1010
+ const children = ref(props.filter.value?.type === "nested" ? [...props.filter.value.value] : []);
1011
+ const fieldOptions = computed(() => lookup.value.getVisibleFields().map((field) => ({
1012
+ value: field.key,
1013
+ label: field.label
1014
+ })));
1015
+ const operatorOptions = computed(() => lookup.value.getVisibleOperators(fieldKey.value).map((operator) => ({
1016
+ value: operator.key,
1017
+ label: resolveOperatorLabel(operator, messages.value.powerSearch)
1018
+ })));
1019
+ const operatorValue = computed(() => lookup.value.getOperator(fieldKey.value, operatorKey.value)?.value);
1020
+ const partial = computed(() => ({
1021
+ field: fieldKey.value,
1022
+ operator: operatorKey.value || void 0,
1023
+ value: operatorValue.value?.type === "nested" ? void 0 : draft.value,
1024
+ children: operatorValue.value?.type === "nested" ? children.value : void 0,
1025
+ isReadOnly: props.filter.isReadOnly
1026
+ }));
1027
+ const completed = computed(() => completePowerSearchFilter(partial.value, lookup.value));
1028
+ const showFooter = computed(() => operatorValue.value != null && operatorValue.value.type !== "empty");
1029
+ function focusWithin(element) {
1030
+ element?.querySelector(focusable)?.focus();
1031
+ }
1032
+ function saveIfEmpty(field, operatorKeyValue) {
1033
+ const operator = operatorKeyValue ? lookup.value.getOperator(field, operatorKeyValue) : void 0;
1034
+ if (operator?.value.type !== "empty") return;
1035
+ queueMicrotask(() => {
1036
+ props.onSave({
1037
+ field,
1038
+ operator: operator.key,
1039
+ value: { type: "empty" },
1040
+ isReadOnly: props.filter.isReadOnly
1041
+ });
1042
+ });
1043
+ }
1044
+ function onField(next) {
1045
+ const key = String(next ?? "");
1046
+ if (key === "" || key === fieldKey.value) return;
1047
+ const operator = lookup.value.getDefaultOperator(key);
1048
+ fieldKey.value = key;
1049
+ operatorKey.value = operator?.key ?? "";
1050
+ children.value = [];
1051
+ draft.value = void 0;
1052
+ saveIfEmpty(key, operator?.key);
1053
+ }
1054
+ function onOperator(next) {
1055
+ const key = String(next ?? "");
1056
+ if (key === "" || key === operatorKey.value) return;
1057
+ const nextOperator = lookup.value.getOperator(fieldKey.value, key);
1058
+ const previous = lookup.value.getOperator(fieldKey.value, operatorKey.value);
1059
+ const keep = nextOperator != null && previous != null && nextOperator.value.type === previous.value.type;
1060
+ operatorKey.value = key;
1061
+ if (!keep) {
1062
+ children.value = [];
1063
+ draft.value = void 0;
1064
+ }
1065
+ saveIfEmpty(fieldKey.value, key);
1066
+ }
1067
+ function onValue(value, shouldSave) {
1068
+ draft.value = value;
1069
+ if (shouldSave) save();
1070
+ }
1071
+ function save() {
1072
+ const filter = completePowerSearchFilter({
1073
+ field: fieldKey.value,
1074
+ operator: operatorKey.value,
1075
+ value: draft.value,
1076
+ isReadOnly: props.filter.isReadOnly
1077
+ }, lookup.value);
1078
+ if (filter) props.onSave(filter);
1079
+ }
1080
+ function onKeydown(event) {
1081
+ if (event.isComposing || event.key === "Process") return;
1082
+ if (event.key === "Escape" && !event.defaultPrevented) {
1083
+ event.preventDefault();
1084
+ props.onCancel();
1085
+ return;
1086
+ }
1087
+ if (event.key === "Enter" && event.target instanceof HTMLButtonElement) return;
1088
+ if (event.key === "Enter" && completed.value && !event.defaultPrevented) {
1089
+ event.preventDefault();
1090
+ save();
1091
+ }
1092
+ }
1093
+ watch([fieldKey, operatorKey], () => {
1094
+ nextTick(() => {
1095
+ requestAnimationFrame(() => focusWithin(valueRoot.value));
1096
+ });
1097
+ });
1098
+ onMounted(() => {
1099
+ nextTick(() => {
1100
+ requestAnimationFrame(() => focusWithin(valueRoot.value ?? root.value));
1101
+ });
1102
+ });
1103
+ return (_ctx, _cache) => {
1104
+ return openBlock(), createElementBlock(Fragment, null, [createCommentVNode(" eslint-disable-next-line vue-a11y/no-static-element-interactions -- 编辑器整组接收 Enter 和 Escape。 "), createElementVNode("div", {
1105
+ ref_key: "root",
1106
+ ref: root,
1107
+ class: "astryx-power-search-editor-body",
1108
+ role: "group",
1109
+ "aria-label": text.value.editor.editing,
1110
+ tabindex: "-1",
1111
+ onKeydown
1112
+ }, [
1113
+ createElementVNode("div", _hoisted_2$1, [
1114
+ createVNode(_sfc_main$15, {
1115
+ label: text.value.editor.field,
1116
+ "is-label-hidden": "",
1117
+ options: fieldOptions.value,
1118
+ "model-value": fieldKey.value,
1119
+ disabled: __props.readOnly,
1120
+ "onUpdate:modelValue": onField
1121
+ }, null, 8, [
1122
+ "label",
1123
+ "options",
1124
+ "model-value",
1125
+ "disabled"
1126
+ ]),
1127
+ operatorOptions.value.length > 1 || operatorValue.value?.type !== "empty" ? (openBlock(), createBlock(_sfc_main$15, {
1128
+ key: 0,
1129
+ label: text.value.editor.operator,
1130
+ "is-label-hidden": "",
1131
+ options: operatorOptions.value,
1132
+ "model-value": operatorKey.value || null,
1133
+ disabled: __props.readOnly,
1134
+ "onUpdate:modelValue": onOperator
1135
+ }, null, 8, [
1136
+ "label",
1137
+ "options",
1138
+ "model-value",
1139
+ "disabled"
1140
+ ])) : createCommentVNode("v-if", true),
1141
+ operatorValue.value && operatorValue.value.type !== "empty" && operatorValue.value.type !== "nested" ? (openBlock(), createElementBlock("div", {
1142
+ key: 1,
1143
+ ref_key: "valueRoot",
1144
+ ref: valueRoot,
1145
+ class: "astryx-power-search-editor-value"
1146
+ }, [(openBlock(), createBlock(_sfc_main$4, {
1147
+ key: `${fieldKey.value}:${operatorKey.value}`,
1148
+ "operator-value": operatorValue.value,
1149
+ "filter-value": draft.value,
1150
+ messages: unref(messages).powerSearch,
1151
+ disabled: __props.readOnly,
1152
+ "time-zone": __props.timeZone,
1153
+ "max-menu-items": __props.maxMenuItems,
1154
+ onChange: onValue
1155
+ }, null, 8, [
1156
+ "operator-value",
1157
+ "filter-value",
1158
+ "messages",
1159
+ "disabled",
1160
+ "time-zone",
1161
+ "max-menu-items"
1162
+ ]))], 512)) : createCommentVNode("v-if", true)
1163
+ ]),
1164
+ operatorValue.value?.type === "nested" ? (openBlock(), createElementBlock("div", _hoisted_3$1, [createElementVNode("div", _hoisted_4$1, toDisplayString(text.value.editor.group), 1), createVNode(_sfc_main$3, {
1165
+ config: __props.config,
1166
+ "model-value": children.value,
1167
+ disabled: __props.readOnly,
1168
+ "time-zone": __props.timeZone,
1169
+ "max-menu-items": __props.maxMenuItems,
1170
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = (rows) => children.value = rows)
1171
+ }, null, 8, [
1172
+ "config",
1173
+ "model-value",
1174
+ "disabled",
1175
+ "time-zone",
1176
+ "max-menu-items"
1177
+ ])])) : createCommentVNode("v-if", true),
1178
+ showFooter.value ? (openBlock(), createElementBlock("div", _hoisted_5$1, [__props.mode === "edit" && !__props.readOnly ? (openBlock(), createBlock(_sfc_main$5, {
1179
+ key: 0,
1180
+ label: text.value.editor.delete,
1181
+ variant: "ghost",
1182
+ size: "sm",
1183
+ onClick: _cache[1] || (_cache[1] = ($event) => __props.onSave(null))
1184
+ }, null, 8, ["label"])) : (openBlock(), createElementBlock("span", _hoisted_6$1)), createElementVNode("div", _hoisted_7$1, [createVNode(_sfc_main$5, {
1185
+ label: text.value.editor.cancel,
1186
+ variant: "ghost",
1187
+ size: "sm",
1188
+ onClick: __props.onCancel
1189
+ }, null, 8, ["label", "onClick"]), createVNode(_sfc_main$5, {
1190
+ label: __props.saveLabel || text.value.editor.apply,
1191
+ variant: "primary",
1192
+ size: "sm",
1193
+ "is-disabled": completed.value == null,
1194
+ onClick: save
1195
+ }, null, 8, ["label", "is-disabled"])])])) : createCommentVNode("v-if", true)
1196
+ ], 40, _hoisted_1$2)], 2112);
1197
+ };
1198
+ }
1199
+ });
1200
+ //#endregion
1201
+ //#region src/PowerSearch/PowerSearchToken.vue
1202
+ const _hoisted_1$1 = { class: "astryx-power-search-token-value" };
1203
+ const _sfc_main$1 = /*@__PURE__*/ defineComponent({
1204
+ name: "AstryxPowerSearchToken",
1205
+ __name: "PowerSearchToken",
1206
+ props: {
1207
+ fieldLabel: {},
1208
+ operator: {},
1209
+ filter: {},
1210
+ maxLength: {},
1211
+ messages: {},
1212
+ locale: {},
1213
+ timeZone: {},
1214
+ size: {},
1215
+ disabled: { type: Boolean },
1216
+ removable: { type: Boolean }
1217
+ },
1218
+ emits: ["activate", "remove"],
1219
+ setup(__props, { emit: __emit }) {
1220
+ const props = __props;
1221
+ const emit = __emit;
1222
+ const operatorLabel = computed(() => resolveOperatorLabel(props.operator, props.messages));
1223
+ const tokenLabel = computed(() => `${props.fieldLabel}: ${operatorLabel.value}`);
1224
+ const valueText = computed(() => {
1225
+ const room = Math.max(props.maxLength - props.fieldLabel.length - operatorLabel.value.length, 10);
1226
+ return formatFilterValue(props.operator.value, props.filter.value, room, props.messages, props.locale, props.timeZone);
1227
+ });
1228
+ return (_ctx, _cache) => {
1229
+ return openBlock(), createBlock(_sfc_main$12, {
1230
+ label: tokenLabel.value,
1231
+ size: __props.size,
1232
+ disabled: __props.disabled,
1233
+ removable: __props.removable,
1234
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("activate")),
1235
+ onRemove: _cache[1] || (_cache[1] = ($event) => emit("remove"))
1236
+ }, createSlots({ _: 2 }, [valueText.value ? {
1237
+ name: "end",
1238
+ fn: withCtx(() => [createElementVNode("span", _hoisted_1$1, toDisplayString(valueText.value), 1)]),
1239
+ key: "0"
1240
+ } : void 0]), 1032, [
1241
+ "label",
1242
+ "size",
1243
+ "disabled",
1244
+ "removable"
1245
+ ]);
1246
+ };
1247
+ }
1248
+ });
1249
+ //#endregion
1250
+ //#region src/PowerSearch/source.ts
1251
+ const MAX_BROWSE_ITEMS = 1e3;
1252
+ function resolveValueMatches(operator, rawValue) {
1253
+ const kind = operator.value.type;
1254
+ if (kind === "string") return [{
1255
+ displayValue: rawValue,
1256
+ filterValue: {
1257
+ type: "string",
1258
+ value: rawValue
1259
+ },
1260
+ quoted: true
1261
+ }];
1262
+ if (kind === "string_list") return [{
1263
+ displayValue: rawValue,
1264
+ filterValue: {
1265
+ type: "string_list",
1266
+ value: [rawValue]
1267
+ },
1268
+ quoted: true
1269
+ }];
1270
+ if (kind === "enum" || kind === "enum_list") {
1271
+ const lower = rawValue.toLowerCase();
1272
+ return operator.value.values.filter((item) => item.label.toLowerCase().includes(lower)).map((item) => ({
1273
+ displayValue: item.label,
1274
+ filterValue: kind === "enum" ? {
1275
+ type: "enum",
1276
+ value: item.value
1277
+ } : {
1278
+ type: "enum_list",
1279
+ value: [item.value]
1280
+ },
1281
+ quoted: false
1282
+ }));
1283
+ }
1284
+ return [];
1285
+ }
1286
+ function browseItems(lookup) {
1287
+ const grouped = /* @__PURE__ */ new Map();
1288
+ const ungrouped = [];
1289
+ for (const field of lookup.getVisibleFields()) {
1290
+ const operator = lookup.getDefaultOperator(field.key);
1291
+ const item = {
1292
+ id: field.key,
1293
+ label: field.label,
1294
+ description: field.description,
1295
+ auxiliaryData: {
1296
+ fieldKey: field.key,
1297
+ operatorKey: operator?.key,
1298
+ group: field.group
1299
+ }
1300
+ };
1301
+ if (field.group) {
1302
+ const bucket = grouped.get(field.group) ?? [];
1303
+ bucket.push(item);
1304
+ grouped.set(field.group, bucket);
1305
+ } else ungrouped.push(item);
1306
+ }
1307
+ const ordered = [...ungrouped];
1308
+ for (const items of grouped.values()) ordered.push(...items);
1309
+ return ordered.slice(0, MAX_BROWSE_ITEMS);
1310
+ }
1311
+ function searchPowerSearchFields(lookup, query, messages, maxTypedResults) {
1312
+ const trimmed = query.trim();
1313
+ if (trimmed === "") return browseItems(lookup);
1314
+ const lower = trimmed.toLowerCase();
1315
+ const results = [];
1316
+ const seen = /* @__PURE__ */ new Set();
1317
+ const labelOf = (operator) => resolveOperatorLabel(operator, messages);
1318
+ for (const field of lookup.getVisibleFields()) {
1319
+ if (field.typeaheadMinQueryLength != null && lower.length < field.typeaheadMinQueryLength) continue;
1320
+ if ((field.label.toLowerCase().includes(lower) || field.typeaheadAliases?.some((alias) => alias.toLowerCase().includes(lower)) === true) && !seen.has(field.key)) {
1321
+ seen.add(field.key);
1322
+ const operator = lookup.getDefaultOperator(field.key);
1323
+ results.push({
1324
+ id: field.key,
1325
+ label: field.label,
1326
+ description: field.description,
1327
+ auxiliaryData: {
1328
+ fieldKey: field.key,
1329
+ operatorKey: operator?.key,
1330
+ group: field.group
1331
+ }
1332
+ });
1333
+ }
1334
+ for (const operator of field.operators) {
1335
+ const combined = `${field.label} ${labelOf(operator)}`.toLowerCase();
1336
+ const id = `${field.key}:${operator.key}`;
1337
+ if (combined.includes(lower) && !seen.has(id)) {
1338
+ seen.add(id);
1339
+ results.push({
1340
+ id,
1341
+ label: `${field.label} ${labelOf(operator)}`,
1342
+ description: field.description,
1343
+ auxiliaryData: {
1344
+ fieldKey: field.key,
1345
+ operatorKey: operator.key,
1346
+ group: field.group
1347
+ }
1348
+ });
1349
+ }
1350
+ }
1351
+ }
1352
+ for (const field of lookup.getVisibleFields()) {
1353
+ if (field.isValueMatchAllowed === false) continue;
1354
+ const fieldLabel = field.label.toLowerCase();
1355
+ let exactOperator = false;
1356
+ for (const operator of field.operators) {
1357
+ const prefix = `${fieldLabel} ${labelOf(operator).toLowerCase()} `;
1358
+ if (!lower.startsWith(prefix) || lower.length <= prefix.length) continue;
1359
+ const matches = resolveValueMatches(operator, trimmed.slice(prefix.length));
1360
+ if (matches.length > 0) exactOperator = true;
1361
+ for (const match of matches) {
1362
+ const id = `${field.key}:${operator.key}:value:${match.displayValue}`;
1363
+ if (seen.has(id)) continue;
1364
+ seen.add(id);
1365
+ const shown = match.quoted ? `"${match.displayValue}"` : match.displayValue;
1366
+ results.push({
1367
+ id,
1368
+ label: `${field.label} ${labelOf(operator)} ${shown}`,
1369
+ auxiliaryData: {
1370
+ fieldKey: field.key,
1371
+ operatorKey: operator.key,
1372
+ filterValue: match.filterValue
1373
+ }
1374
+ });
1375
+ }
1376
+ }
1377
+ const fieldPrefix = `${fieldLabel} `;
1378
+ if (!exactOperator && lower.startsWith(fieldPrefix) && lower.length > fieldPrefix.length) {
1379
+ const remainder = lower.slice(fieldPrefix.length);
1380
+ if (!field.operators.some((operator) => labelOf(operator).toLowerCase().startsWith(remainder))) {
1381
+ const rawValue = trimmed.slice(fieldPrefix.length);
1382
+ for (const operator of field.operators) for (const match of resolveValueMatches(operator, rawValue)) {
1383
+ const id = `${field.key}:${operator.key}:value:${match.displayValue}`;
1384
+ if (seen.has(id)) continue;
1385
+ seen.add(id);
1386
+ const shown = match.quoted ? `"${match.displayValue}"` : match.displayValue;
1387
+ results.push({
1388
+ id,
1389
+ label: `${field.label} ${labelOf(operator)} ${shown}`,
1390
+ auxiliaryData: {
1391
+ fieldKey: field.key,
1392
+ operatorKey: operator.key,
1393
+ filterValue: match.filterValue
1394
+ }
1395
+ });
1396
+ }
1397
+ }
1398
+ }
1399
+ }
1400
+ const contentKey = lookup.config.contentSearchFieldKey;
1401
+ const exact = lookup.getVisibleFields().some((field) => field.label.toLowerCase() === lower || field.operators.some((operator) => `${field.label} ${labelOf(operator)}`.toLowerCase() === lower));
1402
+ if (contentKey && !exact) {
1403
+ const field = lookup.getField(contentKey);
1404
+ const operator = lookup.getDefaultOperator(contentKey);
1405
+ if (field && operator) results.unshift({
1406
+ id: `__content_search__:${trimmed}`,
1407
+ label: `"${trimmed}"`,
1408
+ auxiliaryData: {
1409
+ fieldKey: contentKey,
1410
+ operatorKey: operator.key,
1411
+ filterValue: {
1412
+ type: "string",
1413
+ value: trimmed
1414
+ }
1415
+ }
1416
+ });
1417
+ }
1418
+ return results.slice(0, maxTypedResults);
1419
+ }
1420
+ //#endregion
1421
+ //#region src/PowerSearch/PowerSearch.vue
1422
+ const _hoisted_1 = {
1423
+ key: 0,
1424
+ class: "astryx-power-search-icon",
1425
+ "aria-hidden": "true"
1426
+ };
1427
+ const _hoisted_2 = ["onKeydown"];
1428
+ const _hoisted_3 = {
1429
+ key: 0,
1430
+ class: "astryx-power-search-more"
1431
+ };
1432
+ const _hoisted_4 = {
1433
+ "data-overflow-indicator": "",
1434
+ class: "astryx-power-search-more"
1435
+ };
1436
+ const _hoisted_5 = [
1437
+ "placeholder",
1438
+ "value",
1439
+ "disabled",
1440
+ "readonly",
1441
+ "aria-disabled",
1442
+ "aria-expanded",
1443
+ "aria-activedescendant",
1444
+ "aria-describedby"
1445
+ ];
1446
+ const _hoisted_6 = {
1447
+ key: 1,
1448
+ class: "astryx-power-search-count"
1449
+ };
1450
+ const _hoisted_7 = ["aria-label"];
1451
+ const _hoisted_8 = {
1452
+ class: "astryx-visually-hidden",
1453
+ "aria-live": "polite"
1454
+ };
1455
+ const _hoisted_9 = ["aria-label", "data-placement"];
1456
+ const _hoisted_10 = {
1457
+ class: "astryx-typeahead-menu",
1458
+ role: "presentation"
1459
+ };
1460
+ const _hoisted_11 = {
1461
+ key: 0,
1462
+ class: "astryx-typeahead-state"
1463
+ };
1464
+ const _hoisted_12 = {
1465
+ key: 1,
1466
+ class: "astryx-typeahead-options",
1467
+ role: "presentation"
1468
+ };
1469
+ const _hoisted_13 = {
1470
+ key: 0,
1471
+ class: "astryx-power-search-menu-group"
1472
+ };
1473
+ const _hoisted_14 = [
1474
+ "id",
1475
+ "aria-selected",
1476
+ "data-option-id",
1477
+ "onMouseenter",
1478
+ "onClick"
1479
+ ];
1480
+ const _hoisted_15 = { class: "astryx-typeahead-option-copy" };
1481
+ const _hoisted_16 = { class: "astryx-typeahead-option-label" };
1482
+ const _hoisted_17 = {
1483
+ key: 0,
1484
+ class: "astryx-typeahead-option-description"
1485
+ };
1486
+ const _hoisted_18 = ["data-ready"];
1487
+ const _sfc_main = /*@__PURE__*/ defineComponent({
1488
+ name: "AstryxPowerSearch",
1489
+ inheritAttrs: false,
1490
+ __name: "PowerSearch",
1491
+ props: {
1492
+ config: {},
1493
+ filters: {},
1494
+ label: {},
1495
+ labelHidden: {
1496
+ type: Boolean,
1497
+ default: true
1498
+ },
1499
+ placeholder: {},
1500
+ autofocus: { type: Boolean },
1501
+ clearable: {
1502
+ type: Boolean,
1503
+ default: true
1504
+ },
1505
+ readOnly: {
1506
+ type: Boolean,
1507
+ default: false
1508
+ },
1509
+ disabled: {
1510
+ type: Boolean,
1511
+ default: false
1512
+ },
1513
+ disabledReason: {},
1514
+ status: { default: "default" },
1515
+ statusMessage: {},
1516
+ statusVariant: { default: "attached" },
1517
+ maxTokenLength: { default: 40 },
1518
+ maxOperatorMenuItems: {},
1519
+ maxSearchResults: { default: 10 },
1520
+ menuWidth: {},
1521
+ saveLabel: {},
1522
+ timeZone: {},
1523
+ overflow: { default: "none" },
1524
+ resultCount: {},
1525
+ size: { default: "md" },
1526
+ components: {}
1527
+ },
1528
+ emits: [
1529
+ "update:filters",
1530
+ "change",
1531
+ "focus",
1532
+ "blur"
1533
+ ],
1534
+ setup(__props, { expose: __expose, emit: __emit }) {
1535
+ const props = __props;
1536
+ const emit = __emit;
1537
+ const slots = useSlots();
1538
+ const messages = useAstryxMessages();
1539
+ const locale = useAstryxLocale();
1540
+ const announce = useAnnounce();
1541
+ const inputId = `astryx-power-search-${useId()}`;
1542
+ const listboxId = `${inputId}-listbox`;
1543
+ const disabledId = `${inputId}-disabled`;
1544
+ const internal = ref([]);
1545
+ const filters = computed(() => props.filters ?? internal.value);
1546
+ const focused = ref(false);
1547
+ const placeholderHeight = ref(0);
1548
+ const queryMirror = ref("");
1549
+ const anchorRef = useTemplateRef("anchorRef");
1550
+ const listboxRef = useTemplateRef("listboxRef");
1551
+ const inputRef = useTemplateRef("inputRef");
1552
+ const editorRef = useTemplateRef("editorRef");
1553
+ const tokenEls = /* @__PURE__ */ new Map();
1554
+ const session = ref(null);
1555
+ const openingControl = ref(null);
1556
+ const editorOpen = computed(() => session.value != null);
1557
+ const sawCount = ref(false);
1558
+ const liveText = ref("");
1559
+ const text = computed(() => messages.value.powerSearch);
1560
+ const label = computed(() => props.label ?? text.value.label);
1561
+ const placeholder = computed(() => props.placeholder ?? text.value.placeholder);
1562
+ const focusableDisabled = computed(() => props.disabled && Boolean(props.disabledReason?.trim()));
1563
+ const collapsed = computed(() => props.overflow !== "none" && !focused.value);
1564
+ const floating = computed(() => props.overflow === "unfocused-layer" && focused.value);
1565
+ const lookup = computed(() => createPowerSearchLookup(props.config));
1566
+ const fieldStatus = computed(() => {
1567
+ if (!props.statusMessage || props.status === "default") return void 0;
1568
+ return {
1569
+ type: props.status,
1570
+ message: props.statusMessage
1571
+ };
1572
+ });
1573
+ const describedBy = computed(() => {
1574
+ return [focusableDisabled.value ? disabledId : void 0, props.statusMessage ? `${inputId}-status` : void 0].filter(Boolean).join(" ") || void 0;
1575
+ });
1576
+ const source = computed(() => ({ search(query) {
1577
+ const limit = query.trim() === "" ? 1e3 : props.maxSearchResults;
1578
+ return searchPowerSearchFields(lookup.value, query, text.value, limit);
1579
+ } }));
1580
+ const menu = useTypeaheadMenu({
1581
+ source: () => source.value,
1582
+ debounceMs: 0,
1583
+ showOnFocus: () => !props.readOnly,
1584
+ maxItems: () => queryMirror.value.trim() === "" ? 1e3 : props.maxSearchResults,
1585
+ disabled: () => props.disabled || props.readOnly || session.value != null,
1586
+ onSelect: (entry) => pick(entry.item),
1587
+ onQueryChange: (query) => {
1588
+ queryMirror.value = query;
1589
+ }
1590
+ });
1591
+ const anchored = useAnchoredListbox({
1592
+ anchor: anchorRef,
1593
+ layer: listboxRef,
1594
+ isOpen: menu.combobox.isOpen,
1595
+ onDismiss: () => menu.close()
1596
+ });
1597
+ useDismiss({
1598
+ container: editorRef,
1599
+ trigger: openingControl,
1600
+ isEnabled: editorOpen,
1601
+ enableEscape: ref(false),
1602
+ onDismiss: () => closeEditor(true)
1603
+ });
1604
+ const tokenCount = computed(() => filters.value.length);
1605
+ const overflowState = useOverflow(tokenCount, { gap: 4 });
1606
+ const visibleCount = computed(() => collapsed.value ? overflowState.visibleCount.value : tokenCount.value);
1607
+ const hiddenCount = computed(() => Math.max(0, tokenCount.value - visibleCount.value));
1608
+ const visibleFilters = computed(() => filters.value.slice(0, visibleCount.value));
1609
+ const displayCount = computed(() => {
1610
+ if (props.resultCount == null) return "";
1611
+ return typeof props.resultCount === "number" ? text.value.resultCount(props.resultCount) : props.resultCount;
1612
+ });
1613
+ const menuStyle = computed(() => {
1614
+ const base = anchored.style.value;
1615
+ if (props.menuWidth == null) return base;
1616
+ const width = `${props.menuWidth}px`;
1617
+ return {
1618
+ ...base,
1619
+ width,
1620
+ minWidth: width,
1621
+ maxWidth: width
1622
+ };
1623
+ });
1624
+ const editorStyle = computed(() => {
1625
+ const place = session.value?.placement;
1626
+ if (place == null) return void 0;
1627
+ return {
1628
+ top: `${place.top}px`,
1629
+ left: `${place.left}px`,
1630
+ width: `${place.width}px`
1631
+ };
1632
+ });
1633
+ const editorComponent = computed(() => {
1634
+ const filter = session.value?.filter;
1635
+ if (filter?.operator == null) return _sfc_main$2;
1636
+ const type = lookup.value.getOperator(filter.field, filter.operator)?.value.type;
1637
+ return (type ? props.components?.[type]?.editor : void 0) ?? _sfc_main$2;
1638
+ });
1639
+ watch(collapsed, () => {
1640
+ nextTick(() => overflowState.remeasure());
1641
+ });
1642
+ watch(() => menu.combobox.activeIndex.value, (index) => {
1643
+ if (!menu.combobox.isOpen.value || index < 0) return;
1644
+ nextTick(() => scrollOptionIntoView(listboxRef.value, menu.entries.value[index]?.id));
1645
+ });
1646
+ watch(() => props.resultCount, (value) => {
1647
+ if (!sawCount.value) {
1648
+ sawCount.value = true;
1649
+ return;
1650
+ }
1651
+ if (typeof value === "number") liveText.value = text.value.resultCount(value);
1652
+ else if (typeof value === "string") liveText.value = value;
1653
+ }, { immediate: true });
1654
+ function commit(next, changeType, index) {
1655
+ internal.value = next;
1656
+ emit("update:filters", next);
1657
+ emit("change", next, changeType, index);
1658
+ }
1659
+ function operatorFor(filter) {
1660
+ return lookup.value.getOperator(filter.field, filter.operator);
1661
+ }
1662
+ function fieldFor(filter) {
1663
+ return lookup.value.getField(filter.field);
1664
+ }
1665
+ function canEdit(filter) {
1666
+ if (props.disabled || props.readOnly || filter.isReadOnly) return false;
1667
+ const operator = operatorFor(filter);
1668
+ if (operator == null) return false;
1669
+ if (operator.value.type !== "empty") return true;
1670
+ return Boolean(props.components?.empty?.editor || slots.editor);
1671
+ }
1672
+ function canRemove(filter) {
1673
+ return !props.disabled && !props.readOnly && filter.isReadOnly !== true;
1674
+ }
1675
+ function tokenComponent(filter) {
1676
+ const type = operatorFor(filter)?.value.type;
1677
+ return type ? props.components?.[type]?.token : void 0;
1678
+ }
1679
+ function measure(control) {
1680
+ const outer = anchorRef.value;
1681
+ if (outer == null) return null;
1682
+ const target = control ?? outer;
1683
+ const outerRect = outer.getBoundingClientRect();
1684
+ const controlRect = target.getBoundingClientRect();
1685
+ return resolveEditorPlacement({
1686
+ outer: {
1687
+ left: outerRect.left,
1688
+ right: outerRect.right,
1689
+ width: outerRect.width
1690
+ },
1691
+ control: {
1692
+ left: controlRect.left,
1693
+ right: controlRect.right,
1694
+ width: controlRect.width
1695
+ },
1696
+ viewportWidth: window.innerWidth,
1697
+ viewportHeight: window.innerHeight,
1698
+ direction: getComputedStyle(outer).direction === "rtl" ? "rtl" : "ltr",
1699
+ anchorTop: controlRect.top,
1700
+ anchorBottom: controlRect.bottom
1701
+ });
1702
+ }
1703
+ function openEditor(mode, filter, index, control) {
1704
+ const placement = measure(control);
1705
+ if (placement == null) return;
1706
+ menu.close();
1707
+ openingControl.value = control;
1708
+ session.value = {
1709
+ mode,
1710
+ index,
1711
+ filter,
1712
+ placement,
1713
+ ready: false,
1714
+ control
1715
+ };
1716
+ nextTick(() => {
1717
+ requestAnimationFrame(() => {
1718
+ if (session.value) session.value = {
1719
+ ...session.value,
1720
+ ready: true
1721
+ };
1722
+ });
1723
+ });
1724
+ }
1725
+ function closeEditor(restore) {
1726
+ const control = session.value?.control;
1727
+ session.value = null;
1728
+ openingControl.value = null;
1729
+ if (!restore) return;
1730
+ nextTick(() => {
1731
+ if (control instanceof HTMLElement) control.focus();
1732
+ else inputRef.value?.focus();
1733
+ });
1734
+ }
1735
+ function pick(item) {
1736
+ const data = item.auxiliaryData;
1737
+ if (data == null) return;
1738
+ const field = lookup.value.getField(data.fieldKey);
1739
+ const operator = (data.operatorKey ? lookup.value.getOperator(data.fieldKey, data.operatorKey) : void 0) ?? lookup.value.getDefaultOperator(data.fieldKey);
1740
+ if (field == null || operator == null) return;
1741
+ menu.query.value = "";
1742
+ menu.close();
1743
+ if (data.filterValue != null || operator.value.type === "empty") {
1744
+ const value = data.filterValue ?? { type: "empty" };
1745
+ const next = [...filters.value, {
1746
+ field: field.key,
1747
+ operator: operator.key,
1748
+ value
1749
+ }];
1750
+ commit(next, "add", next.length - 1);
1751
+ announce(`${field.label}: ${operator.key}`);
1752
+ nextTick(() => inputRef.value?.focus());
1753
+ return;
1754
+ }
1755
+ openEditor("create", {
1756
+ field: field.key,
1757
+ operator: operator.key
1758
+ }, filters.value.length, inputRef.value);
1759
+ }
1760
+ function onEditorSave(filter) {
1761
+ const current = session.value;
1762
+ if (current == null) return;
1763
+ if (filter == null) {
1764
+ if (current.mode === "edit") {
1765
+ const removed = filters.value[current.index];
1766
+ commit(filters.value.filter((_, index) => index !== current.index), "remove", current.index);
1767
+ announce(text.value.removeFilter(removed ? fieldFor(removed)?.label ?? removed.field : ""));
1768
+ }
1769
+ closeEditor(false);
1770
+ nextTick(() => inputRef.value?.focus());
1771
+ return;
1772
+ }
1773
+ if (current.mode === "edit") commit(filters.value.map((item, index) => index === current.index ? filter : item), "edit", current.index);
1774
+ else {
1775
+ const next = [...filters.value, filter];
1776
+ commit(next, "add", next.length - 1);
1777
+ }
1778
+ const field = lookup.value.getField(filter.field);
1779
+ announce(field?.label ?? filter.field);
1780
+ closeEditor(false);
1781
+ nextTick(() => inputRef.value?.focus());
1782
+ }
1783
+ function removeAt(index) {
1784
+ const filter = filters.value[index];
1785
+ if (filter == null || !canRemove(filter)) return;
1786
+ commit(filters.value.filter((_, itemIndex) => itemIndex !== index), "remove", index);
1787
+ announce(text.value.removeFilter(fieldFor(filter)?.label ?? filter.field));
1788
+ nextTick(() => inputRef.value?.focus());
1789
+ }
1790
+ function clearAll(event) {
1791
+ event?.stopPropagation();
1792
+ if (props.disabled || filters.value.length === 0) return;
1793
+ commit([], "remove", 0);
1794
+ announce(text.value.clear);
1795
+ menu.close();
1796
+ inputRef.value?.focus();
1797
+ }
1798
+ function activate(index) {
1799
+ const filter = filters.value[index];
1800
+ if (filter == null || !canEdit(filter)) return;
1801
+ openEditor("edit", filter, index, tokenEls.get(index) ?? null);
1802
+ }
1803
+ function setTokenEl(index, element) {
1804
+ if (element instanceof HTMLElement) tokenEls.set(index, element);
1805
+ else tokenEls.delete(index);
1806
+ }
1807
+ function focusToken(index) {
1808
+ nextTick(() => tokenEls.get(index)?.focus());
1809
+ }
1810
+ function onInput(event) {
1811
+ if (props.disabled || props.readOnly) return;
1812
+ menu.setQuery(event.target.value);
1813
+ }
1814
+ function onInputFocus(event) {
1815
+ emit("focus", event);
1816
+ if (!props.disabled && !props.readOnly && session.value == null) menu.open();
1817
+ }
1818
+ function onFocusIn() {
1819
+ if (!focused.value && props.overflow === "unfocused-layer") placeholderHeight.value = anchorRef.value?.offsetHeight ?? 0;
1820
+ focused.value = true;
1821
+ }
1822
+ function onFocusOut(event) {
1823
+ const next = event.relatedTarget;
1824
+ if (next instanceof Node && (anchorRef.value?.contains(next) || listboxRef.value?.contains(next) || editorRef.value?.contains(next))) return;
1825
+ focused.value = false;
1826
+ if (session.value == null) menu.close();
1827
+ }
1828
+ function onInputKeyDown(event) {
1829
+ if (session.value != null) return;
1830
+ const input = inputRef.value;
1831
+ if (event.key === "Backspace" && menu.query.value === "" && filters.value.length > 0 && canRemove(filters.value[filters.value.length - 1])) {
1832
+ event.preventDefault();
1833
+ removeAt(filters.value.length - 1);
1834
+ return;
1835
+ }
1836
+ if (event.key === "ArrowLeft" && input && input.selectionStart === 0 && input.selectionEnd === 0 && filters.value.length > 0) {
1837
+ event.preventDefault();
1838
+ focusToken(Math.min(visibleCount.value, filters.value.length) - 1);
1839
+ return;
1840
+ }
1841
+ if (event.key === "ArrowRight" && input && menu.query.value === "" && input.selectionStart === 0) return;
1842
+ menu.onKeyDown(event);
1843
+ }
1844
+ function onTokenKeyDown(event, index) {
1845
+ if (event.key === "ArrowLeft" && index > 0) {
1846
+ event.preventDefault();
1847
+ focusToken(index - 1);
1848
+ } else if (event.key === "ArrowRight") {
1849
+ event.preventDefault();
1850
+ if (index < visibleCount.value - 1) focusToken(index + 1);
1851
+ else inputRef.value?.focus();
1852
+ } else if (event.key === "Escape") inputRef.value?.focus();
1853
+ else if ((event.key === "Backspace" || event.key === "Delete") && canRemove(filters.value[index])) {
1854
+ event.preventDefault();
1855
+ removeAt(index);
1856
+ if (index > 0) focusToken(index - 1);
1857
+ } else if (event.key === "Enter") {
1858
+ event.preventDefault();
1859
+ activate(index);
1860
+ }
1861
+ }
1862
+ function onFieldClick(event) {
1863
+ if (props.disabled && !focusableDisabled.value) return;
1864
+ const target = event.target;
1865
+ if (target instanceof Element && target.closest("button, a")) return;
1866
+ inputRef.value?.focus();
1867
+ }
1868
+ function highlight(index) {
1869
+ const entry = menu.entries.value[index];
1870
+ if (entry && !entry.disabled) menu.combobox.activeIndex.value = index;
1871
+ }
1872
+ function groupLabel(index) {
1873
+ const group = menu.entries.value[index]?.item.auxiliaryData?.group;
1874
+ if (group == null || group === "") return void 0;
1875
+ return group !== (index > 0 ? menu.entries.value[index - 1]?.item.auxiliaryData?.group : void 0) ? group : void 0;
1876
+ }
1877
+ function itemIcon(item) {
1878
+ const data = item.auxiliaryData;
1879
+ const type = (data?.operatorKey ? lookup.value.getOperator(data.fieldKey, data.operatorKey) : void 0)?.value.type;
1880
+ if (type === "date_absolute" || type === "date_range" || type === "date_relative") return "calendar";
1881
+ if (type === "time") return "clock";
1882
+ if (type === "enum" || type === "enum_list") return "funnel";
1883
+ return "search";
1884
+ }
1885
+ function optionId(index) {
1886
+ return `${listboxId}-option-${index}`;
1887
+ }
1888
+ onMounted(() => {
1889
+ if (props.autofocus) inputRef.value?.focus();
1890
+ });
1891
+ __expose({
1892
+ focusTypeahead: () => inputRef.value?.focus(),
1893
+ blurTypeahead: () => inputRef.value?.blur()
1894
+ });
1895
+ return (_ctx, _cache) => {
1896
+ return openBlock(), createElementBlock(Fragment, null, [createVNode(_sfc_main$8, {
1897
+ class: normalizeClass(["astryx-power-search", [`size-${__props.size}`, { "is-floating": floating.value }]]),
1898
+ label: label.value,
1899
+ "input-id": inputId,
1900
+ "is-label-hidden": __props.labelHidden,
1901
+ "is-disabled": __props.disabled && !focusableDisabled.value,
1902
+ status: fieldStatus.value,
1903
+ "status-variant": __props.statusVariant
1904
+ }, {
1905
+ default: withCtx(() => [
1906
+ floating.value ? (openBlock(), createElementBlock("div", {
1907
+ key: 0,
1908
+ class: "astryx-power-search-placeholder",
1909
+ style: normalizeStyle({ height: `${placeholderHeight.value}px` })
1910
+ }, null, 4)) : createCommentVNode("v-if", true),
1911
+ createVNode(_sfc_main$6, {
1912
+ content: __props.disabledReason,
1913
+ "is-enabled": focusableDisabled.value
1914
+ }, {
1915
+ default: withCtx(() => [createCommentVNode(" eslint-disable-next-line vue-a11y/click-events-have-key-events, vue-a11y/no-static-element-interactions -- 点空白处把焦点交给输入框。 "), createElementVNode("div", {
1916
+ ref_key: "anchorRef",
1917
+ ref: anchorRef,
1918
+ class: normalizeClass(["astryx-power-search-control", [`status-${__props.status}`, {
1919
+ "is-open": unref(menu).combobox.isOpen.value,
1920
+ "is-disabled": __props.disabled,
1921
+ "is-floating": floating.value
1922
+ }]]),
1923
+ onClick: onFieldClick,
1924
+ onFocusin: onFocusIn,
1925
+ onFocusout: onFocusOut
1926
+ }, [
1927
+ slots.icon ? (openBlock(), createElementBlock("span", _hoisted_1, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("v-if", true),
1928
+ createElementVNode("span", {
1929
+ ref: unref(overflowState).containerRef,
1930
+ class: normalizeClass(["astryx-power-search-tokens", { "is-collapsed": collapsed.value }])
1931
+ }, [
1932
+ createCommentVNode(" eslint-disable-next-line vue-a11y/no-static-element-interactions -- 方向键在条件之间移动焦点。 "),
1933
+ (openBlock(true), createElementBlock(Fragment, null, renderList(visibleFilters.value, (filter, index) => {
1934
+ return openBlock(), createElementBlock("span", {
1935
+ key: `${filter.field}-${filter.operator}-${index}`,
1936
+ ref_for: true,
1937
+ ref: (element) => setTokenEl(index, element),
1938
+ class: "astryx-power-search-token",
1939
+ tabindex: "-1",
1940
+ onKeydown: ($event) => onTokenKeyDown($event, index)
1941
+ }, [renderSlot(_ctx.$slots, "token", {
1942
+ config: __props.config,
1943
+ filter,
1944
+ field: fieldFor(filter),
1945
+ operator: operatorFor(filter),
1946
+ maxLength: __props.maxTokenLength,
1947
+ disabled: __props.disabled,
1948
+ onClick: () => activate(index),
1949
+ onRemove: () => removeAt(index)
1950
+ }, () => [tokenComponent(filter) ? (openBlock(), createBlock(resolveDynamicComponent(tokenComponent(filter)), {
1951
+ key: 0,
1952
+ config: __props.config,
1953
+ filter,
1954
+ field: fieldFor(filter),
1955
+ operator: operatorFor(filter),
1956
+ "max-length": __props.maxTokenLength,
1957
+ disabled: __props.disabled,
1958
+ "on-click": () => activate(index),
1959
+ "on-remove": () => removeAt(index)
1960
+ }, null, 40, [
1961
+ "config",
1962
+ "filter",
1963
+ "field",
1964
+ "operator",
1965
+ "max-length",
1966
+ "disabled",
1967
+ "on-click",
1968
+ "on-remove"
1969
+ ])) : fieldFor(filter) && operatorFor(filter) ? (openBlock(), createBlock(_sfc_main$1, {
1970
+ key: 1,
1971
+ "field-label": fieldFor(filter).label,
1972
+ operator: operatorFor(filter),
1973
+ filter,
1974
+ "max-length": __props.maxTokenLength,
1975
+ messages: text.value,
1976
+ locale: unref(locale),
1977
+ "time-zone": __props.timeZone,
1978
+ size: __props.size,
1979
+ disabled: __props.disabled,
1980
+ removable: canRemove(filter),
1981
+ onActivate: ($event) => activate(index),
1982
+ onRemove: ($event) => removeAt(index)
1983
+ }, null, 8, [
1984
+ "field-label",
1985
+ "operator",
1986
+ "filter",
1987
+ "max-length",
1988
+ "messages",
1989
+ "locale",
1990
+ "time-zone",
1991
+ "size",
1992
+ "disabled",
1993
+ "removable",
1994
+ "onActivate",
1995
+ "onRemove"
1996
+ ])) : createCommentVNode("v-if", true)])], 40, _hoisted_2);
1997
+ }), 128)),
1998
+ collapsed.value && hiddenCount.value > 0 ? (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString(text.value.more(hiddenCount.value)), 1)) : createCommentVNode("v-if", true)
1999
+ ], 2),
2000
+ createElementVNode("span", {
2001
+ ref: unref(overflowState).measureRef,
2002
+ class: "astryx-power-search-measure",
2003
+ "aria-hidden": "true"
2004
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(filters.value, (filter, index) => {
2005
+ return openBlock(), createElementBlock("span", {
2006
+ key: `${filter.field}-${index}`,
2007
+ class: "astryx-power-search-token"
2008
+ }, [fieldFor(filter) && operatorFor(filter) ? (openBlock(), createBlock(_sfc_main$1, {
2009
+ key: 0,
2010
+ "field-label": fieldFor(filter).label,
2011
+ operator: operatorFor(filter),
2012
+ filter,
2013
+ "max-length": __props.maxTokenLength,
2014
+ messages: text.value,
2015
+ locale: unref(locale),
2016
+ size: __props.size,
2017
+ removable: ""
2018
+ }, null, 8, [
2019
+ "field-label",
2020
+ "operator",
2021
+ "filter",
2022
+ "max-length",
2023
+ "messages",
2024
+ "locale",
2025
+ "size"
2026
+ ])) : createCommentVNode("v-if", true)]);
2027
+ }), 128)), createElementVNode("span", _hoisted_4, toDisplayString(text.value.more(Math.max(hiddenCount.value, 1))), 1)], 512),
2028
+ createElementVNode("input", {
2029
+ id: inputId,
2030
+ ref_key: "inputRef",
2031
+ ref: inputRef,
2032
+ class: "astryx-power-search-input",
2033
+ type: "text",
2034
+ role: "combobox",
2035
+ autocomplete: "off",
2036
+ autocapitalize: "off",
2037
+ placeholder: filters.value.length === 0 ? placeholder.value : void 0,
2038
+ value: unref(menu).query.value,
2039
+ disabled: __props.disabled && !focusableDisabled.value,
2040
+ readonly: __props.readOnly || focusableDisabled.value || void 0,
2041
+ "aria-disabled": __props.disabled ? "true" : void 0,
2042
+ "aria-expanded": unref(menu).combobox.isOpen.value,
2043
+ "aria-controls": listboxId,
2044
+ "aria-autocomplete": "list",
2045
+ "aria-activedescendant": unref(menu).activeId.value ? optionId(unref(menu).combobox.activeIndex.value) : void 0,
2046
+ "aria-describedby": describedBy.value,
2047
+ onInput,
2048
+ onKeydown: onInputKeyDown,
2049
+ onFocus: onInputFocus,
2050
+ onBlur: _cache[0] || (_cache[0] = ($event) => emit("blur", $event))
2051
+ }, null, 40, _hoisted_5),
2052
+ renderSlot(_ctx.$slots, "end"),
2053
+ displayCount.value ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(displayCount.value), 1)) : createCommentVNode("v-if", true),
2054
+ __props.clearable && filters.value.length > 0 && !__props.disabled && !__props.readOnly ? (openBlock(), createElementBlock("button", {
2055
+ key: 2,
2056
+ type: "button",
2057
+ class: "astryx-power-search-clear",
2058
+ "aria-label": text.value.clear,
2059
+ onClick: clearAll
2060
+ }, [createVNode(_sfc_main$7, {
2061
+ icon: "close",
2062
+ size: "sm"
2063
+ })], 8, _hoisted_7)) : createCommentVNode("v-if", true),
2064
+ focusableDisabled.value ? (openBlock(), createElementBlock("span", {
2065
+ key: 3,
2066
+ id: disabledId,
2067
+ class: "astryx-visually-hidden"
2068
+ }, toDisplayString(__props.disabledReason), 1)) : createCommentVNode("v-if", true)
2069
+ ], 34)]),
2070
+ _: 3
2071
+ }, 8, ["content", "is-enabled"]),
2072
+ createElementVNode("span", _hoisted_8, toDisplayString(liveText.value), 1)
2073
+ ]),
2074
+ _: 3
2075
+ }, 8, [
2076
+ "class",
2077
+ "label",
2078
+ "is-label-hidden",
2079
+ "is-disabled",
2080
+ "status",
2081
+ "status-variant"
2082
+ ]), (openBlock(), createBlock(Teleport, { to: "body" }, [withDirectives(createElementVNode("div", {
2083
+ id: listboxId,
2084
+ ref_key: "listboxRef",
2085
+ ref: listboxRef,
2086
+ class: "astryx-typeahead-listbox",
2087
+ role: "listbox",
2088
+ "aria-label": text.value.results,
2089
+ "data-placement": unref(anchored).position.value.placement,
2090
+ style: normalizeStyle(menuStyle.value),
2091
+ tabindex: "-1"
2092
+ }, [createElementVNode("div", _hoisted_10, [unref(menu).entries.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_11, toDisplayString(text.value.empty), 1)) : (openBlock(), createElementBlock("div", _hoisted_12, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(menu).entries.value, (entry, index) => {
2093
+ return openBlock(), createElementBlock(Fragment, { key: entry.id }, [
2094
+ groupLabel(index) ? (openBlock(), createElementBlock("div", _hoisted_13, toDisplayString(groupLabel(index)), 1)) : createCommentVNode("v-if", true),
2095
+ createCommentVNode(" eslint-disable-next-line vue-a11y/click-events-have-key-events, vue-a11y/mouse-events-have-key-events -- 选项不进 Tab 序。 "),
2096
+ createElementVNode("div", {
2097
+ id: optionId(index),
2098
+ class: normalizeClass(["astryx-typeahead-option", {
2099
+ "is-active": index === unref(menu).combobox.activeIndex.value,
2100
+ "is-disabled": entry.disabled
2101
+ }]),
2102
+ role: "option",
2103
+ "aria-selected": index === unref(menu).combobox.activeIndex.value ? "true" : "false",
2104
+ "data-option-id": entry.id,
2105
+ tabindex: "-1",
2106
+ onMousedown: _cache[1] || (_cache[1] = withModifiers(() => {}, ["prevent"])),
2107
+ onMouseenter: ($event) => highlight(index),
2108
+ onClick: ($event) => pick(entry.item)
2109
+ }, [createVNode(_sfc_main$7, {
2110
+ icon: itemIcon(entry.item),
2111
+ size: "sm"
2112
+ }, null, 8, ["icon"]), createElementVNode("span", _hoisted_15, [createElementVNode("span", _hoisted_16, toDisplayString(entry.label), 1), entry.description ? (openBlock(), createElementBlock("span", _hoisted_17, toDisplayString(entry.description), 1)) : createCommentVNode("v-if", true)])], 42, _hoisted_14)
2113
+ ], 64);
2114
+ }), 128))]))])], 12, _hoisted_9), [[vShow, unref(menu).combobox.isOpen.value]]), session.value ? (openBlock(), createElementBlock("div", {
2115
+ key: 0,
2116
+ ref_key: "editorRef",
2117
+ ref: editorRef,
2118
+ class: "astryx-power-search-editor",
2119
+ "data-ready": session.value.ready ? "true" : "false",
2120
+ style: normalizeStyle(editorStyle.value)
2121
+ }, [renderSlot(_ctx.$slots, "editor", {
2122
+ config: __props.config,
2123
+ filter: session.value.filter,
2124
+ mode: session.value.mode,
2125
+ saveLabel: __props.saveLabel,
2126
+ readOnly: __props.readOnly,
2127
+ timeZone: __props.timeZone,
2128
+ maxMenuItems: __props.maxOperatorMenuItems,
2129
+ onSave: onEditorSave,
2130
+ onCancel: () => closeEditor(true)
2131
+ }, () => [(openBlock(), createBlock(resolveDynamicComponent(editorComponent.value), {
2132
+ config: __props.config,
2133
+ filter: session.value.filter,
2134
+ mode: session.value.mode,
2135
+ "save-label": __props.saveLabel,
2136
+ "read-only": __props.readOnly,
2137
+ "time-zone": __props.timeZone,
2138
+ "max-menu-items": __props.maxOperatorMenuItems,
2139
+ "on-save": onEditorSave,
2140
+ "on-cancel": () => closeEditor(true)
2141
+ }, null, 40, [
2142
+ "config",
2143
+ "filter",
2144
+ "mode",
2145
+ "save-label",
2146
+ "read-only",
2147
+ "time-zone",
2148
+ "max-menu-items",
2149
+ "on-cancel"
2150
+ ]))])], 12, _hoisted_18)) : createCommentVNode("v-if", true)]))], 64);
2151
+ };
2152
+ }
2153
+ });
2154
+ //#endregion
2155
+ //#region src/PowerSearch/fieldBuilders.ts
2156
+ function i18n(key, message, value) {
2157
+ return {
2158
+ key,
2159
+ i18nKey: `@astryx.powersearch.operator.${message}`,
2160
+ value
2161
+ };
2162
+ }
2163
+ function stringField(key, label) {
2164
+ return {
2165
+ key,
2166
+ label,
2167
+ defaultOperator: "contains",
2168
+ operators: [
2169
+ i18n("contains", "contains", { type: "string" }),
2170
+ i18n("not_contains", "notContains", { type: "string" }),
2171
+ i18n("starts_with", "startsWith", { type: "string" }),
2172
+ i18n("not_starts_with", "notStartsWith", { type: "string" }),
2173
+ i18n("ends_with", "endsWith", { type: "string" }),
2174
+ i18n("not_ends_with", "notEndsWith", { type: "string" }),
2175
+ i18n("is", "is", { type: "string" }),
2176
+ i18n("is_not", "isNot", { type: "string" })
2177
+ ]
2178
+ };
2179
+ }
2180
+ function numberField(key, label) {
2181
+ const value = { type: "float" };
2182
+ return {
2183
+ key,
2184
+ label,
2185
+ defaultOperator: "equals",
2186
+ operators: [
2187
+ i18n("equals", "equals", value),
2188
+ i18n("not_equals", "notEquals", value),
2189
+ i18n("greater_than", "greaterThan", value),
2190
+ i18n("less_than", "lessThan", value),
2191
+ i18n("greater_than_or_equal", "greaterThanOrEqual", value),
2192
+ i18n("less_than_or_equal", "lessThanOrEqual", value)
2193
+ ]
2194
+ };
2195
+ }
2196
+ function dateField(key, label) {
2197
+ return {
2198
+ key,
2199
+ label,
2200
+ defaultOperator: "after",
2201
+ operators: [
2202
+ i18n("before", "before", { type: "date_absolute" }),
2203
+ i18n("after", "after", { type: "date_absolute" }),
2204
+ i18n("between", "between", { type: "date_range" })
2205
+ ]
2206
+ };
2207
+ }
2208
+ function booleanField(key, label) {
2209
+ return {
2210
+ key,
2211
+ label,
2212
+ defaultOperator: "is_true",
2213
+ operators: [i18n("is_true", "isTrue", { type: "empty" }), i18n("is_false", "isFalse", { type: "empty" })]
2214
+ };
2215
+ }
2216
+ function enumField(key, label, values) {
2217
+ return {
2218
+ key,
2219
+ label,
2220
+ defaultOperator: "is",
2221
+ operators: [
2222
+ i18n("is", "is", {
2223
+ type: "enum",
2224
+ values
2225
+ }),
2226
+ i18n("is_not", "isNot", {
2227
+ type: "enum",
2228
+ values
2229
+ }),
2230
+ i18n("is_any_of", "isAnyOf", {
2231
+ type: "enum_list",
2232
+ values
2233
+ }),
2234
+ i18n("is_none_of", "isNoneOf", {
2235
+ type: "enum_list",
2236
+ values
2237
+ })
2238
+ ]
2239
+ };
2240
+ }
2241
+ function enumListField(key, label, values) {
2242
+ return {
2243
+ key,
2244
+ label,
2245
+ defaultOperator: "is_any_of",
2246
+ operators: [i18n("is_any_of", "isAnyOf", {
2247
+ type: "enum_list",
2248
+ values
2249
+ }), i18n("is_none_of", "isNoneOf", {
2250
+ type: "enum_list",
2251
+ values
2252
+ })]
2253
+ };
2254
+ }
2255
+ function stringListField(key, label) {
2256
+ return {
2257
+ key,
2258
+ label,
2259
+ defaultOperator: "is_any_of",
2260
+ operators: [i18n("is_any_of", "isAnyOf", { type: "string_list" }), i18n("is_none_of", "isNoneOf", { type: "string_list" })]
2261
+ };
2262
+ }
2263
+ function buildPowerSearchField(definition) {
2264
+ const label = definition.label ?? definition.key;
2265
+ switch (definition.type) {
2266
+ case "string": return stringField(definition.key, label);
2267
+ case "number": return numberField(definition.key, label);
2268
+ case "date": return dateField(definition.key, label);
2269
+ case "boolean": return booleanField(definition.key, label);
2270
+ case "enum": return enumField(definition.key, label, definition.enumValues ?? []);
2271
+ case "enum_list": return enumListField(definition.key, label, definition.enumValues ?? []);
2272
+ case "string_list": return stringListField(definition.key, label);
2273
+ }
2274
+ }
2275
+ //#endregion
2276
+ //#region src/PowerSearch/query.ts
2277
+ const stringHandlers = {
2278
+ contains: (value, target) => value.includes(target),
2279
+ not_contains: (value, target) => !value.includes(target),
2280
+ starts_with: (value, target) => value.startsWith(target),
2281
+ not_starts_with: (value, target) => !value.startsWith(target),
2282
+ ends_with: (value, target) => value.endsWith(target),
2283
+ not_ends_with: (value, target) => !value.endsWith(target),
2284
+ is: (value, target) => value === target,
2285
+ is_not: (value, target) => value !== target
2286
+ };
2287
+ const numberHandlers = {
2288
+ equals: (value, target) => value === target,
2289
+ not_equals: (value, target) => value !== target,
2290
+ greater_than: (value, target) => value > target,
2291
+ less_than: (value, target) => value < target,
2292
+ greater_than_or_equal: (value, target) => value >= target,
2293
+ less_than_or_equal: (value, target) => value <= target
2294
+ };
2295
+ function toUnixSeconds(value) {
2296
+ return value instanceof Date ? Math.floor(value.getTime() / 1e3) : value;
2297
+ }
2298
+ function toStringValues(value) {
2299
+ if (typeof value === "string") return [value];
2300
+ if (Array.isArray(value) && value.every((item) => typeof item === "string")) return value;
2301
+ return null;
2302
+ }
2303
+ function isAnyOperator(operator) {
2304
+ return operator === "or" || operator === "any" || operator === "any_of" || operator.includes("any");
2305
+ }
2306
+ function matchesNested(row, value, operator) {
2307
+ if (value.type !== "nested") return true;
2308
+ const checks = value.value.map((filter) => matchesPowerSearchFilter(row, filter));
2309
+ if (checks.length === 0) return true;
2310
+ return isAnyOperator(operator) ? checks.some(Boolean) : checks.every(Boolean);
2311
+ }
2312
+ function matchesPowerSearchFilter(row, filter) {
2313
+ const fieldValue = row[filter.field];
2314
+ const { operator, value } = filter;
2315
+ switch (value.type) {
2316
+ case "empty":
2317
+ if (operator === "is_true") return Boolean(fieldValue) === true;
2318
+ if (operator === "is_false") return Boolean(fieldValue) === false;
2319
+ return true;
2320
+ case "string": {
2321
+ if (typeof fieldValue !== "string") return false;
2322
+ const handler = stringHandlers[operator];
2323
+ return handler ? handler(fieldValue.toLowerCase(), value.value.toLowerCase()) : true;
2324
+ }
2325
+ case "integer":
2326
+ case "float": {
2327
+ if (typeof fieldValue !== "number") return false;
2328
+ const handler = numberHandlers[operator];
2329
+ return handler ? handler(fieldValue, value.value) : true;
2330
+ }
2331
+ case "date_absolute": {
2332
+ if (!(fieldValue instanceof Date) && typeof fieldValue !== "number") return false;
2333
+ const stamp = toUnixSeconds(fieldValue);
2334
+ if (operator === "before") return stamp < value.unixSeconds;
2335
+ if (operator === "after") return stamp > value.unixSeconds;
2336
+ return true;
2337
+ }
2338
+ case "date_range": {
2339
+ if (!(fieldValue instanceof Date) && typeof fieldValue !== "number") return false;
2340
+ if (operator !== "between") return true;
2341
+ const now = Date.now() / 1e3;
2342
+ const stamp = toUnixSeconds(fieldValue);
2343
+ const start = resolveDateTimeRangePart(value.value.start, now);
2344
+ const end = resolveDateTimeRangePart(value.value.end, now);
2345
+ return stamp >= start && stamp <= end;
2346
+ }
2347
+ case "enum":
2348
+ if (typeof fieldValue !== "string") return false;
2349
+ if (operator === "is") return fieldValue === value.value;
2350
+ if (operator === "is_not") return fieldValue !== value.value;
2351
+ return true;
2352
+ case "enum_list":
2353
+ case "string_list": {
2354
+ const values = toStringValues(fieldValue);
2355
+ if (values == null) return false;
2356
+ if (operator === "is_any_of") return values.some((item) => value.value.includes(item));
2357
+ if (operator === "is_none_of") return values.every((item) => !value.value.includes(item));
2358
+ return true;
2359
+ }
2360
+ case "nested": return matchesNested(row, value, operator);
2361
+ case "time":
2362
+ case "date_relative":
2363
+ case "entity_list":
2364
+ case "custom": return true;
2365
+ }
2366
+ }
2367
+ function applyPowerSearchFilters(filters, data) {
2368
+ if (filters.length === 0) return [...data];
2369
+ return data.filter((row) => filters.every((filter) => matchesPowerSearchFilter(row, filter)));
2370
+ }
2371
+ function createPowerSearchConfig(definitions, configName) {
2372
+ return {
2373
+ config: {
2374
+ name: configName ?? "PowerSearchConfig",
2375
+ fields: definitions.map((definition) => buildPowerSearchField(definition))
2376
+ },
2377
+ applyFilters(filters, data) {
2378
+ return applyPowerSearchFilters(filters, data);
2379
+ }
2380
+ };
2381
+ }
2382
+ function usePowerSearchConfig(definitions, configName) {
2383
+ return createPowerSearchConfig(definitions, configName);
2384
+ }
2385
+ //#endregion
2386
+ export { searchPowerSearchFields as a, formatDateAbsolute as c, createPowerSearchLookup as d, completePowerSearchFilter as f, _sfc_main as i, formatDateAbsoluteCompact as l, createPowerSearchConfig as n, resolveEditorPlacement as o, usePowerSearchConfig as r, resolveOperatorLabel as s, applyPowerSearchFilters as t, formatFilterValue as u };