@reltio/components 1.4.2162 → 1.4.2164

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 (73) hide show
  1. package/AddressAutocompleteEditor/AddressAutocompleteEditor.js +123 -55
  2. package/AddressAutocompleteEditor/AddressAutocompleteEditor.module.css.js +2 -2
  3. package/AddressAutocompleteEditor/AddressAutocompleteEditor.test.js +101 -5
  4. package/AddressAutocompleteEditor/helpers.d.ts +1 -0
  5. package/AddressAutocompleteEditor/helpers.js +3 -0
  6. package/FacetGroup/FacetGroup.d.ts +7 -0
  7. package/FacetGroup/FacetGroup.js +9 -0
  8. package/FacetGroup/FacetGroup.module.css.js +9 -0
  9. package/FacetGroup/index.d.ts +1 -0
  10. package/FacetGroup/index.js +1 -0
  11. package/FacetGroupTitle/FacetGroupTitle.d.ts +8 -0
  12. package/FacetGroupTitle/FacetGroupTitle.js +13 -0
  13. package/FacetGroupTitle/FacetGroupTitle.module.css.js +9 -0
  14. package/FacetGroupTitle/index.d.ts +1 -0
  15. package/FacetGroupTitle/index.js +1 -0
  16. package/MoreAttributesButton/styles.d.ts +1 -1
  17. package/QuickFiltersEntityTypeFacet/QuickFiltersEntityTypeFacet.d.ts +13 -0
  18. package/QuickFiltersEntityTypeFacet/QuickFiltersEntityTypeFacet.js +17 -0
  19. package/QuickFiltersEntityTypeFacet/QuickFiltersEntityTypeFacet.module.css.js +9 -0
  20. package/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/EntityTypesFacetGroups.d.ts +12 -0
  21. package/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/EntityTypesFacetGroups.js +49 -0
  22. package/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/EntityTypesFacetGroups.module.css.js +9 -0
  23. package/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/index.d.ts +1 -0
  24. package/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/index.js +1 -0
  25. package/QuickFiltersEntityTypeFacet/components/EntityTypesList/EntityTypesList.d.ts +10 -0
  26. package/QuickFiltersEntityTypeFacet/components/EntityTypesList/EntityTypesList.js +39 -0
  27. package/QuickFiltersEntityTypeFacet/components/EntityTypesList/EntityTypesList.module.css.js +9 -0
  28. package/QuickFiltersEntityTypeFacet/components/EntityTypesList/index.d.ts +1 -0
  29. package/QuickFiltersEntityTypeFacet/components/EntityTypesList/index.js +1 -0
  30. package/QuickFiltersEntityTypeFacet/index.d.ts +2 -0
  31. package/QuickFiltersEntityTypeFacet/index.js +1 -0
  32. package/QuickFiltersEntityTypeFacet/types.d.ts +5 -0
  33. package/QuickFiltersEntityTypeFacet/types.js +1 -0
  34. package/cjs/AddressAutocompleteEditor/AddressAutocompleteEditor.js +120 -52
  35. package/cjs/AddressAutocompleteEditor/AddressAutocompleteEditor.module.css.js +2 -2
  36. package/cjs/AddressAutocompleteEditor/AddressAutocompleteEditor.test.js +101 -5
  37. package/cjs/AddressAutocompleteEditor/helpers.d.ts +1 -0
  38. package/cjs/AddressAutocompleteEditor/helpers.js +5 -1
  39. package/cjs/FacetGroup/FacetGroup.d.ts +7 -0
  40. package/cjs/FacetGroup/FacetGroup.js +16 -0
  41. package/cjs/FacetGroup/FacetGroup.module.css.js +9 -0
  42. package/cjs/FacetGroup/index.d.ts +1 -0
  43. package/cjs/FacetGroup/index.js +5 -0
  44. package/cjs/FacetGroupTitle/FacetGroupTitle.d.ts +8 -0
  45. package/cjs/FacetGroupTitle/FacetGroupTitle.js +20 -0
  46. package/cjs/FacetGroupTitle/FacetGroupTitle.module.css.js +9 -0
  47. package/cjs/FacetGroupTitle/index.d.ts +1 -0
  48. package/cjs/FacetGroupTitle/index.js +5 -0
  49. package/cjs/MoreAttributesButton/styles.d.ts +1 -1
  50. package/cjs/QuickFiltersEntityTypeFacet/QuickFiltersEntityTypeFacet.d.ts +13 -0
  51. package/cjs/QuickFiltersEntityTypeFacet/QuickFiltersEntityTypeFacet.js +47 -0
  52. package/cjs/QuickFiltersEntityTypeFacet/QuickFiltersEntityTypeFacet.module.css.js +9 -0
  53. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/EntityTypesFacetGroups.d.ts +12 -0
  54. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/EntityTypesFacetGroups.js +79 -0
  55. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/EntityTypesFacetGroups.module.css.js +9 -0
  56. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/index.d.ts +1 -0
  57. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesFacetGroups/index.js +5 -0
  58. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesList/EntityTypesList.d.ts +10 -0
  59. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesList/EntityTypesList.js +69 -0
  60. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesList/EntityTypesList.module.css.js +9 -0
  61. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesList/index.d.ts +1 -0
  62. package/cjs/QuickFiltersEntityTypeFacet/components/EntityTypesList/index.js +5 -0
  63. package/cjs/QuickFiltersEntityTypeFacet/index.d.ts +2 -0
  64. package/cjs/QuickFiltersEntityTypeFacet/index.js +5 -0
  65. package/cjs/QuickFiltersEntityTypeFacet/types.d.ts +5 -0
  66. package/cjs/QuickFiltersEntityTypeFacet/types.js +2 -0
  67. package/cjs/contexts/AutoCompleteContext/helpers.js +2 -2
  68. package/cjs/index.d.ts +3 -0
  69. package/cjs/index.js +11 -5
  70. package/contexts/AutoCompleteContext/helpers.js +3 -3
  71. package/index.d.ts +3 -0
  72. package/index.js +3 -0
  73. package/package.json +2 -2
@@ -56,31 +56,43 @@ var __rest = (this && this.__rest) || function (s, e) {
56
56
  }
57
57
  return t;
58
58
  };
59
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
60
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
61
+ if (ar || !(i in from)) {
62
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
63
+ ar[i] = from[i];
64
+ }
65
+ }
66
+ return to.concat(ar || Array.prototype.slice.call(from));
67
+ };
59
68
  import React, { useState, useCallback, useMemo, useContext, useEffect } from 'react';
60
69
  import classnames from 'classnames';
61
- import { identity } from 'ramda';
70
+ import { identity, path } from 'ramda';
62
71
  import { useContextSelector } from '@fluentui/react-context-selector';
63
72
  import Autocomplete from '@mui/material/Autocomplete';
64
- import ListItem from '@mui/material/ListItem';
65
- import ListItemText from '@mui/material/ListItemText';
73
+ import Button from '@mui/material/Button';
74
+ import ChevronRightIcon from '@mui/icons-material/ChevronRight';
66
75
  import LinearProgress from '@mui/material/LinearProgress';
67
- import Typography from '@mui/material/Typography';
76
+ import ListItemButton from '@mui/material/ListItemButton';
68
77
  import TextField from '@mui/material/TextField';
69
- import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
78
+ import Typography from '@mui/material/Typography';
70
79
  import i18n from 'ui-i18n';
71
- import { searchAddresses, fetchAddressDetails, debounce, AddressType } from '@reltio/mdm-sdk';
80
+ import { searchAddresses, fetchAddressDetails, debounce, AddressType, isEmptyValue } from '@reltio/mdm-sdk';
72
81
  import { AddressAutoCompleteContext } from '../contexts/AutoCompleteContext';
73
82
  import { AttributeValueContext } from '../contexts/AttributeValueContext';
74
- import { convertSearchResultToOption, getOptionLabel, isOptionEqualToValue } from './helpers';
83
+ import { convertSearchResultToOption, getOptionLabel, isMinLength, isOptionEqualToValue } from './helpers';
75
84
  import { useSafePromise } from '../hooks/useSafePromise';
85
+ import { ExpandedValueTooltip } from '../ExpandedValueTooltip';
86
+ import { EmptySearchResult } from '../EmptySearchResult';
76
87
  import styles from './AddressAutocompleteEditor.module.css';
77
88
  export var INPUT_DEBOUNCE_INTERVAL = 400;
89
+ var EMPTY_OPTION_ID = 'empty_option_id';
78
90
  export var AddressAutocompleteEditor = function (_a) {
79
91
  var _b = _a.value, value = _b === void 0 ? '' : _b, onChange = _a.onChange, InputProps = _a.InputProps, _c = _a.fullWidth, fullWidth = _c === void 0 ? true : _c, otherProps = __rest(_a, ["value", "onChange", "InputProps", "fullWidth"]);
80
92
  var _d = useState(value), inputValue = _d[0], setInputValue = _d[1];
81
- var _e = useState([]), options = _e[0], setOptions = _e[1];
82
- var _f = useState(false), loading = _f[0], setLoading = _f[1];
83
- var _g = useState(false), detailsLoading = _g[0], setDetailsLoading = _g[1];
93
+ var _e = useState(null), options = _e[0], setOptions = _e[1];
94
+ var _f = useState([]), previousOptions = _f[0], setPreviousOptions = _f[1];
95
+ var _g = useState(false), loading = _g[0], setLoading = _g[1];
84
96
  var _h = useState(false), open = _h[0], setOpen = _h[1];
85
97
  var searchSafePromise = useSafePromise();
86
98
  var detailsSafePromise = useSafePromise();
@@ -91,45 +103,61 @@ export var AddressAutocompleteEditor = function (_a) {
91
103
  var countries = autocompleteSettings.countries, countryNames = autocompleteSettings.countryNames, limit = autocompleteSettings.limit, minSearchTextLen = autocompleteSettings.minSearchTextLen;
92
104
  var countriesHash = countries.toString();
93
105
  useEffect(function () {
94
- setOptions([]);
106
+ setOptions(null);
107
+ setPreviousOptions([]);
95
108
  }, [countriesHash]);
96
- var fetchAddressSuggestions = useCallback(function (searchTerm) { return __awaiter(void 0, void 0, void 0, function () {
97
- var results, convertedOptions, error_1;
98
- return __generator(this, function (_a) {
99
- switch (_a.label) {
109
+ var fetchAddressSuggestions = useCallback(function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
110
+ var results, _c, convertedOptions, error_1;
111
+ var searchTerm = _b.searchTerm, container = _b.container;
112
+ return __generator(this, function (_d) {
113
+ switch (_d.label) {
100
114
  case 0:
101
115
  setLoading(true);
102
- _a.label = 1;
116
+ _d.label = 1;
103
117
  case 1:
104
- _a.trys.push([1, 3, 4, 5]);
105
- return [4 /*yield*/, searchSafePromise(searchAddresses({
106
- text: searchTerm,
107
- limit: limit,
108
- countries: countries
109
- }))];
118
+ _d.trys.push([1, 6, 7, 8]);
119
+ if (!container) return [3 /*break*/, 3];
120
+ return [4 /*yield*/, searchSafePromise(searchAddresses({ container: container }))];
110
121
  case 2:
111
- results = _a.sent();
122
+ _c = _d.sent();
123
+ return [3 /*break*/, 5];
124
+ case 3: return [4 /*yield*/, searchSafePromise(searchAddresses({
125
+ text: searchTerm,
126
+ limit: limit,
127
+ countries: countries
128
+ }))];
129
+ case 4:
130
+ _c = _d.sent();
131
+ _d.label = 5;
132
+ case 5:
133
+ results = _c;
112
134
  convertedOptions = results.map(convertSearchResultToOption);
135
+ if (container) {
136
+ setPreviousOptions(options || []);
137
+ }
138
+ else {
139
+ setPreviousOptions([]);
140
+ }
113
141
  setOptions(convertedOptions);
114
- return [3 /*break*/, 5];
115
- case 3:
116
- error_1 = _a.sent();
142
+ return [3 /*break*/, 8];
143
+ case 6:
144
+ error_1 = _d.sent();
117
145
  console.warn('Error fetching address suggestions:', error_1);
118
146
  setOptions([]);
119
- return [3 /*break*/, 5];
120
- case 4:
147
+ return [3 /*break*/, 8];
148
+ case 7:
121
149
  setLoading(false);
122
150
  return [7 /*endfinally*/];
123
- case 5: return [2 /*return*/];
151
+ case 8: return [2 /*return*/];
124
152
  }
125
153
  });
126
- }); }, [countries, limit, searchSafePromise]);
154
+ }); }, [countries, limit, searchSafePromise, options]);
127
155
  var fetchAddressDetailsById = useCallback(function (addressId) { return __awaiter(void 0, void 0, void 0, function () {
128
156
  var error_2;
129
157
  return __generator(this, function (_a) {
130
158
  switch (_a.label) {
131
159
  case 0:
132
- setDetailsLoading(true);
160
+ setLoading(true);
133
161
  _a.label = 1;
134
162
  case 1:
135
163
  _a.trys.push([1, 3, 4, 5]);
@@ -138,9 +166,9 @@ export var AddressAutocompleteEditor = function (_a) {
138
166
  case 3:
139
167
  error_2 = _a.sent();
140
168
  console.warn('Error fetching address details:', error_2);
141
- return [2 /*return*/, null];
169
+ return [3 /*break*/, 5];
142
170
  case 4:
143
- setDetailsLoading(false);
171
+ setLoading(false);
144
172
  return [7 /*endfinally*/];
145
173
  case 5: return [2 /*return*/];
146
174
  }
@@ -149,13 +177,17 @@ export var AddressAutocompleteEditor = function (_a) {
149
177
  var debouncedFetchAddressSuggestions = useCallback(debounce(fetchAddressSuggestions, INPUT_DEBOUNCE_INTERVAL), [
150
178
  fetchAddressSuggestions
151
179
  ]);
152
- var handleInputChange = useCallback(function (event, newInputValue) {
180
+ var handleInputChange = useCallback(function (event, newInputValue, reason) {
181
+ if (reason === 'reset') {
182
+ return;
183
+ }
153
184
  setInputValue(newInputValue);
154
- if (newInputValue.trim().length >= minSearchTextLen) {
155
- debouncedFetchAddressSuggestions(newInputValue);
185
+ if (isMinLength(newInputValue, minSearchTextLen)) {
186
+ debouncedFetchAddressSuggestions({ searchTerm: newInputValue });
156
187
  }
157
188
  else {
158
189
  setOptions([]);
190
+ setPreviousOptions([]);
159
191
  }
160
192
  }, [debouncedFetchAddressSuggestions, minSearchTextLen]);
161
193
  var handleOptionSelect = useCallback(function (event, selectedOption) { return __awaiter(void 0, void 0, void 0, function () {
@@ -165,9 +197,11 @@ export var AddressAutocompleteEditor = function (_a) {
165
197
  case 0:
166
198
  if (!selectedOption) return [3 /*break*/, 3];
167
199
  if (selectedOption.type === AddressType.Container) {
200
+ fetchAddressSuggestions({ container: selectedOption.id });
168
201
  return [2 /*return*/];
169
202
  }
170
203
  setInputValue(selectedOption.fullAddress);
204
+ setPreviousOptions([]);
171
205
  if (onChange) {
172
206
  onChange(selectedOption.fullAddress);
173
207
  }
@@ -189,35 +223,69 @@ export var AddressAutocompleteEditor = function (_a) {
189
223
  case 4: return [2 /*return*/];
190
224
  }
191
225
  });
192
- }); }, [fetchAddressDetailsById, onChange, onPopulateAttributes, attributeTypeUri, valueUri]);
226
+ }); }, [fetchAddressDetailsById, fetchAddressSuggestions, onChange, onPopulateAttributes, attributeTypeUri, valueUri]);
227
+ var handleFocus = useCallback(function () {
228
+ if (!options && isMinLength(inputValue, minSearchTextLen)) {
229
+ debouncedFetchAddressSuggestions({ searchTerm: inputValue });
230
+ }
231
+ setOpen(true);
232
+ }, [debouncedFetchAddressSuggestions, inputValue, minSearchTextLen, options]);
193
233
  var handleBlur = useCallback(function () {
194
234
  setOpen(false);
195
235
  }, []);
196
236
  var renderOption = useCallback(function (props, option) {
197
237
  var _a;
238
+ if (option.id === EMPTY_OPTION_ID) {
239
+ return null;
240
+ }
198
241
  var isContainer = option.type === AddressType.Container;
199
- return (React.createElement(ListItem, __assign({}, props, { className: classnames(styles.option, (_a = {}, _a[styles.containerOption] = isContainer, _a)) }),
200
- React.createElement(ListItemText, { primary: option.fullAddress, primaryTypographyProps: { variant: 'body1' }, secondaryTypographyProps: { variant: 'body2', color: 'textSecondary' } }),
201
- isContainer && (React.createElement("div", null,
202
- React.createElement(ArrowForwardIosIcon, null)))));
203
- }, []);
204
- var renderInput = useCallback(function (props) { return (React.createElement(TextField, __assign({}, otherProps, props, { placeholder: i18n.text('Start typing to autocomplete'), fullWidth: fullWidth, onBlur: handleBlur, InputProps: __assign(__assign(__assign({}, InputProps), props.InputProps), { endAdornment: React.createElement(React.Fragment, null, props.InputProps.endAdornment) }) }))); }, [fullWidth, handleBlur, InputProps, otherProps]);
242
+ return (React.createElement(ListItemButton, __assign({}, props, { className: classnames(styles.option, (_a = {}, _a[styles.containerOption] = isContainer, _a)), component: "li", disabled: loading }),
243
+ React.createElement(ExpandedValueTooltip, { value: option.fullAddress },
244
+ React.createElement(Typography, { variant: "body2", className: styles.optionText }, option.fullAddress)),
245
+ isContainer && (React.createElement("div", { className: styles.containerForwardIcon },
246
+ React.createElement(ChevronRightIcon, null)))));
247
+ }, [loading]);
248
+ var renderInput = useCallback(function (props) {
249
+ var _a;
250
+ return (React.createElement(TextField, __assign({}, props, otherProps, { placeholder: i18n.text('Start typing to autocomplete'), fullWidth: fullWidth, onBlur: handleBlur, InputProps: __assign(__assign(__assign({}, props.InputProps), InputProps), { classes: __assign(__assign({}, InputProps === null || InputProps === void 0 ? void 0 : InputProps.classes), { root: classnames(styles.textFieldRoot, path(['classes', 'root'], InputProps)), input: classnames(styles.textFieldInput, path(['classes', 'input'], InputProps)), underline: classnames((_a = {}, _a[styles.underline] = isEmptyValue(value), _a)) }) }) })));
251
+ }, [fullWidth, handleBlur, InputProps, otherProps, value]);
252
+ var handleBackToAllSearchResults = useCallback(function () {
253
+ setOptions(previousOptions);
254
+ setPreviousOptions([]);
255
+ }, [previousOptions]);
205
256
  var renderListbox = useCallback(React.forwardRef(function ListboxComponent(props, ref) {
206
- return (React.createElement(React.Fragment, null,
207
- detailsLoading && React.createElement(LinearProgress, { color: "primary" }),
208
- React.createElement("ul", __assign({ ref: ref }, props),
209
- React.createElement("li", { className: styles.countryHeader },
210
- React.createElement(Typography, { variant: "body2", fontWeight: 500 },
257
+ var onMouseDown = props.onMouseDown, restProps = __rest(props, ["onMouseDown"]);
258
+ var shouldShowEmptyState = (options === null || options === void 0 ? void 0 : options.length) === 0 && isMinLength(inputValue, minSearchTextLen) && !loading;
259
+ var shouldShowMinLengthMessage = !isMinLength(inputValue, minSearchTextLen) && !loading;
260
+ var shouldShowOptions = (options === null || options === void 0 ? void 0 : options.length) > 0 && !shouldShowMinLengthMessage;
261
+ var countriesLabel = countryNames.join(', ');
262
+ return (React.createElement("div", { onMouseDown: onMouseDown },
263
+ loading && React.createElement(LinearProgress, { className: styles.loadingProgress, color: "primary" }),
264
+ React.createElement("div", { className: styles.countryHeader },
265
+ React.createElement(ExpandedValueTooltip, { value: countriesLabel },
266
+ React.createElement(Typography, { variant: "body2", color: "textSecondary", className: styles.headerCountries },
211
267
  i18n.text('Searching in'),
212
268
  ": ",
213
- countryNames.join(', ')),
214
- React.createElement(Typography, { variant: "caption", color: "textSecondary" }, i18n.text('To search in a different country, update the Country field'))),
215
- props.children)));
216
- }), [detailsLoading, countryNames]);
269
+ countriesLabel)),
270
+ React.createElement(Typography, { variant: "caption", color: "textSecondary", className: styles.headerHelper }, i18n.text('To search in a different country, update the Country field'))),
271
+ React.createElement("ul", __assign({ ref: ref }, restProps, { className: styles.listbox }),
272
+ shouldShowMinLengthMessage && (React.createElement("li", { className: styles.emptyState },
273
+ React.createElement(Typography, { variant: "body2", color: "textSecondary" }, i18n.text('Please enter at least ${minSearchTextLen} characters', {
274
+ minSearchTextLen: minSearchTextLen
275
+ })))),
276
+ shouldShowEmptyState && (React.createElement("li", { className: styles.emptyState },
277
+ React.createElement(EmptySearchResult, { className: styles.noData }))),
278
+ shouldShowOptions && props.children),
279
+ previousOptions.length > 0 && (React.createElement("div", { className: styles.backToAllResults },
280
+ React.createElement(Button, { variant: "text", onClick: handleBackToAllSearchResults, color: "primary", disabled: loading, classes: { root: styles.backToAllResultsButton } }, i18n.text('Back to all results'))))));
281
+ }), [loading, countryNames, previousOptions.length, (options || []).length, inputValue, minSearchTextLen]);
217
282
  var openOptionsList = useCallback(function (_event) {
218
283
  setOpen(true);
219
284
  }, []);
220
- return (React.createElement(Autocomplete, { className: styles.root, open: open, onOpen: openOptionsList, value: inputValue, onChange: handleOptionSelect, inputValue: inputValue, onInputChange: handleInputChange, options: options, getOptionLabel: getOptionLabel, loading: loading, renderInput: renderInput, renderOption: renderOption, renderGroup: function (params) { return params.children; }, ListboxComponent: renderListbox, noOptionsText: inputValue.trim().length < minSearchTextLen
221
- ? i18n.text('Please enter at least {{minSearchTextLen}} characters', { minSearchTextLen: minSearchTextLen })
222
- : i18n.text('No addresses found'), loadingText: i18n.text('Searching addresses...'), filterOptions: identity, isOptionEqualToValue: isOptionEqualToValue, popupIcon: null, clearIcon: null, freeSolo: true, "data-reltio-id": "address-autocomplete-editor" }));
285
+ var displayOptions = useMemo(function () {
286
+ return __spreadArray([{ id: EMPTY_OPTION_ID, type: AddressType.Address, fullAddress: '' }], (options || []), true);
287
+ }, [options]);
288
+ return (React.createElement(Autocomplete, { className: styles.root, open: open, onOpen: openOptionsList, value: inputValue, onChange: handleOptionSelect, inputValue: inputValue, onInputChange: handleInputChange, onFocus: handleFocus, options: displayOptions, getOptionLabel: getOptionLabel, renderInput: renderInput, renderOption: renderOption, renderGroup: function (params) { return params.children; }, ListboxComponent: renderListbox, classes: {
289
+ paper: styles.popupContainer
290
+ }, filterOptions: identity, isOptionEqualToValue: isOptionEqualToValue, popupIcon: null, clearIcon: null, freeSolo: true, "data-reltio-id": "address-autocomplete-editor" }));
223
291
  };
@@ -1,9 +1,9 @@
1
- const styles = {"root":"AddressAutocompleteEditor-root--1FDrD","countryHeader":"AddressAutocompleteEditor-countryHeader--k5tRp","loadingContainer":"AddressAutocompleteEditor-loadingContainer--j-U45","option":"AddressAutocompleteEditor-option--3hah-","containerOption":"AddressAutocompleteEditor-containerOption--aLgUn","listbox":"AddressAutocompleteEditor-listbox--cZCpg"};
1
+ const styles = {"root":"AddressAutocompleteEditor-root--1FDrD","textFieldRoot":"AddressAutocompleteEditor-textFieldRoot--udDvK","textFieldInput":"AddressAutocompleteEditor-textFieldInput--Xf-Cf","underline":"AddressAutocompleteEditor-underline--ZNYqN","countryHeader":"AddressAutocompleteEditor-countryHeader--k5tRp","headerCountries":"AddressAutocompleteEditor-headerCountries--WoYl5","headerHelper":"AddressAutocompleteEditor-headerHelper--XPT5S","loadingState":"AddressAutocompleteEditor-loadingState--PRwRK","emptyState":"AddressAutocompleteEditor-emptyState--s8M04","option":"AddressAutocompleteEditor-option--3hah-","popupContainer":"AddressAutocompleteEditor-popupContainer--360Kv","listbox":"AddressAutocompleteEditor-listbox--cZCpg","optionText":"AddressAutocompleteEditor-optionText--IcsBw","containerForwardIcon":"AddressAutocompleteEditor-containerForwardIcon--Ke5rd","backToAllResults":"AddressAutocompleteEditor-backToAllResults--2wqzi","backToAllResultsButton":"AddressAutocompleteEditor-backToAllResultsButton--T5R-3","loadingProgress":"AddressAutocompleteEditor-loadingProgress--AfWtc"};
2
2
  if (typeof document !== 'undefined') {
3
3
  const head = document.head || document.getElementsByTagName('head')[0]
4
4
  const style = document.createElement('style');
5
5
  style.type = 'text/css'
6
- style.innerHTML = `.AddressAutocompleteEditor-root--1FDrD{width:100%}.AddressAutocompleteEditor-countryHeader--k5tRp{background-color:rgba(0,0,0,.04);border-bottom:1px solid rgba(0,0,0,.12);font-weight:500;padding:8px 16px}.AddressAutocompleteEditor-loadingContainer--j-U45{align-items:center;display:flex;justify-content:center;padding:16px}.AddressAutocompleteEditor-option--3hah-{padding:8px 16px}.AddressAutocompleteEditor-containerOption--aLgUn:hover{background-color:rgba(0,0,0,.04)!important}.AddressAutocompleteEditor-listbox--cZCpg{padding:0}`;
6
+ style.innerHTML = `.AddressAutocompleteEditor-root--1FDrD{width:100%}.AddressAutocompleteEditor-root--1FDrD .AddressAutocompleteEditor-textFieldRoot--udDvK{font-size:14px;padding:0}:is(.AddressAutocompleteEditor-root--1FDrD .AddressAutocompleteEditor-textFieldRoot--udDvK) .AddressAutocompleteEditor-textFieldInput--Xf-Cf{height:19px;line-height:19px;padding:10px 12px 11px!important}:is(.AddressAutocompleteEditor-root--1FDrD .AddressAutocompleteEditor-underline--ZNYqN):before{display:none}.AddressAutocompleteEditor-countryHeader--k5tRp{padding:12px 12px 8px}.AddressAutocompleteEditor-countryHeader--k5tRp .AddressAutocompleteEditor-headerCountries--WoYl5{font-size:12px;letter-spacing:0;margin-bottom:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.AddressAutocompleteEditor-countryHeader--k5tRp .AddressAutocompleteEditor-headerHelper--XPT5S{font-size:10px;letter-spacing:0}.AddressAutocompleteEditor-loadingState--PRwRK{padding:16px;text-align:center}.AddressAutocompleteEditor-emptyState--s8M04{padding:8px}.AddressAutocompleteEditor-option--3hah-{padding:4px 12px}.AddressAutocompleteEditor-popupContainer--360Kv{min-width:170px}.AddressAutocompleteEditor-listbox--cZCpg{margin:0;max-height:300px;overflow-y:auto;padding:0}.AddressAutocompleteEditor-listbox--cZCpg li:first-child{border-top:1px solid rgba(0,0,0,.12);padding-top:7px}.AddressAutocompleteEditor-optionText--IcsBw{font-size:14px;letter-spacing:.24px;line-height:16px;overflow:hidden;padding:4px 0;text-overflow:ellipsis;white-space:nowrap;width:100%}.AddressAutocompleteEditor-containerForwardIcon--Ke5rd{height:24px}.AddressAutocompleteEditor-backToAllResults--2wqzi{border-top:1px solid rgba(0,0,0,.12)}.AddressAutocompleteEditor-backToAllResultsButton--T5R-3{letter-spacing:0}.AddressAutocompleteEditor-loadingProgress--AfWtc{left:0;position:absolute;right:0;top:0}`;
7
7
  head.appendChild(style);
8
8
  }
9
9
  export default styles;
@@ -93,6 +93,14 @@ var mockAddressSearchResults = [
93
93
  Description: 'Jose Malhoa 22'
94
94
  }
95
95
  ];
96
+ var mockAddressContainerSearchResults = [
97
+ {
98
+ Id: 'container-1',
99
+ Type: AddressType.Container,
100
+ Text: 'Container Option',
101
+ Description: 'Container'
102
+ }
103
+ ];
96
104
  var mockAddressDetails = [
97
105
  {
98
106
  Id: 'address-1',
@@ -282,15 +290,34 @@ describe('AddressAutocompleteEditor', function () {
282
290
  return [4 /*yield*/, user.paste('Lisbon')];
283
291
  case 2:
284
292
  _a.sent();
285
- expect(screen.getByText('Searching addresses...')).toBeInTheDocument();
293
+ expect(screen.getByRole('progressbar')).toBeInTheDocument();
286
294
  resolveSearch([]);
287
- return [4 /*yield*/, waitForElementToBeRemoved(function () { return screen.queryByText('Searching addresses...'); })];
295
+ return [4 /*yield*/, waitForElementToBeRemoved(function () { return screen.queryByRole('progressbar'); })];
288
296
  case 3:
289
297
  _a.sent();
290
298
  return [2 /*return*/];
291
299
  }
292
300
  });
293
301
  }); });
302
+ it('should show empty state when no options are found', function () { return __awaiter(void 0, void 0, void 0, function () {
303
+ var user, input;
304
+ return __generator(this, function (_a) {
305
+ switch (_a.label) {
306
+ case 0:
307
+ mockSearchAddresses.mockResolvedValue([]);
308
+ user = setUp().user;
309
+ input = screen.getByRole('combobox');
310
+ return [4 /*yield*/, user.click(input)];
311
+ case 1:
312
+ _a.sent();
313
+ return [4 /*yield*/, user.paste('Lisbon')];
314
+ case 2:
315
+ _a.sent();
316
+ expect(screen.getByText('No results found')).toBeInTheDocument();
317
+ return [2 /*return*/];
318
+ }
319
+ });
320
+ }); });
294
321
  describe('Address search', function () {
295
322
  it('should fetch address suggestions when user types minimum characters', function () { return __awaiter(void 0, void 0, void 0, function () {
296
323
  var user, input;
@@ -378,9 +405,7 @@ describe('AddressAutocompleteEditor', function () {
378
405
  switch (_a.label) {
379
406
  case 0:
380
407
  onChange = jest.fn();
381
- mockSearchAddresses.mockResolvedValue([
382
- { Id: 'container-1', Type: AddressType.Container, Text: 'Container Option', Description: 'Container' }
383
- ]);
408
+ mockSearchAddresses.mockResolvedValue(mockAddressContainerSearchResults);
384
409
  user = setUp({ onChange: onChange }).user;
385
410
  input = screen.getByRole('combobox');
386
411
  return [4 /*yield*/, user.click(input)];
@@ -455,6 +480,76 @@ describe('AddressAutocompleteEditor', function () {
455
480
  }
456
481
  });
457
482
  }); });
483
+ it('should request address list for container options', function () { return __awaiter(void 0, void 0, void 0, function () {
484
+ var onChange, user, input, option;
485
+ return __generator(this, function (_a) {
486
+ switch (_a.label) {
487
+ case 0:
488
+ onChange = jest.fn();
489
+ mockSearchAddresses.mockResolvedValue(mockAddressContainerSearchResults);
490
+ user = setUp({ onChange: onChange }).user;
491
+ input = screen.getByRole('combobox');
492
+ return [4 /*yield*/, user.click(input)];
493
+ case 1:
494
+ _a.sent();
495
+ return [4 /*yield*/, user.paste('Lisbon')];
496
+ case 2:
497
+ _a.sent();
498
+ expect(screen.getByText('Container Option')).toBeInTheDocument();
499
+ expect(mockSearchAddresses).toHaveBeenCalledWith({
500
+ text: 'Lisbon',
501
+ limit: 10,
502
+ countries: ['PT', 'US']
503
+ });
504
+ mockSearchAddresses.mockReset();
505
+ mockSearchAddresses.mockResolvedValue(mockAddressSearchResults);
506
+ option = screen.getByText('Container Option');
507
+ return [4 /*yield*/, user.click(option)];
508
+ case 3:
509
+ _a.sent();
510
+ expect(mockSearchAddresses).toHaveBeenCalledWith({
511
+ container: 'container-1'
512
+ });
513
+ expect(screen.getByText('Avenida Jose Malhoa 22, Lisbon')).toBeInTheDocument();
514
+ expect(screen.queryByText('Container Option')).not.toBeInTheDocument();
515
+ expect(onChange).not.toHaveBeenCalled();
516
+ expect(mockFetchAddressDetails).not.toHaveBeenCalled();
517
+ return [2 /*return*/];
518
+ }
519
+ });
520
+ }); });
521
+ it('should back to all search results after selecting container option', function () { return __awaiter(void 0, void 0, void 0, function () {
522
+ var onChange, user, input, option;
523
+ return __generator(this, function (_a) {
524
+ switch (_a.label) {
525
+ case 0:
526
+ onChange = jest.fn();
527
+ mockSearchAddresses.mockResolvedValue(mockAddressContainerSearchResults);
528
+ user = setUp({ onChange: onChange }).user;
529
+ input = screen.getByRole('combobox');
530
+ return [4 /*yield*/, user.click(input)];
531
+ case 1:
532
+ _a.sent();
533
+ return [4 /*yield*/, user.paste('Lisbon')];
534
+ case 2:
535
+ _a.sent();
536
+ expect(screen.queryByText('Back to all results')).not.toBeInTheDocument();
537
+ mockSearchAddresses.mockReset();
538
+ mockSearchAddresses.mockResolvedValue(mockAddressSearchResults);
539
+ option = screen.getByText('Container Option');
540
+ return [4 /*yield*/, user.click(option)];
541
+ case 3:
542
+ _a.sent();
543
+ expect(screen.getByText('Back to all results')).toBeInTheDocument();
544
+ return [4 /*yield*/, user.click(screen.getByText('Back to all results'))];
545
+ case 4:
546
+ _a.sent();
547
+ expect(screen.queryByText('Back to all results')).not.toBeInTheDocument();
548
+ expect(screen.getByText('Container Option')).toBeInTheDocument();
549
+ return [2 /*return*/];
550
+ }
551
+ });
552
+ }); });
458
553
  });
459
554
  describe('Autocomplete settings', function () {
460
555
  it('should use default autocomplete settings, when no settings from metadata', function () { return __awaiter(void 0, void 0, void 0, function () {
@@ -506,6 +601,7 @@ describe('AddressAutocompleteEditor', function () {
506
601
  case 2:
507
602
  _a.sent();
508
603
  expect(mockSearchAddresses).not.toHaveBeenCalled();
604
+ expect(screen.getByText('Please enter at least 3 characters')).toBeInTheDocument();
509
605
  return [4 /*yield*/, user.paste('sbon')];
510
606
  case 3:
511
607
  _a.sent();
@@ -8,3 +8,4 @@ export type AddressOption = {
8
8
  export declare const convertSearchResultToOption: (result: AddressSearchResult) => AddressOption;
9
9
  export declare const getOptionLabel: (option: AddressOption | string) => string;
10
10
  export declare const isOptionEqualToValue: (option: AddressOption, value: string) => boolean;
11
+ export declare const isMinLength: (value: string, minLength: number) => boolean;
@@ -16,3 +16,6 @@ export var isOptionEqualToValue = function (option, value) {
16
16
  }
17
17
  return option.fullAddress === value;
18
18
  };
19
+ export var isMinLength = function (value, minLength) {
20
+ return (value === null || value === void 0 ? void 0 : value.trim().length) >= minLength;
21
+ };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ type Props = {
3
+ children?: React.ReactNode;
4
+ title?: string;
5
+ };
6
+ export declare const FacetGroup: ({ children, title }: Props) => React.JSX.Element;
7
+ export {};
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { FacetGroupTitle } from '../FacetGroupTitle';
3
+ import styles from './FacetGroup.module.css';
4
+ export var FacetGroup = function (_a) {
5
+ var children = _a.children, _b = _a.title, title = _b === void 0 ? '' : _b;
6
+ return (React.createElement("div", { className: styles.facetGroupContainer },
7
+ React.createElement(FacetGroupTitle, { title: title }),
8
+ children));
9
+ };
@@ -0,0 +1,9 @@
1
+ const styles = {"facetGroupContainer":"FacetGroup-facetGroupContainer--r4EGm"};
2
+ if (typeof document !== 'undefined') {
3
+ const head = document.head || document.getElementsByTagName('head')[0]
4
+ const style = document.createElement('style');
5
+ style.type = 'text/css'
6
+ style.innerHTML = `.FacetGroup-facetGroupContainer--r4EGm{display:flex;flex-direction:column;flex-shrink:0}.FacetGroup-facetGroupContainer--r4EGm+.FacetGroup-facetGroupContainer--r4EGm,.FacetGroup-facetGroupContainer--r4EGm+hr{margin-top:8px}`;
7
+ head.appendChild(style);
8
+ }
9
+ export default styles;
@@ -0,0 +1 @@
1
+ export { FacetGroup } from './FacetGroup';
@@ -0,0 +1 @@
1
+ export { FacetGroup } from './FacetGroup';
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ type Props = {
3
+ title?: string;
4
+ iconSrc?: string;
5
+ leftIcon?: React.ReactNode;
6
+ };
7
+ export declare const FacetGroupTitle: ({ title, iconSrc, leftIcon }: Props) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import Avatar from '@mui/material/Avatar';
3
+ import { ExpandedValueTooltip } from '../ExpandedValueTooltip';
4
+ import styles from './FacetGroupTitle.module.css';
5
+ export var FacetGroupTitle = function (_a) {
6
+ var _b = _a.title, title = _b === void 0 ? '' : _b, _c = _a.iconSrc, iconSrc = _c === void 0 ? '' : _c, leftIcon = _a.leftIcon;
7
+ return (React.createElement("div", { className: styles.titleBox },
8
+ React.createElement("div", { className: styles.title },
9
+ leftIcon && React.createElement("div", { className: styles.leftIcon }, leftIcon),
10
+ iconSrc && React.createElement(Avatar, { src: iconSrc, className: styles.avatar }),
11
+ React.createElement(ExpandedValueTooltip, { value: title },
12
+ React.createElement("span", null, title)))));
13
+ };
@@ -0,0 +1,9 @@
1
+ const styles = {"titleBox":"FacetGroupTitle-titleBox--yg91y","title":"FacetGroupTitle-title--6MrZT","leftIcon":"FacetGroupTitle-leftIcon--ts7l3","avatar":"FacetGroupTitle-avatar--dgaa0"};
2
+ if (typeof document !== 'undefined') {
3
+ const head = document.head || document.getElementsByTagName('head')[0]
4
+ const style = document.createElement('style');
5
+ style.type = 'text/css'
6
+ style.innerHTML = `.FacetGroupTitle-titleBox--yg91y{align-items:center;display:flex;flex-direction:row;flex-shrink:0;justify-content:space-between;line-height:24px;padding-bottom:8px;padding-top:12px}.FacetGroupTitle-title--6MrZT{align-items:center;color:rgba(0,0,0,.87);display:flex;flex-grow:1;font-size:16px;font-weight:500;letter-spacing:.15px;overflow:hidden;padding-left:16px}.FacetGroupTitle-leftIcon--ts7l3{flex-shrink:0;margin-right:20px}.FacetGroupTitle-avatar--dgaa0{height:32px;margin-right:12px;width:32px}`;
7
+ head.appendChild(style);
8
+ }
9
+ export default styles;
@@ -0,0 +1 @@
1
+ export { FacetGroupTitle } from './FacetGroupTitle';
@@ -0,0 +1 @@
1
+ export { FacetGroupTitle } from './FacetGroupTitle';
@@ -1 +1 @@
1
- export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"dense" | "icon" | "subHeader" | "moreButton" | "buttonLabel" | "moreAttributes" | "popupContainer" | "moreAttributesPopup" | "noResultsCaptionContainer">;
1
+ export declare const useStyles: (props?: any) => import("@mui/styles").ClassNameMap<"dense" | "icon" | "subHeader" | "moreButton" | "buttonLabel" | "popupContainer" | "moreAttributes" | "moreAttributesPopup" | "noResultsCaptionContainer">;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { EntityTypeFacetDataItem } from '@reltio/mdm-sdk';
3
+ type Props = {
4
+ items: EntityTypeFacetDataItem[];
5
+ maxRowCount?: number;
6
+ showAllItems?: boolean;
7
+ values?: string[];
8
+ onChange?: (values?: string[]) => void;
9
+ onViewMoreLess: () => void;
10
+ countFormatter?: (number: number) => string;
11
+ };
12
+ export declare const QuickFiltersEntityTypeFacet: ({ items, maxRowCount, showAllItems, values, onChange, onViewMoreLess, countFormatter }: Props) => React.JSX.Element;
13
+ export {};
@@ -0,0 +1,17 @@
1
+ import React, { useMemo } from 'react';
2
+ import { identity } from 'ramda';
3
+ import { getGroupedEntityTypes } from '@reltio/mdm-sdk';
4
+ import { ViewMoreToggle } from '../ViewMoreToggle';
5
+ import { EmptySearchResult } from '../EmptySearchResult';
6
+ import { EntityTypesFacetGroups } from './components/EntityTypesFacetGroups';
7
+ import styles from './QuickFiltersEntityTypeFacet.module.css';
8
+ var DEFAULT_ROW_COUNT = 7;
9
+ export var QuickFiltersEntityTypeFacet = function (_a) {
10
+ var items = _a.items, _b = _a.maxRowCount, maxRowCount = _b === void 0 ? DEFAULT_ROW_COUNT : _b, showAllItems = _a.showAllItems, _c = _a.values, values = _c === void 0 ? [] : _c, _d = _a.onChange, onChange = _d === void 0 ? identity : _d, onViewMoreLess = _a.onViewMoreLess, countFormatter = _a.countFormatter;
11
+ var groups = useMemo(function () { return getGroupedEntityTypes(items); }, [items]);
12
+ var totalItems = groups.reduce(function (sum, group) { return sum + group.items.length; }, 0);
13
+ var needShowViewMoreButton = totalItems > maxRowCount;
14
+ return (React.createElement("div", { className: styles.container }, groups.length > 0 ? (React.createElement(React.Fragment, null,
15
+ React.createElement(EntityTypesFacetGroups, { groups: groups, values: values, maxRowCount: maxRowCount, onChange: onChange, showAll: showAllItems, countFormatter: countFormatter }),
16
+ needShowViewMoreButton && (React.createElement(ViewMoreToggle, { active: showAllItems, onClick: onViewMoreLess, className: styles.viewMoreLess })))) : (React.createElement(EmptySearchResult, { variant: "noData", className: styles.noData }))));
17
+ };
@@ -0,0 +1,9 @@
1
+ const styles = {"container":"QuickFiltersEntityTypeFacet-container--dVdDy","noData":"QuickFiltersEntityTypeFacet-noData--y-9iH","viewMoreLess":"QuickFiltersEntityTypeFacet-viewMoreLess--xgmjA"};
2
+ if (typeof document !== 'undefined') {
3
+ const head = document.head || document.getElementsByTagName('head')[0]
4
+ const style = document.createElement('style');
5
+ style.type = 'text/css'
6
+ style.innerHTML = `.QuickFiltersEntityTypeFacet-container--dVdDy{display:flex;flex-direction:column;flex-grow:1;font-size:13px;overflow:hidden}.QuickFiltersEntityTypeFacet-noData--y-9iH{margin-left:16px}.QuickFiltersEntityTypeFacet-viewMoreLess--xgmjA{padding-left:20px}`;
7
+ head.appendChild(style);
8
+ }
9
+ export default styles;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { EntityTypesGroup } from '../../types';
3
+ type Props = {
4
+ groups: EntityTypesGroup[];
5
+ values: string[];
6
+ maxRowCount: number;
7
+ showAll: boolean;
8
+ onChange: (values: string[]) => void;
9
+ countFormatter?: (number: number) => string;
10
+ };
11
+ export declare const EntityTypesFacetGroups: ({ groups, values, maxRowCount, showAll, onChange, countFormatter }: Props) => React.JSX.Element;
12
+ export {};