@wavemaker/react-runtime 11.14.2-1.245 → 12.0.0-next.28533

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 (244) hide show
  1. package/actions/base-action.js +5 -7
  2. package/actions/login-action.js +7 -8
  3. package/actions/logout-action.js +5 -7
  4. package/actions/navigation-action.js +32 -10
  5. package/actions/notification-action.js +22 -8
  6. package/actions/timer-action.js +13 -15
  7. package/actions/toast.js +4 -2
  8. package/actions/toast.service.js +1 -2
  9. package/components/advanced/carousel/index.js +1 -1
  10. package/components/advanced/carousel/template.js +1 -1
  11. package/components/basic/anchor/index.js +26 -9
  12. package/components/basic/html/index.js +115 -24
  13. package/components/basic/icon/index.js +2 -1
  14. package/components/basic/iframe/index.js +2 -1
  15. package/components/basic/label/index.js +12 -9
  16. package/components/basic/message/index.js +12 -3
  17. package/components/basic/picture/index.js +11 -4
  18. package/components/basic/progress-bar/index.js +1 -1
  19. package/components/basic/progress-circle/index.js +34 -28
  20. package/components/basic/progress-circle/props.js +10 -2
  21. package/components/basic/richtexteditor/index.js +95 -94
  22. package/components/basic/search/index.js +401 -156
  23. package/components/basic/search/providers.js +126 -61
  24. package/components/basic/spinner/index.js +2 -1
  25. package/components/basic/tree/index.js +34 -34
  26. package/components/basic/tree/utils.js +10 -4
  27. package/components/chart/components/barColumnChart/index.js +36 -33
  28. package/components/chart/components/bubbleChart/index.js +35 -25
  29. package/components/chart/components/chartLegend/utils.js +2 -1
  30. package/components/chart/components/cumulativeLineChart/index.js +30 -26
  31. package/components/chart/components/lineAreaChart/index.js +50 -32
  32. package/components/chart/components/pieDonutChart/index.js +13 -4
  33. package/components/chart/hooks/useXAxisConfig.js +15 -8
  34. package/components/chart/index.js +223 -53
  35. package/components/chart/utils.js +12 -1
  36. package/components/constants.js +5 -2
  37. package/components/container/accordion/accordion-pane/index.js +17 -12
  38. package/components/container/accordion/index.js +9 -4
  39. package/components/container/alignment-utils.js +56 -1
  40. package/components/container/index.js +49 -20
  41. package/components/container/panel/components/panel-header/index.js +3 -4
  42. package/components/container/panel/index.js +15 -10
  43. package/components/container/tabs/index.js +92 -14
  44. package/components/container/tabs/tab-pane/index.js +15 -8
  45. package/components/container/tabs/utils.js +51 -0
  46. package/components/container/wizard/components/StepComponents.js +2 -1
  47. package/components/container/wizard/components/WizardStep.js +2 -1
  48. package/components/container/wizard/index.js +64 -35
  49. package/components/container/wizard/utils.js +46 -1
  50. package/components/container/wizard/wizard-step/index.js +11 -1
  51. package/components/data/card/card-content/index.js +1 -1
  52. package/components/data/form/base-form/index.js +991 -180
  53. package/components/data/form/base-form/props.js +3 -1
  54. package/components/data/form/base-form/utils.js +159 -1
  55. package/components/data/form/dynamic-fields/constant.js +53 -0
  56. package/components/data/form/dynamic-fields/index.js +10 -45
  57. package/components/data/form/dynamic-fields/utils.js +37 -2
  58. package/components/data/form/form-action/index.js +5 -4
  59. package/components/data/form/form-context.js +5 -1
  60. package/components/data/form/form-controller/utils.js +84 -0
  61. package/components/data/form/form-controller/validation-contrustor.js +402 -189
  62. package/components/data/form/form-controller/withFormController.js +191 -52
  63. package/components/data/form/form-field/base-field.js +54 -33
  64. package/components/data/form/form-field/index.js +28 -5
  65. package/components/data/form/form-header/index.js +3 -4
  66. package/components/data/form/index.js +20 -1
  67. package/components/data/list/components/ListDND.js +2 -1
  68. package/components/data/list/components/ListItem.js +6 -2
  69. package/components/data/list/components/ListItemWithTemplate.js +46 -2
  70. package/components/data/list/components/ListItems.js +17 -26
  71. package/components/data/list/components/ListPagination.js +3 -3
  72. package/components/data/list/components/StandardListItems.js +3 -4
  73. package/components/data/list/hooks/useListEffects.js +55 -14
  74. package/components/data/list/hooks/useListEventHandlers.js +3 -1
  75. package/components/data/list/hooks/useListState.js +3 -1
  76. package/components/data/list/hooks/usePaginatedGroupedData.js +18 -5
  77. package/components/data/list/index.js +74 -55
  78. package/components/data/list/utils/list-helpers.js +73 -35
  79. package/components/data/list/utils/list-widget-methods.js +138 -95
  80. package/components/data/live-filter/index.js +26 -15
  81. package/components/data/live-form/index.js +23 -7
  82. package/components/data/live-form/props.js +1 -1
  83. package/components/data/pagination/components/BasicPagination.js +71 -16
  84. package/components/data/pagination/components/PageSizeSelector.js +8 -3
  85. package/components/data/pagination/components/TotalRecords.js +1 -5
  86. package/components/data/pagination/hooks/usePagination.js +349 -66
  87. package/components/data/pagination/index.js +137 -19
  88. package/components/data/table/components/AddNewRow.js +5 -1
  89. package/components/data/table/components/EditableCell.js +2 -2
  90. package/components/data/table/components/RowCells.js +64 -0
  91. package/components/data/table/components/RowExpansionButton.js +2 -2
  92. package/components/data/table/components/SummaryCell.js +111 -0
  93. package/components/data/table/components/SummaryRow.js +54 -0
  94. package/components/data/table/components/SummaryRowFooter.js +46 -0
  95. package/components/data/table/components/TableBody.js +61 -59
  96. package/components/data/table/components/TableDataRow.js +109 -0
  97. package/components/data/table/components/TableFilters.js +225 -121
  98. package/components/data/table/components/TableHeader.js +291 -23
  99. package/components/data/table/components/TablePanelHeading.js +139 -8
  100. package/components/data/table/components/index.js +22 -1
  101. package/components/data/table/hooks/use-edited-rows.js +141 -0
  102. package/components/data/table/hooks/useCellState.js +5 -12
  103. package/components/data/table/hooks/useFormWidget.js +58 -51
  104. package/components/data/table/hooks/usePaginationState.js +45 -24
  105. package/components/data/table/hooks/usePanelStructure.js +4 -4
  106. package/components/data/table/hooks/useRowHandlers.js +39 -5
  107. package/components/data/table/hooks/useRowSelection.js +244 -50
  108. package/components/data/table/hooks/useServerSideSorting.js +81 -37
  109. package/components/data/table/hooks/useTableColumns.js +211 -118
  110. package/components/data/table/hooks/useTableData.js +54 -9
  111. package/components/data/table/hooks/useTableEdit.js +272 -97
  112. package/components/data/table/hooks/useTableEffects.js +31 -13
  113. package/components/data/table/hooks/useTableFilter.js +1 -1
  114. package/components/data/table/hooks/useTableInitialization.js +23 -22
  115. package/components/data/table/hooks/useTableState.js +11 -5
  116. package/components/data/table/hooks/useTableStateManager.js +140 -65
  117. package/components/data/table/index.js +637 -274
  118. package/components/data/table/live-table/index.js +54 -22
  119. package/components/data/table/table-action/index.js +1 -1
  120. package/components/data/table/table-group/index.js +26 -0
  121. package/components/data/table/table-row-action/index.js +32 -18
  122. package/components/data/table/utils/buildSelectionColumns.js +12 -21
  123. package/components/data/table/utils/columnBuilder.js +29 -14
  124. package/components/data/table/utils/columnProxy.js +68 -1
  125. package/components/data/table/utils/constants.js +6 -2
  126. package/components/data/table/utils/crud-handlers.js +68 -63
  127. package/components/data/table/utils/groupHeaderUtils.js +102 -0
  128. package/components/data/table/utils/index.js +210 -21
  129. package/components/data/table/utils/renderDisplayCell.js +6 -6
  130. package/components/data/table/utils/selectionUtils.js +25 -26
  131. package/components/data/table/utils/validation.js +1 -0
  132. package/components/data/utils/filter-field-util.js +3 -3
  133. package/components/dialogs/alert-dialog/index.js +1 -1
  134. package/components/dialogs/confirm-dialog/index.js +1 -1
  135. package/components/dialogs/dialog/index.js +4 -1
  136. package/components/dialogs/dialog-content/index.js +3 -1
  137. package/components/dialogs/dialog-header/index.js +2 -2
  138. package/components/dialogs/iframe-dialog/index.js +11 -5
  139. package/components/dialogs/index.js +1 -1
  140. package/components/dialogs/login-dialog/index.js +1 -1
  141. package/components/dialogs/page-dialog/index.js +1 -1
  142. package/components/form/button/index.js +33 -7
  143. package/components/input/calendar/index.js +18 -6
  144. package/components/input/chips/index.js +99 -28
  145. package/components/input/chips/utils.js +34 -4
  146. package/components/input/color-picker/index.js +74 -25
  147. package/components/input/composite/index.js +3 -3
  148. package/components/input/currency/index.js +35 -49
  149. package/components/input/default/checkbox/index.js +23 -28
  150. package/components/input/default/checkboxset/index.js +38 -18
  151. package/components/input/default/checkboxset/utils.js +30 -0
  152. package/components/input/default/radioset/index.js +36 -39
  153. package/components/input/default/switch/index.js +30 -13
  154. package/components/input/epoch/date/index.js +130 -69
  155. package/components/input/epoch/date/utils.js +94 -1
  156. package/components/input/epoch/datetime/index.js +72 -22
  157. package/components/input/epoch/datetime/utils.js +49 -10
  158. package/components/input/epoch/time/index.js +68 -19
  159. package/components/input/epoch/time/utils.js +62 -14
  160. package/components/input/fileupload/Utils.js +12 -7
  161. package/components/input/fileupload/components/MultiUpload.js +2 -6
  162. package/components/input/fileupload/components/SingleUpload.js +3 -7
  163. package/components/input/fileupload/index.js +6 -10
  164. package/components/input/fileupload/useFileUpload.js +16 -5
  165. package/components/input/number/index.js +158 -43
  166. package/components/input/rating/index.js +90 -7
  167. package/components/input/select/index.js +147 -70
  168. package/components/input/slider/index.js +84 -26
  169. package/components/input/text/index.js +38 -18
  170. package/components/input/text/util.js +283 -130
  171. package/components/input/textarea/index.js +13 -10
  172. package/components/input/upload/index.js +124 -0
  173. package/components/input/upload/props.js +5 -0
  174. package/components/input/util/index.js +11 -0
  175. package/components/navbar/index.js +51 -3
  176. package/components/navbar/nav/index.js +46 -16
  177. package/components/navbar/nav-item/index.js +11 -5
  178. package/components/navigation/menu/components/ListItems.js +3 -0
  179. package/components/navigation/menu/constants.js +2 -1
  180. package/components/navigation/menu/hooks/useHoverState.hook.js +48 -0
  181. package/components/navigation/menu/hooks/useKeyboardMovements.hook.js +37 -0
  182. package/components/navigation/menu/hooks/useTransformedDataset.hook.js +15 -0
  183. package/components/navigation/menu/index.js +326 -188
  184. package/components/navigation/menu/utils/action-task.js +14 -0
  185. package/components/navigation/menu/utils/role-filter.js +76 -0
  186. package/components/navigation/popover/index.js +99 -26
  187. package/components/page/partial-container/index.js +34 -5
  188. package/components/prefab/index.js +2 -4
  189. package/context/PrefabContext.js +10 -6
  190. package/context/WidgetProvider.js +30 -31
  191. package/core/app.service.js +1 -1
  192. package/core/constants/events.js +57 -1
  193. package/core/dialog.service.js +1 -2
  194. package/core/event-notifier.js +1 -2
  195. package/core/formatter/array-formatters.js +33 -0
  196. package/core/formatter/date-formatters.js +2 -4
  197. package/core/formatter/index.js +2 -1
  198. package/core/formatter/number-formatters.js +5 -10
  199. package/core/formatter/security-formatters.js +2 -4
  200. package/core/formatter/string-formatters.js +3 -6
  201. package/core/proxy-service.js +84 -13
  202. package/core/script-registry.js +108 -48
  203. package/core/util/common.js +4 -4
  204. package/core/util/compare.js +30 -0
  205. package/core/util/dom.js +8 -8
  206. package/core/util/index.js +16 -6
  207. package/core/util/safe-is-equal.js +156 -0
  208. package/core/util/security.js +1 -2
  209. package/core/util/utils.js +16 -7
  210. package/higherOrder/BaseApp.js +108 -65
  211. package/higherOrder/BaseDateTime.js +31 -13
  212. package/higherOrder/BasePage.js +268 -144
  213. package/higherOrder/BasePartial.js +1 -1
  214. package/higherOrder/BasePrefab.js +33 -15
  215. package/higherOrder/DataNav.js +99 -16
  216. package/higherOrder/helper.js +5 -0
  217. package/higherOrder/withBaseWrapper.js +41 -28
  218. package/hooks/useAuth.js +11 -5
  219. package/hooks/useHttp.js +280 -94
  220. package/mui-config/theme-provider.js +1 -1
  221. package/mui-config/theme.js +1 -1
  222. package/package-lock.json +711 -669
  223. package/package.json +8 -8
  224. package/store/bindActions/i18nActions.js +18 -0
  225. package/store/index.js +3 -1
  226. package/store/slices/appConfigSlice.js +2 -2
  227. package/store/slices/authSlice.js +31 -28
  228. package/store/slices/i18nSlice.js +2 -2
  229. package/store/slices/navigationSlice.js +35 -0
  230. package/store/viewport.service.js +255 -0
  231. package/utils/attr.js +35 -0
  232. package/utils/dataset-util.js +1 -2
  233. package/utils/form-state.util.js +43 -12
  234. package/utils/form-utils.js +47 -2
  235. package/utils/format-util.js +28 -13
  236. package/utils/page-params-util.js +33 -1
  237. package/utils/state-persistance.js +72 -13
  238. package/utils/transformedDataset-utils.js +35 -24
  239. package/variables/base-variable.js +12 -14
  240. package/variables/crud-variable.js +225 -0
  241. package/variables/live-variable.js +56 -20
  242. package/variables/metadata.service.js +123 -0
  243. package/variables/model-variable.js +21 -15
  244. package/variables/service-variable.js +88 -83
@@ -17,6 +17,8 @@ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/h
17
17
  var _react = _interopRequireWildcard(require("react"));
18
18
  var _clsx = _interopRequireDefault(require("clsx"));
19
19
  var _image = _interopRequireDefault(require("next/image"));
20
+ var _debounce = _interopRequireDefault(require("lodash/debounce"));
21
+ var _isPlainObject = _interopRequireDefault(require("lodash/isPlainObject"));
20
22
  var _Typography = _interopRequireDefault(require("@mui/material/Typography"));
21
23
  var _IconButton = _interopRequireDefault(require("@mui/material/IconButton"));
22
24
  var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem"));
@@ -28,11 +30,10 @@ var _CircularProgress = _interopRequireDefault(require("@mui/material/CircularPr
28
30
  var _dompurify = _interopRequireDefault(require("dompurify"));
29
31
  var _material = require("@mui/material");
30
32
  var _withBaseWrapper = _interopRequireDefault(require("@wavemaker/react-runtime/higherOrder/withBaseWrapper"));
31
- var _lodash = require("lodash");
32
33
  var _transformedDatasetUtils = require("@wavemaker/react-runtime/utils/transformedDataset-utils");
33
34
  var _providers = require("./providers");
34
35
  var _withFormController = _interopRequireDefault(require("@wavemaker/react-runtime/components/data/form/form-controller/withFormController"));
35
- var _excluded = ["showclear", "debouncetime", "searchkey", "searchon", "matchmode", "minchars", "limit", "tabindex", "placeholder", "dropup", "readonly", "datavalue", "dataset", "datafield", "displayfield", "disabled", "autofocus", "type", "showsearchicon", "showbackbutton", "imagewidth", "width", "displaylabel", "displayimagesrc", "displayexpression", "datacompletemsg", "loadingdatamsg", "clearsearchiconclass", "backsearchiconclass", "searchiconclass", "navsearchbar", "class", "shortcutkey", "required", "hint", "arialabel", "onBeforeservicecall", "onBlur", "onChange", "onFocus", "onSelect", "onSubmit", "onClear", "onSearch", "onDatasetready", "conditionalstyles", "styles", "name", "listener", "value", "datasetItems", "selectedItems", "displayValue", "groupedData", "handleHeaderClick", "toggleAllHeaders", "isDestroyed", "validation", "casesensitive", "isUpdateRequired", "onQuerySearch"];
36
+ var _excluded = ["showclear", "debouncetime", "searchkey", "searchon", "matchmode", "minchars", "limit", "tabindex", "placeholder", "dropup", "readonly", "datavalue", "dataset", "datafield", "displayfield", "disabled", "autofocus", "type", "showsearchicon", "showbackbutton", "imagewidth", "width", "displaylabel", "displayimagesrc", "displayexpression", "datacompletemsg", "loadingdatamsg", "clearsearchiconclass", "backsearchiconclass", "searchiconclass", "navsearchbar", "class", "shortcutkey", "required", "hint", "arialabel", "onBeforeservicecall", "onBlur", "onChange", "onFocus", "onSelect", "onSubmit", "onClear", "onSearch", "onDatasetready", "conditionalstyles", "styles", "name", "listener", "value", "datasetItems", "selectedItems", "displayValue", "groupedData", "handleHeaderClick", "toggleAllHeaders", "isDestroyed", "validation", "casesensitive", "isUpdateRequired", "onQuerySearch", "getDisplayExpression"];
36
37
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
37
38
  var __jsx = _react["default"].createElement;
38
39
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
@@ -131,10 +132,18 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
131
132
  casesensitive = _props$casesensitive === void 0 ? false : _props$casesensitive,
132
133
  isUpdateRequired = props.isUpdateRequired,
133
134
  onQuerySearch = props.onQuerySearch,
135
+ getDisplayExpression = props.getDisplayExpression,
134
136
  restProps = (0, _objectWithoutProperties2["default"])(props, _excluded);
137
+ var debouncedSearchRef = (0, _react.useRef)(null);
138
+ var debouncedSearchItemRef = (0, _react.useRef)(null);
139
+ var getDataSourceRef = (0, _react.useRef)(null);
135
140
  var searchRef = (0, _react.useRef)(null);
136
141
  var inputRef = (0, _react.useRef)(null);
137
142
  var dropdownRef = (0, _react.useRef)(null);
143
+ var searchButtonRef = (0, _react.useRef)(null);
144
+ var listRef = (0, _react.useRef)(null);
145
+ var initializedRef = (0, _react.useRef)(false);
146
+ var isLoadingNextPageRef = (0, _react.useRef)(false); // Track if pagination request is in progress
138
147
  var _useState = (0, _react.useState)(typeof datavalue === "string" ? datavalue : ""),
139
148
  query = _useState[0],
140
149
  setQuery = _useState[1];
@@ -171,10 +180,52 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
171
180
  var _useState10 = (0, _react.useState)(undefined),
172
181
  updateRequired = _useState10[0],
173
182
  setUpdateRequired = _useState10[1];
183
+ var dataProvider = (0, _react.useMemo)(function () {
184
+ return new _providers.DataProvider();
185
+ }, []);
186
+
187
+ // Note: Don't pass groupby to transformDataset - let getGroupedData handle grouping
188
+ // transformDataset with groupby produces {key: groupKey, data: [...]} structure
189
+ // which is incompatible with getGroupedData expecting {dataObject: {...}} structure
190
+ var normalizedData = (0, _react.useMemo)(function () {
191
+ return (0, _transformedDatasetUtils.transformDataset)(dataset, datafield, displayfield, displaylabel, displayexpression, props.orderby, undefined,
192
+ // Don't pre-group - getGroupedData will handle it
193
+ props.dataPath);
194
+ }, [dataset, datafield, displayfield, displaylabel, displayexpression, props.orderby, props.dataPath]);
174
195
  (0, _react.useEffect)(function () {
175
- // do not remove this code specifically handled for chips component for clearing the query.
176
- if (datavalue == "") {
196
+ // Handle clearing when datavalue becomes undefined or null
197
+ if (datavalue === undefined || datavalue === null || datavalue === "") {
177
198
  setQuery("");
199
+ setSelectedItem(null);
200
+ setFormattedDataset([]);
201
+ return;
202
+ }
203
+ if (((0, _isPlainObject["default"])(datavalue) || Array.isArray(datavalue)) && searchkey && Object.keys(datavalue).length > 0) {
204
+ var _value = Array.isArray(datavalue) ? datavalue[0] : datavalue;
205
+ if (_value) {
206
+ var key = searchkey.split(",")[0] || searchkey;
207
+ var item = (getDisplayExpression === null || getDisplayExpression === void 0 ? void 0 : getDisplayExpression(_value)) || _value[key];
208
+ if (item) {
209
+ setQuery(item);
210
+ handleUpdateDatavalue(_value);
211
+ }
212
+ }
213
+ } else if (datafield !== "All Fields" && datafield) {
214
+ var findItem = normalizedData === null || normalizedData === void 0 ? void 0 : normalizedData.find(function (item) {
215
+ return item.value === datavalue;
216
+ });
217
+ if (findItem) {
218
+ var _displayValue = (getDisplayExpression === null || getDisplayExpression === void 0 ? void 0 : getDisplayExpression(getSelectedItem(findItem))) || findItem.label;
219
+ setQuery(_displayValue);
220
+ handleUpdateDatavalue(findItem);
221
+ } else {
222
+ var _debouncedSearchItemR;
223
+ (_debouncedSearchItemR = debouncedSearchItemRef.current) === null || _debouncedSearchItemR === void 0 || _debouncedSearchItemR.call(debouncedSearchItemRef, datavalue);
224
+ }
225
+ }
226
+ // do not remove this code specifically handled for chips component for clearing the query.
227
+ else if (!(0, _isPlainObject["default"])(datavalue)) {
228
+ setQuery(datavalue);
178
229
  }
179
230
  }, [datavalue]);
180
231
 
@@ -184,9 +235,61 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
184
235
  }, styles), conditionalstyles);
185
236
 
186
237
  // Create dataProvider instance
187
- var dataProvider = (0, _react.useMemo)(function () {
188
- return new _providers.DataProvider();
189
- }, []);
238
+
239
+ // Initialize debounced searchItem function
240
+ (0, _react.useEffect)(function () {
241
+ // Cancel previous debounced function if it exists
242
+ if (debouncedSearchItemRef.current) {
243
+ debouncedSearchItemRef.current.cancel();
244
+ }
245
+
246
+ // Create debounced version of searchItem
247
+ debouncedSearchItemRef.current = (0, _debounce["default"])(/*#__PURE__*/function () {
248
+ var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(value) {
249
+ var response, key, findItem, _displayValue2;
250
+ return _regenerator["default"].wrap(function _callee$(_context) {
251
+ while (1) switch (_context.prev = _context.next) {
252
+ case 0:
253
+ _context.next = 2;
254
+ return dataProvider === null || dataProvider === void 0 ? void 0 : dataProvider.invokeVariable(props, value);
255
+ case 2:
256
+ response = _context.sent;
257
+ if (!(response && response.length > 0)) {
258
+ _context.next = 9;
259
+ break;
260
+ }
261
+ key = (searchkey === null || searchkey === void 0 ? void 0 : searchkey.split(",")[0]) || searchkey;
262
+ if (key) {
263
+ _context.next = 7;
264
+ break;
265
+ }
266
+ return _context.abrupt("return");
267
+ case 7:
268
+ findItem = response.find(function (item) {
269
+ return item[key] == value;
270
+ });
271
+ if (findItem && Object.keys(findItem).length > 0) {
272
+ _displayValue2 = (getDisplayExpression === null || getDisplayExpression === void 0 ? void 0 : getDisplayExpression(getSelectedItem(findItem))) || findItem[key];
273
+ setQuery(_displayValue2);
274
+ }
275
+ case 9:
276
+ case "end":
277
+ return _context.stop();
278
+ }
279
+ }, _callee);
280
+ }));
281
+ return function (_x) {
282
+ return _ref.apply(this, arguments);
283
+ };
284
+ }(), 200);
285
+
286
+ // Cleanup: cancel debounced function on unmount or dependency change
287
+ return function () {
288
+ if (debouncedSearchItemRef.current) {
289
+ debouncedSearchItemRef.current.cancel();
290
+ }
291
+ };
292
+ }, [dataProvider, props, searchkey, getDisplayExpression]);
190
293
 
191
294
  // Focus input on mount
192
295
  (0, _react.useEffect)(function () {
@@ -194,6 +297,11 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
194
297
  var _inputRef$current;
195
298
  (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
196
299
  }
300
+ if (listener && listener.onChange) {
301
+ listener.onChange(name, {
302
+ clearSearch: handleClearSearch
303
+ });
304
+ }
197
305
  }, []);
198
306
 
199
307
  // Handle shortcut key
@@ -217,20 +325,29 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
217
325
  if (type === "autocomplete") {
218
326
  getDataSource("");
219
327
  }
220
- }, [type]);
221
-
222
- // Update listen query state when type changes
223
- (0, _react.useEffect)(function () {
328
+ // Update listen query state when type changes
224
329
  setListenQuery(type === "autocomplete");
225
330
  }, [type]);
331
+ (0, _react.useEffect)(function () {
332
+ if (type !== "autocomplete" || !(normalizedData !== null && normalizedData !== void 0 && normalizedData.length)) {
333
+ return;
334
+ }
335
+ (0, _react.startTransition)(function () {
336
+ setFormattedDataset(normalizedData);
337
+ if (props !== null && props !== void 0 && props.groupby) {
338
+ setGroupedData(getGroupedData(normalizedData));
339
+ }
340
+ });
341
+ }, [normalizedData]);
226
342
  var getGroupedData = (0, _react.useCallback)(function (data) {
227
343
  if (props !== null && props !== void 0 && props.groupby && data !== null && data !== void 0 && data.length) {
228
344
  var result = {};
229
345
  data.forEach(function (item) {
346
+ var _item$dataObject;
230
347
  if (!(props !== null && props !== void 0 && props.groupby)) {
231
348
  return;
232
349
  }
233
- var groupKey = item[props === null || props === void 0 ? void 0 : props.groupby] || "ungrouped";
350
+ var groupKey = item[props === null || props === void 0 ? void 0 : props.groupby] || (item === null || item === void 0 || (_item$dataObject = item.dataObject) === null || _item$dataObject === void 0 ? void 0 : _item$dataObject[props === null || props === void 0 ? void 0 : props.groupby]) || "ungrouped";
234
351
  if (!result[groupKey]) {
235
352
  result[groupKey] = [];
236
353
  }
@@ -243,22 +360,27 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
243
360
  };
244
361
  }, [props === null || props === void 0 ? void 0 : props.groupby]);
245
362
  var getDataSource = (0, _react.useCallback)(/*#__PURE__*/function () {
246
- var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(query, nextPage) {
247
- var normalizedData, dataConfig, _isUpdateRequired, _response, dataSet, localDataProvider, response, data, isLastPage;
248
- return _regenerator["default"].wrap(function _callee$(_context) {
249
- while (1) switch (_context.prev = _context.next) {
363
+ var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(query, nextPage) {
364
+ var dataConfig, _isUpdateRequired, _response, dataSet, localDataProvider, response, data, isLastPage;
365
+ return _regenerator["default"].wrap(function _callee2$(_context2) {
366
+ while (1) switch (_context2.prev = _context2.next) {
250
367
  case 0:
368
+ if (!(nextPage && isLoadingNextPageRef.current)) {
369
+ _context2.next = 2;
370
+ break;
371
+ }
372
+ return _context2.abrupt("return", []);
373
+ case 2:
251
374
  if (!(!query && (type === "search" || type === "autocomplete" && !nextPage))) {
252
- _context.next = 5;
375
+ _context2.next = 7;
253
376
  break;
254
377
  }
255
378
  setFormattedDataset([]);
256
379
  setIsOpen(false);
257
380
  setMenuOpen(false);
258
- return _context.abrupt("return", []);
259
- case 5:
260
- normalizedData = (0, _transformedDatasetUtils.transformDataset)(dataset, datafield, displayfield, displaylabel, displayexpression, props.orderby, props.groupby, props.dataPath);
261
- dataConfig = {
381
+ return _context2.abrupt("return", []);
382
+ case 7:
383
+ dataConfig = _objectSpread(_objectSpread({}, props), {}, {
262
384
  dataset: normalizedData,
263
385
  datafield: datafield || "All Fields",
264
386
  query: query,
@@ -266,40 +388,51 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
266
388
  casesensitive: false,
267
389
  searchKey: searchkey,
268
390
  isformfield: false,
269
- limit: limit,
270
391
  page: nextPage ? page + 1 : 1,
271
392
  isLocalFilter: true,
272
- onBeforeservicecall: onBeforeservicecall
273
- };
274
- _context.prev = 7;
393
+ onBeforeservicecall: onBeforeservicecall,
394
+ groupby: props.groupby,
395
+ orderby: props.orderby,
396
+ limit: limit
397
+ }); // Set loading flag for pagination requests
398
+ if (nextPage) {
399
+ isLoadingNextPageRef.current = true;
400
+ setPage(function (prev) {
401
+ return prev + 1;
402
+ });
403
+ }
404
+ _context2.prev = 9;
275
405
  setLoadingItems(true);
276
406
  _isUpdateRequired = updateRequired;
277
407
  if (searchkey && updateRequired === undefined) {
278
- _isUpdateRequired = dataProvider.init(props);
408
+ _isUpdateRequired = dataProvider.init(dataConfig);
279
409
  setUpdateRequired(_isUpdateRequired);
280
410
  }
281
411
 
282
412
  // Handle remote search if required
283
413
  if (!(searchkey && _isUpdateRequired)) {
284
- _context.next = 31;
414
+ _context2.next = 32;
285
415
  break;
286
416
  }
287
- _context.prev = 12;
288
- _context.next = 15;
289
- return dataProvider === null || dataProvider === void 0 ? void 0 : dataProvider.invokeVariable(props, query);
290
- case 15:
291
- _response = _context.sent;
292
- setLoadingItems(false);
417
+ _context2.prev = 14;
418
+ _context2.next = 17;
419
+ return dataProvider === null || dataProvider === void 0 ? void 0 : dataProvider.invokeVariable(dataConfig, query);
420
+ case 17:
421
+ _response = _context2.sent;
293
422
  if (!_response) {
294
- _context.next = 23;
423
+ _context2.next = 23;
295
424
  break;
296
425
  }
297
426
  dataSet = Array.isArray(_response) ? _response : [_response];
298
- setFormattedDataset(dataSet);
299
-
300
- // Group data if grouping is enabled
301
- if (props !== null && props !== void 0 && props.groupby) {
427
+ if (!nextPage) {
428
+ setFormattedDataset(dataSet);
302
429
  setGroupedData(getGroupedData(dataSet));
430
+ } else {
431
+ setFormattedDataset(function (prev) {
432
+ var updatedDataset = [].concat((0, _toConsumableArray2["default"])(prev), (0, _toConsumableArray2["default"])(dataSet));
433
+ setGroupedData(getGroupedData(updatedDataset));
434
+ return updatedDataset;
435
+ });
303
436
  }
304
437
 
305
438
  // Update UI state based on results
@@ -310,31 +443,35 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
310
443
  setIsOpen(false);
311
444
  setMenuOpen(false);
312
445
  }
313
- return _context.abrupt("return", dataSet);
446
+ return _context2.abrupt("return", dataSet);
314
447
  case 23:
315
- _context.next = 30;
448
+ _context2.next = 31;
316
449
  break;
317
450
  case 25:
318
- _context.prev = 25;
319
- _context.t0 = _context["catch"](12);
451
+ _context2.prev = 25;
452
+ _context2.t0 = _context2["catch"](14);
320
453
  setLoadingItems(false);
321
454
  setIsOpen(false);
322
455
  setMenuOpen(false);
456
+ // Reset scroll flag on error so user can try again
457
+ if (nextPage) {
458
+ setIsScrolled(false);
459
+ }
323
460
  // TODO: call a toast here
324
- case 30:
325
- return _context.abrupt("return", []);
326
461
  case 31:
462
+ return _context2.abrupt("return", []);
463
+ case 32:
327
464
  if (!(!normalizedData || normalizedData.length === 0)) {
328
- _context.next = 33;
465
+ _context2.next = 34;
329
466
  break;
330
467
  }
331
- return _context.abrupt("return", []);
332
- case 33:
468
+ return _context2.abrupt("return", []);
469
+ case 34:
333
470
  localDataProvider = new _providers.LocalDataProvider();
334
- _context.next = 36;
471
+ _context2.next = 37;
335
472
  return localDataProvider.filter(dataConfig);
336
- case 36:
337
- response = _context.sent;
473
+ case 37:
474
+ response = _context2.sent;
338
475
  data = response.data, isLastPage = response.isLastPage; // Update hasMoreData state based on results
339
476
  setHasMoreData(data.length > 0 && !isLastPage);
340
477
  if (!nextPage) {
@@ -342,14 +479,11 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
342
479
  setGroupedData(getGroupedData(data));
343
480
  } else {
344
481
  setFormattedDataset(function (prev) {
345
- return [].concat((0, _toConsumableArray2["default"])(prev), (0, _toConsumableArray2["default"])(data));
482
+ var updatedDataset = [].concat((0, _toConsumableArray2["default"])(prev), (0, _toConsumableArray2["default"])(data));
483
+ setGroupedData(getGroupedData(updatedDataset));
484
+ return updatedDataset;
346
485
  });
347
- setGroupedData(getGroupedData([].concat((0, _toConsumableArray2["default"])(formattedDataset), (0, _toConsumableArray2["default"])(data))));
348
486
  }
349
- setPage(function (prev) {
350
- return nextPage ? prev + 1 : 1;
351
- });
352
- setIsScrolled(false);
353
487
 
354
488
  // Show dropdown if we have results
355
489
  if (data.length > 0) {
@@ -361,54 +495,79 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
361
495
  if (onDatasetready && listener !== null && listener !== void 0 && listener.Widgets && name && name in listener.Widgets) {
362
496
  onDatasetready(listener.Widgets[name], data);
363
497
  }
364
- return _context.abrupt("return", data);
365
- case 47:
366
- _context.prev = 47;
367
- _context.t1 = _context["catch"](7);
368
- console.error("Error fetching data:", _context.t1);
369
- return _context.abrupt("return", []);
370
- case 51:
371
- _context.prev = 51;
498
+ return _context2.abrupt("return", data);
499
+ case 46:
500
+ _context2.prev = 46;
501
+ _context2.t1 = _context2["catch"](9);
502
+ console.error("Error fetching data:", _context2.t1);
503
+ return _context2.abrupt("return", []);
504
+ case 50:
505
+ _context2.prev = 50;
372
506
  setLoadingItems(false);
373
- return _context.finish(51);
507
+ // Reset pagination loading flag and scroll state
508
+ if (nextPage) {
509
+ isLoadingNextPageRef.current = false;
510
+ setIsScrolled(false);
511
+ }
512
+ return _context2.finish(50);
374
513
  case 54:
375
514
  case "end":
376
- return _context.stop();
515
+ return _context2.stop();
377
516
  }
378
- }, _callee, null, [[7, 47, 51, 54], [12, 25]]);
517
+ }, _callee2, null, [[9, 46, 50, 54], [14, 25]]);
379
518
  }));
380
- return function (_x, _x2) {
381
- return _ref.apply(this, arguments);
519
+ return function (_x2, _x3) {
520
+ return _ref2.apply(this, arguments);
382
521
  };
383
522
  }(), [dataset, datafield, matchmode, searchkey, limit, onBeforeservicecall, page, formattedDataset, getGroupedData, type, onDatasetready, listener === null || listener === void 0 ? void 0 : listener.Widgets, name]);
384
523
 
385
- // First, modify getDataSourceAsObservable to handle the state updates properly
386
- var getDataSourceDebounced = (0, _react.useMemo)(function () {
387
- return (0, _lodash.debounce)(/*#__PURE__*/function () {
388
- var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(query) {
389
- var data;
390
- return _regenerator["default"].wrap(function _callee2$(_context2) {
391
- while (1) switch (_context2.prev = _context2.next) {
524
+ // Keep ref updated with latest getDataSource
525
+ (0, _react.useEffect)(function () {
526
+ getDataSourceRef.current = getDataSource;
527
+ }, [getDataSource]);
528
+
529
+ // Initialize or update the debounced function when dependencies change
530
+ // Note: Using ref for getDataSource to prevent debounced function recreation on every render
531
+ (0, _react.useEffect)(function () {
532
+ // Cancel previous debounced function if it exists
533
+ if (debouncedSearchRef.current) {
534
+ debouncedSearchRef.current.cancel();
535
+ }
536
+
537
+ // Create new debounced function - uses ref to always get latest getDataSource
538
+ debouncedSearchRef.current = (0, _debounce["default"])(/*#__PURE__*/function () {
539
+ var _ref3 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3(query) {
540
+ var _getDataSourceRef$cur, data;
541
+ return _regenerator["default"].wrap(function _callee3$(_context3) {
542
+ while (1) switch (_context3.prev = _context3.next) {
392
543
  case 0:
393
544
  if (query) {
394
- _context2.next = 5;
545
+ _context3.next = 5;
395
546
  break;
396
547
  }
397
548
  setFormattedDataset([]);
398
549
  setIsOpen(false);
399
550
  setMenuOpen(false);
400
- return _context2.abrupt("return");
551
+ return _context3.abrupt("return");
401
552
  case 5:
402
553
  if (!(query.length >= minchars)) {
403
- _context2.next = 22;
554
+ _context3.next = 25;
404
555
  break;
405
556
  }
406
- _context2.prev = 6;
557
+ _context3.prev = 6;
407
558
  setLoadingItems(true);
408
- _context2.next = 10;
409
- return getDataSource(query);
559
+ // Use ref to get latest getDataSource function
560
+ _context3.next = 10;
561
+ return (_getDataSourceRef$cur = getDataSourceRef.current) === null || _getDataSourceRef$cur === void 0 ? void 0 : _getDataSourceRef$cur.call(getDataSourceRef, query);
410
562
  case 10:
411
- data = _context2.sent;
563
+ _context3.t0 = _context3.sent;
564
+ if (_context3.t0) {
565
+ _context3.next = 13;
566
+ break;
567
+ }
568
+ _context3.t0 = [];
569
+ case 13:
570
+ data = _context3.t0;
412
571
  setLoadingItems(false);
413
572
 
414
573
  // Update the formatted dataset first
@@ -422,37 +581,55 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
422
581
  setIsOpen(false);
423
582
  setMenuOpen(false);
424
583
  }
425
- _context2.next = 22;
584
+ _context3.next = 25;
426
585
  break;
427
- case 16:
428
- _context2.prev = 16;
429
- _context2.t0 = _context2["catch"](6);
430
- console.error("Error in search:", _context2.t0);
586
+ case 19:
587
+ _context3.prev = 19;
588
+ _context3.t1 = _context3["catch"](6);
589
+ console.error("Error in search:", _context3.t1);
431
590
  setLoadingItems(false);
432
591
  setIsOpen(false);
433
592
  setMenuOpen(false);
434
- case 22:
593
+ case 25:
435
594
  case "end":
436
- return _context2.stop();
595
+ return _context3.stop();
437
596
  }
438
- }, _callee2, null, [[6, 16]]);
597
+ }, _callee3, null, [[6, 19]]);
439
598
  }));
440
- return function (_x3) {
441
- return _ref2.apply(this, arguments);
599
+ return function (_x4) {
600
+ return _ref3.apply(this, arguments);
442
601
  };
443
602
  }(), debouncetime);
444
- }, [getDataSource, minchars, debouncetime]);
603
+
604
+ // Cleanup: cancel debounced function on unmount or dependency change
605
+ return function () {
606
+ if (debouncedSearchRef.current) {
607
+ debouncedSearchRef.current.cancel();
608
+ }
609
+ };
610
+ }, [minchars, debouncetime]); // Removed getDataSource - now using ref
445
611
 
446
612
  // listen to query change and trigger debounced search
447
613
  (0, _react.useEffect)(function () {
448
614
  if (query && (type === "autocomplete" && listenQuery || type === "search" && searchon === "typing")) {
449
- getDataSourceDebounced(query);
615
+ var _debouncedSearchRef$c;
616
+ // Call the persisted debounced function
617
+ (_debouncedSearchRef$c = debouncedSearchRef.current) === null || _debouncedSearchRef$c === void 0 || _debouncedSearchRef$c.call(debouncedSearchRef, query);
450
618
  }
451
- }, [query]);
619
+ }, [query, type, listenQuery, searchon]);
620
+ function clearDataValue() {
621
+ var _listener$onChange;
622
+ listener === null || listener === void 0 || (_listener$onChange = listener.onChange) === null || _listener$onChange === void 0 || _listener$onChange.call(listener, props.fieldName || name, {
623
+ datavalue: ""
624
+ });
625
+ }
452
626
 
453
627
  // Simplify handleInputChange to only update query
454
628
  var handleInputChange = function handleInputChange(event) {
455
629
  var _event$target;
630
+ if (readonly || disabled) {
631
+ return;
632
+ }
456
633
  var queryValue = (event === null || event === void 0 || (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.value) || "";
457
634
  setQuery(queryValue);
458
635
 
@@ -461,30 +638,28 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
461
638
  onChange(event, listener.Widgets[name], queryValue, queryValue);
462
639
  }
463
640
 
464
- // Clear results and close dropdown if query is empty
641
+ // Handle empty query - for autocomplete show all options, for search close dropdown
465
642
  if (!queryValue) {
466
- setFormattedDataset([]);
467
643
  setSelectedItem(null);
468
- setIsOpen(false);
469
- setMenuOpen(false);
470
644
  if (onClear && listener !== null && listener !== void 0 && listener.Widgets && name && name in (listener === null || listener === void 0 ? void 0 : listener.Widgets)) {
471
645
  onClear(event, listener.Widgets[name]);
472
646
  }
473
- if (listener !== null && listener !== void 0 && listener.onChange) {
474
- listener.onChange(name, {
475
- datavalue: {}
476
- });
647
+ clearDataValue();
648
+ // For autocomplete type, show all options when query is cleared
649
+ if (type === "autocomplete" && normalizedData && normalizedData.length > 0) {
650
+ setFormattedDataset(normalizedData);
651
+ if (props !== null && props !== void 0 && props.groupby) {
652
+ setGroupedData(getGroupedData(normalizedData));
653
+ }
654
+ setIsOpen(true);
655
+ setMenuOpen(true);
656
+ } else {
657
+ setFormattedDataset([]);
658
+ setIsOpen(false);
659
+ setMenuOpen(false);
477
660
  }
478
661
  return;
479
662
  }
480
-
481
- // For autocomplete type, only show dropdown if we meet minimum chars
482
- if (type === "autocomplete" && queryValue.length < minchars) {
483
- setFormattedDataset([]);
484
- setIsOpen(false);
485
- setMenuOpen(false);
486
- return;
487
- }
488
663
  };
489
664
  var handleKeyDown = function handleKeyDown(event) {
490
665
  if (event.key === "Enter") {
@@ -506,6 +681,9 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
506
681
  if (onSubmit && listener !== null && listener !== void 0 && listener.Widgets && name && name in listener.Widgets) {
507
682
  onSubmit(event, listener.Widgets[name]);
508
683
  }
684
+ if (props.isSearchInChips) {
685
+ setQuery("");
686
+ }
509
687
  }
510
688
  } else if (event.key === "ArrowDown") {
511
689
  event.preventDefault();
@@ -515,41 +693,74 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
515
693
  setMenuOpen(false);
516
694
  }
517
695
  };
696
+ (0, _react.useEffect)(function () {
697
+ var handler = function handler(event) {
698
+ // Use currentTarget to always refer to the element on which the event listener is registered
699
+ var target = event.currentTarget;
700
+ // Consider it "at the bottom" if within 1px of the bottom (to deal with floating point inaccuracies)
701
+ if (target.scrollHeight - target.scrollTop - target.clientHeight <= 1) {
702
+ // Cast a synthetic event that looks like React's UIEvent if needed, otherwise just call with event
703
+ handleScroll(event);
704
+ }
705
+ };
706
+ if (listRef.current) {
707
+ listRef.current.addEventListener("scroll", handler);
708
+ }
709
+ return function () {
710
+ if (listRef.current) {
711
+ listRef.current.removeEventListener("scroll", handler);
712
+ }
713
+ };
714
+ }, [hasMoreData]);
518
715
  var handleClearSearch = function handleClearSearch(event) {
519
716
  var _inputRef$current3;
520
717
  setQuery("");
521
- setIsOpen(false);
522
- setMenuOpen(false);
523
718
  setSelectedItem(null);
524
- setFormattedDataset([]);
525
719
  if (onClear && listener !== null && listener !== void 0 && listener.Widgets && name && name in listener.Widgets) {
526
720
  onClear(event, listener.Widgets[name]);
527
721
  }
722
+ clearDataValue();
723
+ // For autocomplete type, show all options after clearing
724
+ if (type === "autocomplete" && normalizedData && normalizedData.length > 0) {
725
+ setFormattedDataset(normalizedData);
726
+ if (props !== null && props !== void 0 && props.groupby) {
727
+ setGroupedData(getGroupedData(normalizedData));
728
+ }
729
+ setIsOpen(true);
730
+ setMenuOpen(true);
731
+ } else {
732
+ setFormattedDataset([]);
733
+ setIsOpen(false);
734
+ setMenuOpen(false);
735
+ }
528
736
 
529
737
  // Focus back on input
530
738
  (_inputRef$current3 = inputRef.current) === null || _inputRef$current3 === void 0 || _inputRef$current3.focus();
531
739
  };
532
740
  var handleClickAway = function handleClickAway(e) {
533
- setIsOpen(false);
534
- setMenuOpen(false);
535
- handleBlur(e);
741
+ if (isOpen) {
742
+ setIsOpen(false);
743
+ setMenuOpen(false);
744
+ handleBlur(e);
745
+ }
536
746
  };
537
747
  var handleFocus = function handleFocus(event) {
538
- // For autocomplete type
748
+ // For autocomplete type - show all options on focus
539
749
  if (type === "autocomplete") {
540
750
  // If we already have results, show them
541
- if (formattedDataset.length > 0) {
751
+ if (formattedDataset.length > 0 && !selectedItem) {
542
752
  setIsOpen(true);
543
753
  setMenuOpen(true);
544
754
  }
545
- // If we have a query that meets minimum length, search with it
546
- else {
547
- setLoadingItems(true);
548
- var normalizedData = (0, _transformedDatasetUtils.transformDataset)(dataset, datafield, displayfield, displaylabel, displayexpression, props.orderby, props.groupby);
755
+ // Show all data on focus (use normalizedData which is already computed)
756
+ else if (normalizedData && normalizedData.length > 0) {
549
757
  setFormattedDataset(normalizedData);
758
+ // Update grouped data if groupby is specified
759
+ if (props !== null && props !== void 0 && props.groupby) {
760
+ setGroupedData(getGroupedData(normalizedData));
761
+ }
550
762
  setIsOpen(true);
551
763
  setMenuOpen(true);
552
- setLoadingItems(false);
553
764
  }
554
765
  }
555
766
 
@@ -561,8 +772,9 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
561
772
  var handleBlur = function handleBlur(event) {
562
773
  // Don't close dropdown immediately to allow click events on menu items
563
774
  setTimeout(function () {
564
- var _dropdownRef$current2;
565
- if (document.activeElement !== dropdownRef.current && !((_dropdownRef$current2 = dropdownRef.current) !== null && _dropdownRef$current2 !== void 0 && _dropdownRef$current2.contains(document.activeElement))) {
775
+ var _dropdownRef$current2, _searchButtonRef$curr;
776
+ var activeElement = document.activeElement;
777
+ if (document.activeElement !== dropdownRef.current && !((_dropdownRef$current2 = dropdownRef.current) !== null && _dropdownRef$current2 !== void 0 && _dropdownRef$current2.contains(activeElement)) && !((_searchButtonRef$curr = searchButtonRef.current) !== null && _searchButtonRef$curr !== void 0 && _searchButtonRef$curr.contains(activeElement))) {
566
778
  setIsOpen(false);
567
779
  setMenuOpen(false);
568
780
  }
@@ -572,6 +784,8 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
572
784
  }
573
785
  };
574
786
  var handleSearchClick = function handleSearchClick(event) {
787
+ event.preventDefault();
788
+ event.stopPropagation();
575
789
  // Reset hasMoreData state before new search
576
790
  setHasMoreData(true);
577
791
 
@@ -607,42 +821,62 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
607
821
  firstMatch.focus();
608
822
  }
609
823
  };
824
+ function handleUpdateDatavalue(item) {
825
+ var updatedItem = getSelectedItem(item);
826
+ var value = datafield === "All Fields" ? updatedItem : updatedItem === null || updatedItem === void 0 ? void 0 : updatedItem[datafield];
827
+ if (listener !== null && listener !== void 0 && listener.onChange) {
828
+ listener.onChange(props.fieldName || name, {
829
+ datavalue: value
830
+ });
831
+ }
832
+ }
833
+ function getSelectedItem(item) {
834
+ var _item$dataObject2;
835
+ return (item === null || item === void 0 || (_item$dataObject2 = item.dataObject) === null || _item$dataObject2 === void 0 ? void 0 : _item$dataObject2.dataObject) || (item === null || item === void 0 ? void 0 : item.dataObject) || item;
836
+ }
610
837
  var handleMatchSelect = function handleMatchSelect(match) {
838
+ if (readonly || disabled) {
839
+ return;
840
+ }
611
841
  var itemData = match.getAttribute("data-item");
612
842
  if (!itemData) return;
613
843
  try {
614
844
  var item = JSON.parse(itemData);
845
+ var _selectedItem = getSelectedItem(item);
615
846
 
616
847
  // Set display value in input
617
- var displayVal = item.displayValue || item.label;
618
- setQuery(displayVal);
848
+ var displayVal = (getDisplayExpression === null || getDisplayExpression === void 0 ? void 0 : getDisplayExpression(_selectedItem)) || item.displayValue || item.label;
849
+ if (props.isSearchInChips) {
850
+ setQuery("");
851
+ } else {
852
+ setQuery(displayVal);
853
+ }
619
854
  setIsOpen(false);
620
855
  setMenuOpen(false);
621
856
  setSelectedItem(item); // Set the selected item
622
857
  setFormattedDataset([]); // Clear the dropdown dataset
623
858
  if (onChange && listener !== null && listener !== void 0 && listener.Widgets && name && name in (listener === null || listener === void 0 ? void 0 : listener.Widgets)) {
624
- var _item$dataObject, _item$dataObject2;
625
- onChange(undefined, listener.Widgets[name], (_item$dataObject = item.dataObject) === null || _item$dataObject === void 0 ? void 0 : _item$dataObject.value, (_item$dataObject2 = item.dataObject) === null || _item$dataObject2 === void 0 ? void 0 : _item$dataObject2.value);
859
+ var _item$dataObject3, _item$dataObject4;
860
+ onChange(undefined, listener.Widgets[name], (_item$dataObject3 = item.dataObject) === null || _item$dataObject3 === void 0 ? void 0 : _item$dataObject3.value, (_item$dataObject4 = item.dataObject) === null || _item$dataObject4 === void 0 ? void 0 : _item$dataObject4.value);
626
861
  }
627
- if (listener !== null && listener !== void 0 && listener.onChange) {
628
- listener.onChange(name, {
629
- datavalue: item.dataObject.value
630
- });
862
+ if (!props.isSearchInChips) {
863
+ handleUpdateDatavalue(item);
631
864
  }
632
865
 
633
866
  // Trigger onSelect callback if provided
634
867
  if (onSelect && listener !== null && listener !== void 0 && listener.Widgets && name && name in listener.Widgets) {
635
- onSelect(new MouseEvent("click"), listener.Widgets[name], item);
868
+ onSelect(new MouseEvent("click"), props, item);
869
+ props.onSubmit && !props.isSearchInChips && props.onSubmit(new MouseEvent("click"), props);
636
870
  }
637
871
  } catch (error) {
638
872
  console.error("Error parsing item data:", error);
639
873
  }
640
874
  };
641
- var handleMenuItemClick = function handleMenuItemClick(event) {
875
+ var handleMenuItemClick = function handleMenuItemClick(event, item) {
642
876
  handleMatchSelect(event.currentTarget);
643
877
  };
644
878
  var handleScroll = function handleScroll(event) {
645
- if (!loadingItems && !isScrolled && hasMoreData && !selectedItem) {
879
+ if (!loadingItems && !isScrolled && !isLoadingNextPageRef.current && hasMoreData && !selectedItem) {
646
880
  var target = event.target;
647
881
  if (target.scrollHeight - target.scrollTop <= target.clientHeight + 50) {
648
882
  setIsScrolled(true);
@@ -723,7 +957,7 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
723
957
  if (fieldValue != null) return String(fieldValue);
724
958
 
725
959
  // Fallback to first object value
726
- var firstValue = Object.values(item).find(function (val) {
960
+ var firstValue = !(props.groupby && props.isSearchInChips) && Object.values(item).find(function (val) {
727
961
  return val != null;
728
962
  });
729
963
  return firstValue ? String(firstValue) : "";
@@ -731,13 +965,20 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
731
965
  var displayValue = getDisplayValue();
732
966
  var keyFields = [datafield && datafield !== "All Fields" ? datafield : null, "id", "key", "value"];
733
967
  var keyValue = findFieldValue(keyFields, index);
734
- var displayImage = displayimagesrc && item[displayimagesrc] ? item[displayimagesrc] : null;
968
+ var imageSrc = null;
969
+ if (typeof displayimagesrc === "function") {
970
+ var _ref4, _item$dataObject$data, _item$dataObject5;
971
+ imageSrc = displayimagesrc((_ref4 = (_item$dataObject$data = item === null || item === void 0 || (_item$dataObject5 = item.dataObject) === null || _item$dataObject5 === void 0 ? void 0 : _item$dataObject5.dataObject) !== null && _item$dataObject$data !== void 0 ? _item$dataObject$data : item === null || item === void 0 ? void 0 : item.dataObject) !== null && _ref4 !== void 0 ? _ref4 : item);
972
+ } else {
973
+ var _item$dataObject6, _item$dataObject7;
974
+ imageSrc = displayimagesrc && (_item$dataObject6 = item.dataObject) !== null && _item$dataObject6 !== void 0 && _item$dataObject6[displayimagesrc] ? (_item$dataObject7 = item.dataObject) === null || _item$dataObject7 === void 0 ? void 0 : _item$dataObject7[displayimagesrc] : null;
975
+ }
735
976
  return {
736
977
  key: keyValue,
737
978
  value: item,
738
979
  label: displayValue,
739
980
  displayValue: displayValue,
740
- displayImage: displayImage,
981
+ displayImage: imageSrc,
741
982
  dataObject: item
742
983
  };
743
984
  };
@@ -771,9 +1012,12 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
771
1012
 
772
1013
  // Get the display text
773
1014
  var displayText = typeof dataItem.displayValue === "string" ? _dompurify["default"].sanitize(dataItem.displayValue) : String(dataItem.label);
1015
+ function handleClick(event) {
1016
+ handleMenuItemClick(event, dataItem);
1017
+ }
774
1018
  return __jsx(_MenuItem["default"], {
775
1019
  key: "item-".concat(index, "-").concat(dataItem.key),
776
- onClick: handleMenuItemClick,
1020
+ onClick: handleClick,
777
1021
  "data-item": JSON.stringify(dataItem),
778
1022
  dense: true,
779
1023
  className: "search-dropdown-item",
@@ -792,13 +1036,14 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
792
1036
  width: parseInt(imagewidth) || 16,
793
1037
  height: parseInt(imagewidth) || 16,
794
1038
  style: {
795
- marginRight: "8px"
1039
+ marginRight: "8px",
1040
+ borderRadius: "100%"
796
1041
  }
797
1042
  }), __jsx(_material.Box, {
798
1043
  component: "span",
799
1044
  className: "",
800
1045
  title: displayText
801
- }, highlightMatch(displayText, query))));
1046
+ }, getDisplayExpression ? highlightMatch(getDisplayExpression(getSelectedItem(item)), query) : highlightMatch(displayText, query))));
802
1047
  };
803
1048
 
804
1049
  // Update renderItems to handle non-array cases
@@ -834,10 +1079,7 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
834
1079
  // Ensure formattedDataset is an array before mapping
835
1080
  var formattedArray = Array.isArray(formattedDataset) ? formattedDataset : [];
836
1081
  return formattedArray.map(function (item, index) {
837
- if (index < limit) {
838
- return renderItem(item, query, index);
839
- }
840
- return null;
1082
+ return renderItem(item, query, index);
841
1083
  }).filter(Boolean); // Remove null values
842
1084
  };
843
1085
  var renderClearButton = function renderClearButton() {
@@ -859,9 +1101,10 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
859
1101
  var renderSearchIcon = function renderSearchIcon() {
860
1102
  if (showsearchicon) {
861
1103
  return __jsx(_material.Button, {
1104
+ ref: searchButtonRef,
862
1105
  className: "app-search-button btn btn-icon",
863
1106
  title: "search",
864
- type: "submit",
1107
+ type: "button",
865
1108
  onClick: handleSearchClick,
866
1109
  disabled: disabled,
867
1110
  size: "small"
@@ -956,15 +1199,16 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
956
1199
  },
957
1200
  className: "search-dropdown-container"
958
1201
  }, __jsx(_MenuList["default"], {
959
- className: "search-menu-list app-search dropdown-menu"
1202
+ className: "search-menu-list app-search dropdown-menu",
1203
+ ref: listRef
960
1204
  }, renderItems(), renderNoResultsMessage(), renderLoadingIndicator(), renderCompletionMessage()))));
961
1205
  };
962
1206
 
963
1207
  // Only include safe props in restProps to avoid React warnings
964
- var safeRestProps = Object.entries(restProps).reduce(function (acc, _ref3) {
965
- var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
966
- key = _ref4[0],
967
- value = _ref4[1];
1208
+ var safeRestProps = Object.entries(restProps).reduce(function (acc, _ref5) {
1209
+ var _ref6 = (0, _slicedToArray2["default"])(_ref5, 2),
1210
+ key = _ref6[0],
1211
+ value = _ref6[1];
968
1212
  // Filter out any props that might cause DOM warnings
969
1213
  var invalidProps = ["validation", "datasetItems", "selectedItems", "displayValue", "onchange", "onblur", "groupedData", "handleHeaderClick", "toggleAllHeaders", "isDestroyed"];
970
1214
  if (!invalidProps.includes(key)) {
@@ -982,7 +1226,8 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
982
1226
  }, safeRestProps, {
983
1227
  className: (0, _clsx["default"])(DEFAULT_CLASS, className),
984
1228
  "data-search-type": type,
985
- type: type
1229
+ type: type,
1230
+ readonly: readonly
986
1231
  }), renderBackButton(), __jsx(_material.Box, {
987
1232
  component: "span",
988
1233
  className: "sr-only"
@@ -993,7 +1238,7 @@ var Search = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
993
1238
  type: "text",
994
1239
  "focus-target": "true",
995
1240
  value: query,
996
- onChange: handleInputChange,
1241
+ onChange: !readonly ? handleInputChange : undefined,
997
1242
  disabled: disabled,
998
1243
  tabIndex: tabindex,
999
1244
  ref: inputRef,