@steroidsjs/core 3.0.0-beta.98 → 3.0.0

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 (175) hide show
  1. package/actions/notifications.js +7 -1
  2. package/actions/router.js +16 -2
  3. package/components/HttpComponent.d.ts +7 -7
  4. package/components/JwtHttpComponent.d.ts +2 -2
  5. package/components/LocaleComponent.d.ts +6 -6
  6. package/components/MetaComponent.d.ts +90 -1
  7. package/components/MetricsComponent.js +2 -1
  8. package/components/ResourceComponent.d.ts +4 -4
  9. package/components/UiComponent.d.ts +7 -7
  10. package/components/WebSocketComponent.d.ts +11 -11
  11. package/docs-autogen-result.json +15226 -6277
  12. package/en.json +151 -84
  13. package/hooks/index.d.ts +4 -3
  14. package/hooks/index.js +7 -5
  15. package/hooks/useAbsolutePositioning.js +0 -1
  16. package/hooks/useAddressBar.js +0 -1
  17. package/hooks/useApplication.js +8 -1
  18. package/hooks/useDataProvider.d.ts +17 -2
  19. package/hooks/useDataSelect.js +21 -4
  20. package/hooks/useFetch.js +6 -1
  21. package/hooks/useFile.d.ts +1 -0
  22. package/hooks/useFile.js +2 -0
  23. package/hooks/useList.d.ts +53 -14
  24. package/hooks/useList.js +31 -70
  25. package/hooks/useTree.d.ts +104 -0
  26. package/hooks/useTree.js +169 -0
  27. package/index.d.ts +3 -3
  28. package/package.json +94 -93
  29. package/reducers/router.d.ts +2 -1
  30. package/ui/content/Accordion/Accordion.d.ts +8 -5
  31. package/ui/content/Accordion/Accordion.js +6 -1
  32. package/ui/content/Accordion/AccordionItem.d.ts +2 -2
  33. package/ui/content/Accordion/AccordionItem.js +1 -12
  34. package/ui/content/Alert/Alert.d.ts +5 -2
  35. package/ui/content/Alert/Alert.js +13 -12
  36. package/ui/content/Avatar/Avatar.js +18 -12
  37. package/ui/content/Badge/Badge.d.ts +5 -1
  38. package/ui/content/Badge/Badge.js +14 -12
  39. package/ui/content/Calendar/Calendar.d.ts +6 -1
  40. package/ui/content/Calendar/Calendar.js +19 -12
  41. package/ui/content/CalendarSystem/CalendarSystem.d.ts +94 -17
  42. package/ui/content/CalendarSystem/CalendarSystem.js +66 -77
  43. package/ui/content/CalendarSystem/hooks/useCalendarControls.d.ts +1 -2
  44. package/ui/content/CalendarSystem/hooks/useCalendarControls.js +14 -17
  45. package/ui/content/CalendarSystem/hooks/useCalendarSystemEventGroupModals.d.ts +2 -1
  46. package/ui/content/CalendarSystem/hooks/useCalendarSystemEventGroupModals.js +13 -5
  47. package/ui/content/CalendarSystem/hooks/useCalendarSystemModals.js +2 -2
  48. package/ui/content/CalendarSystem/hooks/useCalendarType.d.ts +5 -0
  49. package/ui/content/CalendarSystem/hooks/useCalendarType.js +22 -0
  50. package/ui/content/CalendarSystem/hooks/useEventsFromDate.d.ts +5 -0
  51. package/ui/content/CalendarSystem/hooks/useEventsFromDate.js +49 -0
  52. package/ui/content/CalendarSystem/hooks/{useMonthCalendar.d.ts → useMonthGrid.d.ts} +4 -5
  53. package/ui/content/CalendarSystem/hooks/{useMonthCalendar.js → useMonthGrid.js} +24 -15
  54. package/ui/content/CalendarSystem/hooks/{useWeekCalendar.d.ts → useWeekGrid.d.ts} +6 -5
  55. package/ui/content/CalendarSystem/hooks/useWeekGrid.js +72 -0
  56. package/ui/content/CalendarSystem/utils/utils.d.ts +8 -0
  57. package/ui/content/CalendarSystem/utils/utils.js +27 -1
  58. package/ui/content/Card/Card.d.ts +33 -27
  59. package/ui/content/Card/Card.js +1 -12
  60. package/ui/content/Chart/Chart.d.ts +38 -8
  61. package/ui/content/Chart/Chart.js +16 -12
  62. package/ui/content/Chat/Chat.d.ts +109 -0
  63. package/ui/content/Chat/Chat.js +52 -0
  64. package/ui/content/Chat/constants/timeTemplatesAndUnits.d.ts +8 -0
  65. package/ui/content/Chat/constants/timeTemplatesAndUnits.js +11 -0
  66. package/ui/content/Chat/hooks/useChat.d.ts +12 -0
  67. package/ui/content/Chat/hooks/useChat.js +58 -0
  68. package/ui/content/Chat/index.d.ts +2 -0
  69. package/ui/content/Chat/index.js +7 -0
  70. package/ui/content/Chat/utils/addNewMessageIntoGroupedMessages.d.ts +5 -0
  71. package/ui/content/Chat/utils/addNewMessageIntoGroupedMessages.js +61 -0
  72. package/ui/content/Chat/utils/calculateMessageTimeAgo.d.ts +1 -0
  73. package/ui/content/Chat/utils/calculateMessageTimeAgo.js +26 -0
  74. package/ui/content/Chat/utils/getMessagesGroupedByDate.d.ts +4 -0
  75. package/ui/content/Chat/utils/getMessagesGroupedByDate.js +56 -0
  76. package/ui/content/Chat/utils/index.d.ts +5 -0
  77. package/ui/content/Chat/utils/index.js +12 -0
  78. package/ui/content/Chat/utils/isTodayMessage.d.ts +1 -0
  79. package/ui/content/Chat/utils/isTodayMessage.js +13 -0
  80. package/ui/content/CopyToClipboard/CopyToClipboard.d.ts +3 -3
  81. package/ui/content/CopyToClipboard/CopyToClipboard.js +10 -12
  82. package/ui/content/Dashboard/Dashboard.d.ts +5 -2
  83. package/ui/content/Dashboard/Dashboard.js +27 -3
  84. package/ui/content/Detail/Detail.d.ts +15 -2
  85. package/ui/content/Detail/Detail.js +12 -1
  86. package/ui/content/DropDown/DropDown.d.ts +1 -1
  87. package/ui/content/DropDown/DropDown.js +16 -4
  88. package/ui/content/Icon/Icon.js +13 -15
  89. package/ui/content/Kanban/Kanban.d.ts +15 -4
  90. package/ui/content/Kanban/Kanban.js +8 -12
  91. package/ui/content/Kanban/hooks/useKanban.d.ts +33 -26
  92. package/ui/content/Menu/Menu.js +10 -12
  93. package/ui/content/Slider/Slider.js +1 -12
  94. package/ui/content/index.d.ts +2 -1
  95. package/ui/content/index.js +3 -1
  96. package/ui/crud/index.d.ts +3 -0
  97. package/ui/form/AutoCompleteField/AutoCompleteField.js +1 -1
  98. package/ui/form/Button/Button.js +8 -2
  99. package/ui/form/CheckboxField/CheckboxField.d.ts +1 -0
  100. package/ui/form/CheckboxField/CheckboxField.js +2 -2
  101. package/ui/form/CheckboxListField/CheckboxListField.d.ts +18 -2
  102. package/ui/form/CheckboxListField/CheckboxListField.js +1 -1
  103. package/ui/form/CheckboxTreeField/CheckboxTreeField.d.ts +67 -0
  104. package/ui/form/CheckboxTreeField/CheckboxTreeField.js +126 -0
  105. package/ui/form/CheckboxTreeField/index.d.ts +2 -0
  106. package/ui/form/CheckboxTreeField/index.js +7 -0
  107. package/ui/form/DateField/DateField.js +4 -1
  108. package/ui/form/DateField/useDateRange.d.ts +1 -0
  109. package/ui/form/DateField/useDateRange.js +13 -2
  110. package/ui/form/DateRangeField/DateRangeField.d.ts +34 -1
  111. package/ui/form/DateRangeField/DateRangeField.js +59 -8
  112. package/ui/form/DateTimeField/DateTimeField.d.ts +10 -0
  113. package/ui/form/DateTimeField/DateTimeField.js +11 -3
  114. package/ui/form/DateTimeRangeField/DateTimeRangeField.d.ts +25 -1
  115. package/ui/form/DateTimeRangeField/DateTimeRangeField.js +66 -13
  116. package/ui/form/DropDownField/DropDownField.d.ts +23 -3
  117. package/ui/form/DropDownField/DropDownField.js +1 -1
  118. package/ui/form/EmailField/EmailField.d.ts +6 -0
  119. package/ui/form/EmailField/EmailField.js +0 -4
  120. package/ui/form/Field/Field.d.ts +9 -1
  121. package/ui/form/Field/Field.js +1 -1
  122. package/ui/form/Field/fieldWrapper.d.ts +9 -1
  123. package/ui/form/FieldList/FieldList.d.ts +13 -7
  124. package/ui/form/FieldList/FieldList.js +30 -4
  125. package/ui/form/FileField/FileField.js +5 -0
  126. package/ui/form/Form/Form.d.ts +26 -3
  127. package/ui/form/Form/Form.js +5 -3
  128. package/ui/form/ImageField/ImageField.d.ts +9 -1
  129. package/ui/form/InputField/InputField.d.ts +5 -2
  130. package/ui/form/InputField/hooks/useInputFieldWarningByType.js +1 -0
  131. package/ui/form/NumberField/NumberField.js +34 -7
  132. package/ui/form/SliderField/SliderField.d.ts +10 -2
  133. package/ui/form/TimeRangeField/TimeRangeField.d.ts +10 -1
  134. package/ui/form/TimeRangeField/TimeRangeField.js +3 -1
  135. package/ui/form/WizardForm/WizardForm.d.ts +119 -0
  136. package/ui/form/WizardForm/WizardForm.js +167 -0
  137. package/ui/form/WizardForm/index.d.ts +2 -0
  138. package/ui/form/WizardForm/index.js +7 -0
  139. package/ui/form/WizardForm/utils.d.ts +12 -0
  140. package/ui/form/WizardForm/utils.js +111 -0
  141. package/ui/form/index.d.ts +3 -1
  142. package/ui/form/index.js +4 -1
  143. package/ui/layout/ProgressBar/ProgressBar.js +8 -2
  144. package/ui/layout/Skeleton/Skeleton.d.ts +3 -1
  145. package/ui/layout/Tooltip/Tooltip.d.ts +4 -1
  146. package/ui/list/ControlsColumn/ControlsColumn.d.ts +17 -3
  147. package/ui/list/FlexGrid/FlexGrid.d.ts +11 -1
  148. package/ui/list/Grid/Grid.d.ts +42 -6
  149. package/ui/list/Grid/Grid.js +1 -2
  150. package/ui/list/LayoutNames/LayoutNames.d.ts +11 -1
  151. package/ui/list/Steps/Steps.d.ts +19 -7
  152. package/ui/list/Steps/Steps.js +46 -26
  153. package/ui/list/TreeTable/TreeTable.d.ts +34 -33
  154. package/ui/list/TreeTable/TreeTable.js +19 -8
  155. package/ui/modal/Modal/Modal.d.ts +7 -1
  156. package/ui/nav/Breadcrumbs/Breadcrumbs.d.ts +11 -1
  157. package/ui/nav/ButtonGroup/ButtonGroup.d.ts +13 -4
  158. package/ui/nav/Controls/Controls.d.ts +7 -1
  159. package/ui/nav/Link/Link.d.ts +1 -1
  160. package/ui/nav/Nav/Nav.d.ts +19 -4
  161. package/ui/nav/Router/Router.d.ts +19 -3
  162. package/ui/nav/Router/Router.js +11 -6
  163. package/ui/nav/Router/helpers.d.ts +2 -2
  164. package/ui/nav/Router/helpers.js +39 -7
  165. package/ui/nav/Tree/Tree.d.ts +32 -62
  166. package/ui/nav/Tree/Tree.js +18 -165
  167. package/utils/calculateComponentAbsolutePosition.js +74 -24
  168. package/utils/calendar.d.ts +8 -0
  169. package/utils/calendar.js +76 -1
  170. package/utils/data.js +1 -0
  171. package/utils/form.d.ts +1 -0
  172. package/utils/form.js +16 -1
  173. package/ui/content/CalendarSystem/hooks/useWeekCalendar.js +0 -86
  174. package/utils/list.d.ts +0 -1
  175. package/utils/list.js +0 -5
package/hooks/useList.js CHANGED
@@ -37,19 +37,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
38
38
  };
39
39
  exports.__esModule = true;
40
- exports.prepareItemsToTree = exports.createInitialValues = exports.getDefaultSearchModel = exports.normalizeSortProps = exports.defaultConfig = void 0;
41
- var react_1 = require("react");
40
+ exports.createInitialValues = exports.getDefaultSearchModel = exports.normalizeSortProps = exports.defaultConfig = void 0;
41
+ /* eslint-disable @typescript-eslint/no-use-before-define */
42
+ var react_1 = __importStar(require("react"));
42
43
  var get_1 = __importDefault(require("lodash-es/get"));
43
44
  var union_1 = __importDefault(require("lodash-es/union"));
44
45
  var isEqual_1 = __importDefault(require("lodash-es/isEqual"));
45
- var React = __importStar(require("react"));
46
46
  var react_use_1 = require("react-use");
47
- var list_1 = require("../utils/list");
48
- var useSelector_1 = __importDefault(require("../hooks/useSelector"));
49
- var list_2 = require("../reducers/list");
47
+ var useSelector_1 = __importDefault(require("./useSelector"));
48
+ var list_1 = require("../reducers/list");
50
49
  var useModel_1 = __importDefault(require("../hooks/useModel"));
51
50
  var useAddressBar_1 = __importDefault(require("../hooks/useAddressBar"));
52
- var list_3 = require("../actions/list");
51
+ var list_2 = require("../actions/list");
53
52
  var useDispatch_1 = __importDefault(require("../hooks/useDispatch"));
54
53
  var form_1 = require("../actions/form");
55
54
  var form_2 = require("../reducers/form");
@@ -105,27 +104,6 @@ var createInitialValues = function (_a) {
105
104
  return (__assign(__assign((_b = {}, _b[paginationProps.attribute] = paginationProps.defaultValue, _b[paginationSizeProps.attribute] = paginationSizeProps.defaultValue, _b[sort.attribute] = sort.defaultValue, _b[layoutNamesProps.attribute] = layoutNamesProps.defaultValue, _b), initialQuery), configQuery));
106
105
  };
107
106
  exports.createInitialValues = createInitialValues;
108
- var TOP_TREE_LEVEL_VALUE = 0;
109
- var prepareItemsToTree = function (sourceItems, openedTreeItems, currentPage, itemsOnPage, onTreeItemClick, parentId, currentLevel) {
110
- if (parentId === void 0) { parentId = ''; }
111
- if (currentLevel === void 0) { currentLevel = TOP_TREE_LEVEL_VALUE; }
112
- var treeItems = [];
113
- if (currentPage && itemsOnPage && currentLevel === TOP_TREE_LEVEL_VALUE) {
114
- var startIndex = (currentPage - 1) * itemsOnPage;
115
- sourceItems = sourceItems.slice(startIndex, startIndex + itemsOnPage);
116
- }
117
- (sourceItems || []).forEach(function (item, index) {
118
- var uniqueId = (0, list_1.getTreeItemUniqId)(item, index, parentId);
119
- var isOpened = !!openedTreeItems[uniqueId];
120
- var hasItems = !!(item.items && item.items.length > 0);
121
- treeItems.push(__assign(__assign({}, item), { uniqueId: uniqueId, level: currentLevel, isOpened: isOpened, hasItems: hasItems, onTreeItemClick: onTreeItemClick }));
122
- if (isOpened) {
123
- treeItems = treeItems.concat((0, exports.prepareItemsToTree)(item.items, openedTreeItems, currentPage, itemsOnPage, onTreeItemClick, uniqueId, currentLevel + 1)).filter(Boolean);
124
- }
125
- });
126
- return treeItems;
127
- };
128
- exports.prepareItemsToTree = prepareItemsToTree;
129
107
  /**
130
108
  * useList
131
109
  * Добавляет массу возможностей для взаимодействия с коллекциями. Коллекции можно получать как с бекенда,
@@ -135,18 +113,7 @@ exports.prepareItemsToTree = prepareItemsToTree;
135
113
  function useList(config) {
136
114
  var _a, _b;
137
115
  // Get list from redux state
138
- var list = (0, useSelector_1["default"])(function (state) { return (0, list_2.getList)(state, config.listId); });
139
- var _c = (0, react_1.useState)({}), openedTreeItems = _c[0], setOpenedTreeItems = _c[1];
140
- var onTreeItemClick = (0, react_1.useCallback)(function (uniqueId, item) {
141
- var _a;
142
- if (((_a = item.items) === null || _a === void 0 ? void 0 : _a.length) > 0) {
143
- setOpenedTreeItems(function (prevItems) {
144
- var _a;
145
- return (__assign(__assign({}, prevItems), (_a = {}, _a[uniqueId] = !prevItems[uniqueId], _a)));
146
- });
147
- }
148
- }, []);
149
- var getTreeItems = (0, react_1.useCallback)(function (sourceItems) { return (0, exports.prepareItemsToTree)(sourceItems, openedTreeItems, list === null || list === void 0 ? void 0 : list.page, list === null || list === void 0 ? void 0 : list.pageSize, onTreeItemClick); }, [onTreeItemClick, openedTreeItems, list]);
116
+ var list = (0, useSelector_1["default"])(function (state) { return (0, list_1.getList)(state, config.listId); });
150
117
  // Normalize sort config
151
118
  var sort = (0, exports.normalizeSortProps)(config.sort);
152
119
  // Empty
@@ -157,24 +124,24 @@ function useList(config) {
157
124
  if (!emptyProps.enable || (list === null || list === void 0 ? void 0 : list.isLoading) || ((_a = list === null || list === void 0 ? void 0 : list.items) === null || _a === void 0 ? void 0 : _a.length) > 0) {
158
125
  return null;
159
126
  }
160
- return (React.createElement(Empty, __assign({ list: list }, emptyProps)));
127
+ return (react_1["default"].createElement(Empty, __assign({ list: list }, emptyProps)));
161
128
  };
162
129
  // Pagination size
163
130
  var PaginationSize = require('../ui/list/PaginationSize')["default"];
164
131
  var paginationSizeProps = (0, PaginationSize_1.normalizePaginationSizeProps)(config.paginationSize);
165
132
  var renderPaginationSize = function () { return paginationSizeProps.enable
166
- ? (React.createElement(PaginationSize, __assign({ list: list }, paginationSizeProps)))
133
+ ? (react_1["default"].createElement(PaginationSize, __assign({ list: list }, paginationSizeProps)))
167
134
  : null; };
168
135
  // Pagination
169
136
  var Pagination = require('../ui/list/Pagination')["default"];
170
137
  var paginationProps = (0, Pagination_1.normalizePaginationProps)(config.pagination);
171
138
  var renderPagination = function () { return paginationProps.enable
172
- ? (React.createElement(Pagination, __assign({ list: list }, paginationProps, { sizeAttribute: paginationSizeProps.attribute })))
139
+ ? (react_1["default"].createElement(Pagination, __assign({ list: list }, paginationProps, { sizeAttribute: paginationSizeProps.attribute })))
173
140
  : null; };
174
141
  // Layout switcher
175
142
  var LayoutNames = require('../ui/list/LayoutNames')["default"];
176
143
  var layoutNamesProps = (0, LayoutNames_1.normalizeLayoutNamesProps)(config.layout);
177
- var renderLayoutNames = function () { return (React.createElement(LayoutNames, __assign({ list: list }, layoutNamesProps))); };
144
+ var renderLayoutNames = function () { return (react_1["default"].createElement(LayoutNames, __assign({ list: list }, layoutNamesProps))); };
178
145
  // Models
179
146
  var defaultSearchModel = (0, react_1.useMemo)(function () { return (0, exports.getDefaultSearchModel)({
180
147
  paginationProps: paginationProps,
@@ -185,17 +152,23 @@ function useList(config) {
185
152
  var model = (0, useModel_1["default"])(config.model);
186
153
  var searchModel = (0, useModel_1["default"])(config.searchModel || ((_a = config.searchForm) === null || _a === void 0 ? void 0 : _a.model), defaultSearchModel);
187
154
  // Address bar synchronization
188
- var _d = (0, useAddressBar_1["default"])(__assign({ enable: !!config.addressBar, model: searchModel }, (typeof config.addressBar === 'boolean' ? { enable: config.addressBar } : config.addressBar))), initialQuery = _d.initialQuery, updateQuery = _d.updateQuery;
155
+ var _c = (0, useAddressBar_1["default"])(__assign({ enable: !!config.addressBar, model: searchModel }, (typeof config.addressBar === 'boolean' ? { enable: config.addressBar } : config.addressBar))), initialQuery = _c.initialQuery, updateQuery = _c.updateQuery;
189
156
  // Outside search form
190
157
  var searchFormFields = (_b = config.searchForm) === null || _b === void 0 ? void 0 : _b.fields;
191
158
  var SearchForm = require('../ui/list/SearchForm')["default"];
192
159
  var initialValuesSearchForm = (0, react_1.useMemo)(function () { return (searchFormFields || []).reduce(function (acc, field) {
160
+ var _a;
193
161
  var attribute = typeof field === 'string' ? field : field.attribute;
194
- acc[attribute] = initialQuery === null || initialQuery === void 0 ? void 0 : initialQuery[attribute];
162
+ if ((_a = config.searchForm) === null || _a === void 0 ? void 0 : _a.initialValues) {
163
+ acc[attribute] = config.searchForm.initialValues[attribute];
164
+ }
165
+ else {
166
+ acc[attribute] = initialQuery === null || initialQuery === void 0 ? void 0 : initialQuery[attribute];
167
+ }
195
168
  return acc;
196
- }, {}); }, [searchFormFields, initialQuery]);
169
+ }, {}); }, [searchFormFields, config.searchForm, initialQuery]);
197
170
  var searchFormProps = __assign(__assign({ listId: config.listId }, config.searchForm), { model: searchModel, initialValues: initialValuesSearchForm });
198
- var renderSearchForm = function () { return React.createElement(SearchForm, __assign({}, searchFormProps)); };
171
+ var renderSearchForm = function () { return react_1["default"].createElement(SearchForm, __assign({}, searchFormProps)); };
199
172
  // Form id
200
173
  var formId = (0, get_1["default"])(config, 'searchForm.formId') || config.listId;
201
174
  var dispatch = (0, useDispatch_1["default"])();
@@ -211,14 +184,13 @@ function useList(config) {
211
184
  var initialValues = (0, useInitial_1["default"])(function () { return _initialValues; });
212
185
  var renderList = (0, react_1.useCallback)(function (children) {
213
186
  var Form = require('../ui/form/Form')["default"];
214
- return (React.createElement(Form, { formId: formId, initialValues: initialValues, view: false, useRedux: true }, children));
187
+ return (react_1["default"].createElement(Form, { formId: formId, initialValues: initialValues, view: false, useRedux: true }, children));
215
188
  }, [formId, initialValues]);
216
189
  // Init list in redux store
217
190
  (0, react_use_1.useMount)(function () {
218
191
  if (!list) {
219
- var items = config.hasTreeItems ? getTreeItems(config.items) : config.items;
220
192
  var toDispatch = [
221
- (0, list_3.listInit)(config.listId, {
193
+ (0, list_2.listInit)(config.listId, {
222
194
  listId: config.listId,
223
195
  action: config.action || config.action === '' ? config.action : null,
224
196
  actionMethod: config.actionMethod || exports.defaultConfig.actionMethod,
@@ -227,7 +199,7 @@ function useList(config) {
227
199
  condition: config.condition,
228
200
  scope: config.scope,
229
201
  items: null,
230
- sourceItems: items || null,
202
+ sourceItems: config.items || null,
231
203
  total: config.initialTotal,
232
204
  isRemote: !config.items,
233
205
  primaryKey: config.primaryKey || exports.defaultConfig.primaryKey,
@@ -239,15 +211,11 @@ function useList(config) {
239
211
  layoutAttribute: layoutNamesProps.attribute || null
240
212
  }),
241
213
  ];
242
- if (config.initialItems) {
243
- var initialItems = config.hasTreeItems ? getTreeItems(config.initialItems) : config.initialItems;
244
- toDispatch.push((0, list_3.listSetItems)(config.listId, initialItems));
245
- }
246
- else if (config.items) {
247
- toDispatch.push((0, list_3.listSetItems)(config.listId, items));
214
+ if (config.initialItems || config.items) {
215
+ toDispatch.push((0, list_2.listSetItems)(config.listId, config.initialItems || config.items));
248
216
  }
249
217
  if (!config.initialItems) {
250
- toDispatch.push((0, list_3.listLazyFetch)(config.listId));
218
+ toDispatch.push((0, list_2.listLazyFetch)(config.listId));
251
219
  }
252
220
  dispatch(toDispatch);
253
221
  }
@@ -270,7 +238,7 @@ function useList(config) {
270
238
  updateQuery(formValues);
271
239
  // Send request
272
240
  if (config.autoFetchOnFormChanges !== false) {
273
- dispatch((0, list_3.listLazyFetch)(config.listId));
241
+ dispatch((0, list_2.listLazyFetch)(config.listId));
274
242
  }
275
243
  }
276
244
  }, [config.autoFetchOnFormChanges, config.listId, dispatch, formId, formValues,
@@ -288,29 +256,22 @@ function useList(config) {
288
256
  // Check change items
289
257
  (0, react_use_1.useUpdateEffect)(function () {
290
258
  dispatch([
291
- (0, list_3.listSetItems)(config.listId, config.items),
259
+ (0, list_2.listSetItems)(config.listId, config.items),
292
260
  ]);
293
261
  }, [dispatch, config.items, config.listId]);
294
- (0, react_use_1.useUpdateEffect)(function () {
295
- if (config.hasTreeItems) {
296
- dispatch([
297
- (0, list_3.listSetItems)(config.listId, getTreeItems(config.items)),
298
- ]);
299
- }
300
- }, [dispatch, config.items, config.listId, openedTreeItems, list === null || list === void 0 ? void 0 : list.pageSize, list === null || list === void 0 ? void 0 : list.page]);
301
262
  // Destroy
302
263
  (0, react_use_1.useUnmount)(function () {
303
264
  var autoDestroy = typeof config.autoDestroy === 'boolean' ? config.autoDestroy : exports.defaultConfig.autoDestroy;
304
265
  if (autoDestroy) {
305
266
  dispatch([
306
- (0, list_3.listDestroy)(config.listId),
267
+ (0, list_2.listDestroy)(config.listId),
307
268
  (0, form_1.formDestroy)(config.listId),
308
269
  ]);
309
270
  }
310
271
  });
311
272
  var onFetch = (0, react_1.useCallback)(function (params) {
312
273
  if (params === void 0) { params = {}; }
313
- dispatch((0, list_3.listFetch)(config.listId, params));
274
+ dispatch((0, list_2.listFetch)(config.listId, params));
314
275
  }, [config.listId, dispatch]);
315
276
  var onSort = (0, react_1.useCallback)(function (value) {
316
277
  dispatch((0, form_1.formChange)(formId, sort.attribute, value));
@@ -0,0 +1,104 @@
1
+ import React from 'react';
2
+ import { IButtonProps } from '@steroidsjs/core/ui/form/Button/Button';
3
+ export interface ITreeItem extends IButtonProps {
4
+ /**
5
+ * Идентификатор узла
6
+ */
7
+ id: string | number | boolean;
8
+ /**
9
+ * Вложенные элементы
10
+ * @example
11
+ * [
12
+ * {
13
+ * id: 2,
14
+ * label: 'Nested element',
15
+ * items: [...]
16
+ * }
17
+ * ]
18
+ */
19
+ items?: ITreeItem[];
20
+ /**
21
+ * Скрыть или показать узел
22
+ * @example true
23
+ */
24
+ visible?: boolean;
25
+ }
26
+ export interface IPreparedTreeItem extends ITreeItem {
27
+ uniqueId: string;
28
+ index: number;
29
+ level: number;
30
+ isOpened: boolean;
31
+ isSelected: boolean;
32
+ hasItems: boolean;
33
+ onClick: (e: Event | React.MouseEvent | any) => void;
34
+ className?: CssClassName;
35
+ }
36
+ export interface ITreeOutput {
37
+ treeItems: IPreparedTreeItem[];
38
+ }
39
+ export interface ITreeConfig {
40
+ /**
41
+ * Коллекция с узлами. Также можно передать идентификатор роута, тогда компонент найдет все
42
+ * вложенные роуты и отобразит их в виде дерева.
43
+ * @example
44
+ * [
45
+ * {
46
+ * id: 1,
47
+ * label: 'Root',
48
+ * items: [...]
49
+ * }
50
+ * ] | 'root'
51
+ */
52
+ items?: ITreeItem[] | string;
53
+ /**
54
+ * Ограничивает максимальный уровень вложенности дерева
55
+ * @example 2
56
+ */
57
+ level?: number;
58
+ /**
59
+ * Ключ для доступа к вложенным элементам узла
60
+ * @example 'items'
61
+ */
62
+ itemsKey?: string;
63
+ /**
64
+ * Идентификатор узла, которой нужно отобразить в раскрытом виде
65
+ * @example 2
66
+ */
67
+ selectedItemId?: string | number;
68
+ /**
69
+ * Максимальный уровень вложенности, до которого все узлы будут отображаться в развёрнутом виде
70
+ * @example 1
71
+ */
72
+ autoOpenLevels?: number;
73
+ /**
74
+ * Обработчик на клик по узлу
75
+ * @param args
76
+ */
77
+ onExpand?: (...args: any[]) => any;
78
+ /**
79
+ * Используется для управления раскрытием всех элементов в дереве
80
+ * @example: true
81
+ */
82
+ alwaysOpened?: boolean;
83
+ /**
84
+ * Текущая страница, используется для корректного отображения пагинации
85
+ * @example: 1
86
+ */
87
+ currentPage?: number;
88
+ /**
89
+ * Количество элементов на странице, используется для корректного отображения пагинации
90
+ * @example: 4
91
+ */
92
+ itemsOnPage?: number;
93
+ /**
94
+ * Параметры роутинга
95
+ * @example: true
96
+ */
97
+ routerParams?: any;
98
+ /**
99
+ * При повторном нажатии на выбранный элемент из дерева, он продолжит отображаться как активный.
100
+ * @example true
101
+ */
102
+ useSameSelectedItemId?: boolean;
103
+ }
104
+ export default function useTree(config: ITreeConfig): ITreeOutput;
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ exports.__esModule = true;
17
+ var react_1 = require("react");
18
+ var isString_1 = __importDefault(require("lodash-es/isString"));
19
+ var omit_1 = __importDefault(require("lodash-es/omit"));
20
+ var join_1 = __importDefault(require("lodash-es/join"));
21
+ var isEqual_1 = __importDefault(require("lodash-es/isEqual"));
22
+ var isEmpty_1 = __importDefault(require("lodash-es/isEmpty"));
23
+ var isNil_1 = __importDefault(require("lodash-es/isNil"));
24
+ var keys_1 = __importDefault(require("lodash-es/keys"));
25
+ var useSelector_1 = __importDefault(require("./useSelector"));
26
+ var router_1 = require("../reducers/router");
27
+ var INITIAL_CURRENT_LEVEL = 0;
28
+ var DOT_SEPARATOR = '.';
29
+ var EMPTY_PARENT_ID = '';
30
+ var FIRST_LEVEL_PARENT_ID = '0';
31
+ var defaultProps = {
32
+ itemsKey: 'items',
33
+ autoOpenLevels: 0
34
+ };
35
+ var getTreeItemUniqueId = function (item, index, parentId) { return (0, join_1["default"])([parentId || FIRST_LEVEL_PARENT_ID, String(item.id || index)], DOT_SEPARATOR); };
36
+ var routeToItem = function (route, routerParams) {
37
+ var routeItems = (Array.isArray(route.items)
38
+ ? route.items.map(function (r) { return routeToItem(r, routerParams); })
39
+ : Object.keys(route.items || {}).map(function (id) { return routeToItem(route.items[id], routerParams); })).filter(function (r) { return r.visible; });
40
+ return {
41
+ id: route.id.toLowerCase(),
42
+ label: route.label || route.title,
43
+ visible: route.isNavVisible !== false,
44
+ toRoute: routeItems.length === 0 ? route.id : null,
45
+ toRouteParams: routeItems.length === 0 ? routerParams : null,
46
+ items: routeItems,
47
+ icon: route.icon
48
+ };
49
+ };
50
+ var findChildById = function (sourceItems, itemId, primaryKey, parentId, level) {
51
+ if (parentId === void 0) { parentId = EMPTY_PARENT_ID; }
52
+ if (level === void 0) { level = 1; }
53
+ if ((0, isString_1["default"])(sourceItems)) {
54
+ return null;
55
+ }
56
+ var foundedItem = null;
57
+ (sourceItems || []).forEach(function (item, index) {
58
+ var uniqueId = getTreeItemUniqueId(item, index, parentId);
59
+ if (!foundedItem && (item.id === itemId || uniqueId === itemId)) {
60
+ foundedItem = __assign(__assign({}, item), { uniqueId: uniqueId, level: level });
61
+ }
62
+ if (!foundedItem) {
63
+ foundedItem = findChildById(item[primaryKey], itemId, primaryKey, uniqueId, level + 1);
64
+ }
65
+ });
66
+ return foundedItem;
67
+ };
68
+ var getAutoExpandedItems = function (sourceItems, selectedItemId, primaryKey, autoOpenLevels, parentId, level) {
69
+ if (autoOpenLevels === void 0) { autoOpenLevels = 1; }
70
+ if (parentId === void 0) { parentId = EMPTY_PARENT_ID; }
71
+ if (level === void 0) { level = 1; }
72
+ var opened = {};
73
+ (sourceItems || []).forEach(function (item, index) {
74
+ var uniqueId = getTreeItemUniqueId(item, index, parentId);
75
+ if (autoOpenLevels >= level) {
76
+ opened[uniqueId] = true;
77
+ }
78
+ if (selectedItemId === item.id) {
79
+ opened[uniqueId] = true;
80
+ }
81
+ if (selectedItemId) {
82
+ var finedItem = findChildById(item[primaryKey], selectedItemId, primaryKey);
83
+ if (finedItem) {
84
+ opened[uniqueId] = true;
85
+ }
86
+ }
87
+ opened = __assign(__assign({}, opened), getAutoExpandedItems(item[primaryKey], selectedItemId, primaryKey, autoOpenLevels, uniqueId, level + 1));
88
+ });
89
+ return opened;
90
+ };
91
+ var isSelectedItem = function (selectedUniqueId, uniqueId, activeRouteIds, item, routerParams) { return (selectedUniqueId === uniqueId
92
+ || ((activeRouteIds || []).includes(item.toRoute)
93
+ && (0, isEqual_1["default"])(item.toRouteParams || {}, (0, omit_1["default"])(routerParams, (0, keys_1["default"])(item.toRouteParams))))); };
94
+ function useTree(config) {
95
+ // Get primary key
96
+ var primaryKey = config.itemsKey || defaultProps.itemsKey;
97
+ var _a = (0, react_1.useState)(null), selectedUniqueId = _a[0], setSelectedUniqueId = _a[1];
98
+ var _b = (0, react_1.useState)({}), expandedItems = _b[0], setExpandedItems = _b[1];
99
+ //Redux connection
100
+ var _c = (0, useSelector_1["default"])(function (state) { return ({
101
+ routes: (0, isString_1["default"])(config.items) ? (0, router_1.getNavItems)(state, config.items) : null,
102
+ selectedItemId: (0, isString_1["default"])(config.items) ? (0, router_1.getRouteId)(state) : config.selectedItemId,
103
+ activeRouteIds: (0, router_1.getActiveRouteIds)(state),
104
+ routerParams: (0, router_1.getRouterParams)(state)
105
+ }); }), routes = _c.routes, selectedItemId = _c.selectedItemId, activeRouteIds = _c.activeRouteIds, routerParams = _c.routerParams;
106
+ var items = (0, react_1.useMemo)(function () {
107
+ if (!(0, isNil_1["default"])(routes)) {
108
+ return routes
109
+ .map(function (route) { return routeToItem(route, config.routerParams); })
110
+ .filter(function (route) { return route.visible; });
111
+ }
112
+ if (Array.isArray(config.items)) {
113
+ return config.items;
114
+ }
115
+ return [];
116
+ }, [config.items, config.routerParams, routes]);
117
+ // Initial expanded items
118
+ (0, react_1.useEffect)(function () {
119
+ // TODO add clientStorage
120
+ setExpandedItems(getAutoExpandedItems(items, selectedItemId, primaryKey, config.autoOpenLevels));
121
+ var selectedItem = findChildById(items, selectedItemId, primaryKey);
122
+ setSelectedUniqueId(selectedItem ? selectedItem.uniqueId : null);
123
+ }, [items]);
124
+ var onExpand = (0, react_1.useCallback)(function (e, uniqueId, item) {
125
+ var _a;
126
+ e.preventDefault();
127
+ if (config.onExpand) {
128
+ config.onExpand.call(null, e, item);
129
+ }
130
+ var sameUniqueIdAccordingToSettings = config.useSameSelectedItemId ? uniqueId : null;
131
+ setSelectedUniqueId(selectedUniqueId === uniqueId ? sameUniqueIdAccordingToSettings : uniqueId);
132
+ if (!(0, isEmpty_1["default"])(item[primaryKey])) {
133
+ setExpandedItems(__assign(__assign({}, expandedItems), (_a = {}, _a[uniqueId] = !expandedItems[uniqueId], _a)));
134
+ }
135
+ }, [config.onExpand, config.useSameSelectedItemId, expandedItems, primaryKey, selectedUniqueId]);
136
+ var resultTreeItems = (0, react_1.useMemo)(function () {
137
+ var getItems = function (sourceItems, parentId, currentLevel) {
138
+ if (parentId === void 0) { parentId = EMPTY_PARENT_ID; }
139
+ if (currentLevel === void 0) { currentLevel = INITIAL_CURRENT_LEVEL; }
140
+ if (config.level && currentLevel === config.level) {
141
+ return [];
142
+ }
143
+ if (config.currentPage && config.itemsOnPage && currentLevel === INITIAL_CURRENT_LEVEL) {
144
+ var startIndex = (config.currentPage - 1) * config.itemsOnPage;
145
+ sourceItems = sourceItems.slice(startIndex, startIndex + config.itemsOnPage);
146
+ }
147
+ return (sourceItems || []).reduce(function (treeItems, item, index) {
148
+ var uniqueId = getTreeItemUniqueId(item, index, parentId);
149
+ var treeItem = __assign(__assign({}, item), { index: index, level: currentLevel, uniqueId: uniqueId, isOpened: config.alwaysOpened || !!expandedItems[uniqueId], hasItems: !(0, isEmpty_1["default"])(item[primaryKey]), isSelected: isSelectedItem(selectedUniqueId, uniqueId, activeRouteIds, item, routerParams), onClick: function (e) { return onExpand(e, uniqueId, item); } });
150
+ // Ограничивает максимальный уровень вложенности дерева
151
+ if (config.level && (currentLevel === config.level - 1)) {
152
+ treeItem.hasItems = false;
153
+ }
154
+ treeItems.push(treeItem);
155
+ if (treeItem.isOpened) {
156
+ var nestedItem = getItems(item[primaryKey], uniqueId, currentLevel + 1);
157
+ treeItems = treeItems.concat(nestedItem).filter(Boolean);
158
+ }
159
+ return treeItems;
160
+ }, []);
161
+ };
162
+ return getItems(items);
163
+ // eslint-disable-next-line max-len
164
+ }, [activeRouteIds, config.alwaysOpened, config.currentPage, config.itemsOnPage, config.level, expandedItems, items, onExpand, primaryKey, routerParams, selectedUniqueId]);
165
+ return {
166
+ treeItems: resultTreeItems
167
+ };
168
+ }
169
+ exports["default"] = useTree;
package/index.d.ts CHANGED
@@ -95,16 +95,16 @@ declare interface IUiComponent {
95
95
  * Переопределение view React компонента для кастомизации отображения
96
96
  * @example MyCustomView
97
97
  */
98
- view?: CustomView;
98
+ view?: CustomView,
99
99
 
100
100
  /**
101
101
  * Дополнительный CSS-класс для элемента отображения
102
102
  */
103
- className?: CssClassName;
103
+ className?: CssClassName,
104
104
 
105
105
  /**
106
106
  * Объект CSS стилей
107
107
  * @example {width: '45%'}
108
108
  */
109
- style?: CustomStyle;
109
+ style?: CustomStyle,
110
110
  }