@steroidsjs/core 2.1.0-beta.2 → 2.1.0-beta.20

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 (136) hide show
  1. package/actions/form.d.ts +9 -0
  2. package/actions/form.js +11 -1
  3. package/actions/list.d.ts +1 -0
  4. package/actions/list.js +1 -0
  5. package/components/ClientStorageComponent.d.ts +3 -3
  6. package/components/ClientStorageComponent.js +28 -22
  7. package/components/HttpComponent.js +32 -15
  8. package/components/LocaleComponent.js +9 -9
  9. package/components/MetricsComponent.js +3 -1
  10. package/components/StoreComponent.d.ts +6 -0
  11. package/components/StoreComponent.js +6 -7
  12. package/components/UiComponent.d.ts +1 -1
  13. package/components/WebSocketComponent.d.ts +1 -1
  14. package/hoc/components.d.ts +1 -1
  15. package/hoc/components.js +1 -1
  16. package/hoc/file.d.ts +1 -0
  17. package/hooks/index.d.ts +2 -1
  18. package/hooks/index.js +3 -1
  19. package/hooks/useAbsolutePositioning.d.ts +5 -0
  20. package/hooks/useAbsolutePositioning.js +6 -6
  21. package/hooks/useApplication.d.ts +29 -26
  22. package/hooks/useApplication.js +17 -82
  23. package/hooks/useComponents.d.ts +1 -14
  24. package/hooks/useComponents.js +5 -5
  25. package/hooks/useDataProvider.js +4 -2
  26. package/hooks/useDataSelect.d.ts +12 -6
  27. package/hooks/useDataSelect.js +5 -3
  28. package/hooks/useFetch.d.ts +11 -3
  29. package/hooks/useFetch.js +34 -31
  30. package/hooks/useFile.js +14 -2
  31. package/hooks/useLayout.d.ts +9 -0
  32. package/hooks/useLayout.js +64 -44
  33. package/hooks/useList.d.ts +45 -0
  34. package/hooks/useList.js +83 -53
  35. package/hooks/useModel.js +1 -1
  36. package/hooks/useScreen.d.ts +1 -1
  37. package/hooks/useScreen.js +2 -2
  38. package/hooks/useSsr.d.ts +2 -0
  39. package/hooks/useSsr.js +8 -0
  40. package/index.d.ts +8 -2
  41. package/package.json +6 -3
  42. package/providers/ComponentsProvider.d.ts +26 -0
  43. package/providers/ComponentsProvider.js +28 -0
  44. package/providers/ScreenProvider.d.ts +20 -0
  45. package/providers/ScreenProvider.js +87 -0
  46. package/providers/SsrProvider.d.ts +17 -0
  47. package/providers/SsrProvider.js +32 -0
  48. package/providers/index.d.ts +4 -0
  49. package/providers/index.js +12 -0
  50. package/reducers/form.d.ts +1 -1
  51. package/reducers/form.js +3 -1
  52. package/reducers/index.js +1 -1
  53. package/reducers/list.js +1 -3
  54. package/reducers/router.js +1 -1
  55. package/ui/content/Alert/Alert.d.ts +50 -0
  56. package/ui/content/Alert/Alert.js +39 -0
  57. package/ui/content/Alert/index.d.ts +2 -0
  58. package/ui/content/Alert/index.js +7 -0
  59. package/ui/content/Avatar/Avatar.d.ts +53 -12
  60. package/ui/content/Avatar/Avatar.js +25 -4
  61. package/ui/content/Avatar/index.d.ts +6 -1
  62. package/ui/content/Avatar/index.js +4 -0
  63. package/ui/content/Card/Card.d.ts +61 -13
  64. package/ui/content/Card/Card.js +3 -2
  65. package/ui/content/Collapse/Collapse.d.ts +63 -0
  66. package/ui/content/Collapse/Collapse.js +75 -0
  67. package/ui/content/Collapse/CollapseItem.d.ts +67 -0
  68. package/ui/content/Collapse/CollapseItem.js +22 -0
  69. package/ui/content/Collapse/index.d.ts +7 -0
  70. package/ui/content/Collapse/index.js +8 -0
  71. package/ui/content/Detail/Detail.d.ts +102 -0
  72. package/ui/content/Detail/Detail.js +155 -0
  73. package/ui/content/Detail/DetailItem.d.ts +43 -0
  74. package/ui/content/Detail/DetailItem.js +10 -0
  75. package/ui/content/Detail/demo/basic.d.ts +8 -0
  76. package/ui/content/Detail/demo/basic.js +56 -0
  77. package/ui/content/Detail/demo/controls.d.ts +8 -0
  78. package/ui/content/Detail/demo/controls.js +56 -0
  79. package/ui/content/Detail/demo/layout.d.ts +8 -0
  80. package/ui/content/Detail/demo/layout.js +56 -0
  81. package/ui/content/Detail/demo/responsive.d.ts +8 -0
  82. package/ui/content/Detail/demo/responsive.js +71 -0
  83. package/ui/content/Detail/demo/sizes.d.ts +8 -0
  84. package/ui/content/Detail/demo/sizes.js +61 -0
  85. package/ui/content/Detail/index.d.ts +3 -0
  86. package/ui/content/Detail/index.js +10 -0
  87. package/ui/content/DropDown/DropDown.d.ts +1 -0
  88. package/ui/content/DropDown/DropDown.js +1 -0
  89. package/ui/content/index.d.ts +13 -0
  90. package/ui/content/index.js +22 -0
  91. package/ui/crud/Crud/Crud.d.ts +1 -1
  92. package/ui/crud/Crud/Crud.js +1 -1
  93. package/ui/crud/index.d.ts +1 -0
  94. package/ui/form/Button/Button.d.ts +1 -0
  95. package/ui/form/Button/Button.js +1 -0
  96. package/ui/form/DateField/useDateInputState.d.ts +4 -0
  97. package/ui/form/DateField/useDateInputState.js +3 -3
  98. package/ui/form/DateField/useDateTime.js +9 -7
  99. package/ui/form/DateTimeField/DateTimeField.js +2 -1
  100. package/ui/form/DropDownField/DropDownField.js +10 -3
  101. package/ui/form/Form/Form.js +118 -106
  102. package/ui/form/ImageField/ImageField.d.ts +87 -0
  103. package/ui/form/ImageField/ImageField.js +145 -0
  104. package/ui/form/ImageField/index.d.ts +2 -0
  105. package/ui/form/ImageField/index.js +7 -0
  106. package/ui/form/InputField/InputField.d.ts +7 -0
  107. package/ui/form/InputField/InputField.js +26 -22
  108. package/ui/form/TextField/TextField.d.ts +2 -1
  109. package/ui/form/TextField/TextField.js +1 -1
  110. package/ui/icon/Icon/Icon.js +3 -0
  111. package/ui/layout/Meta/Meta.d.ts +56 -0
  112. package/ui/layout/Meta/Meta.js +38 -0
  113. package/ui/layout/Meta/index.d.ts +2 -0
  114. package/ui/layout/Meta/index.js +7 -0
  115. package/ui/layout/Notifications/Notifications.js +1 -1
  116. package/ui/layout/Portal.js +3 -0
  117. package/ui/layout/ProgressBar/ProgressBar.d.ts +55 -0
  118. package/ui/layout/ProgressBar/ProgressBar.js +52 -0
  119. package/ui/layout/ProgressBar/index.d.ts +2 -0
  120. package/ui/layout/ProgressBar/index.js +7 -0
  121. package/ui/layout/Skeleton/Skeleton.d.ts +25 -0
  122. package/ui/layout/Skeleton/Skeleton.js +11 -0
  123. package/ui/layout/Skeleton/index.d.ts +2 -0
  124. package/ui/layout/Skeleton/index.js +7 -0
  125. package/ui/list/Steps/Steps.d.ts +32 -0
  126. package/ui/list/Steps/Steps.js +23 -0
  127. package/ui/list/Steps/index.d.ts +2 -0
  128. package/ui/list/Steps/index.js +7 -0
  129. package/ui/nav/Router/Router.d.ts +13 -0
  130. package/ui/nav/Router/Router.js +1 -1
  131. package/utils/calendar.d.ts +1 -1
  132. package/utils/calendar.js +8 -1
  133. package/ui/content/Avatar/SizeContext.d.ts +0 -1
  134. package/ui/content/Avatar/SizeContext.js +0 -14
  135. package/ui/nav/Router/SsrProvider.d.ts +0 -15
  136. package/ui/nav/Router/SsrProvider.js +0 -55
@@ -44,86 +44,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
44
44
  return (mod && mod.__esModule) ? mod : { "default": mod };
45
45
  };
46
46
  exports.__esModule = true;
47
- exports.ComponentsContext = exports.SCREEN_DESKTOP = exports.SCREEN_TABLET = exports.SCREEN_PHONE = exports.ScreenContext = void 0;
47
+ exports.defaultComponents = void 0;
48
48
  var React = __importStar(require("react"));
49
49
  var react_redux_1 = require("react-redux");
50
50
  var merge_1 = __importDefault(require("lodash-es/merge"));
51
51
  var react_1 = require("react");
52
- var react_use_1 = require("react-use");
53
52
  var ClientStorageComponent_1 = __importDefault(require("../components/ClientStorageComponent"));
54
53
  var HtmlComponent_1 = __importDefault(require("../components/HtmlComponent"));
55
54
  var StoreComponent_1 = __importDefault(require("../components/StoreComponent"));
56
55
  var UiComponent_1 = __importDefault(require("../components/UiComponent"));
57
56
  var MetaComponent_1 = __importDefault(require("../components/MetaComponent"));
57
+ var ComponentsProvider_1 = __importDefault(require("../providers/ComponentsProvider"));
58
58
  var Router_1 = __importDefault(require("../ui/nav/Router/Router"));
59
59
  var MetricsComponent_1 = __importDefault(require("../components/MetricsComponent"));
60
- exports.ScreenContext = React.createContext({});
61
- exports.SCREEN_PHONE = 'phone';
62
- exports.SCREEN_TABLET = 'tablet';
63
- exports.SCREEN_DESKTOP = 'desktop';
64
- function ScreenProvider(props) {
65
- var _a;
66
- var _b = react_1.useState(typeof window !== 'undefined' ? window.innerWidth : 1280), width = _b[0], setWidth = _b[1];
67
- var _c = react_1.useState(props.media || (_a = {},
68
- _a[exports.SCREEN_PHONE] = 320,
69
- _a[exports.SCREEN_TABLET] = 768,
70
- _a[exports.SCREEN_DESKTOP] = 1024,
71
- _a)), media = _c[0], setMedia = _c[1];
72
- var timer = null;
73
- var onResize = function () {
74
- if (timer) {
75
- clearTimeout(timer);
76
- }
77
- if (props.skipTimeout) {
78
- setWidth(window.innerWidth);
79
- }
80
- else {
81
- timer = setTimeout(function () { return setWidth(window.innerWidth); }, 100);
82
- }
83
- };
84
- react_use_1.useMount(function () {
85
- if (typeof window !== 'undefined') {
86
- window.addEventListener('resize', onResize, false);
87
- }
88
- });
89
- react_use_1.useUnmount(function () {
90
- if (typeof window !== 'undefined') {
91
- window.removeEventListener('resize', onResize);
92
- }
93
- });
94
- var getDeviceType = react_1.useCallback(function () {
95
- if (width < media[exports.SCREEN_TABLET]) {
96
- return exports.SCREEN_PHONE;
97
- }
98
- if (width < media[exports.SCREEN_DESKTOP]) {
99
- return exports.SCREEN_TABLET;
100
- }
101
- return exports.SCREEN_DESKTOP;
102
- }, [width, media]);
103
- var isPhone = react_1.useCallback(function () { return getDeviceType() === exports.SCREEN_PHONE; }, [getDeviceType]);
104
- var isTablet = react_1.useCallback(function () { return getDeviceType() === exports.SCREEN_TABLET; }, [getDeviceType]);
105
- var isDesktop = react_1.useCallback(function () { return getDeviceType() === exports.SCREEN_DESKTOP; }, [getDeviceType]);
106
- var value = react_1.useMemo(function () { return ({
107
- width: width,
108
- media: media,
109
- setMedia: setMedia,
110
- isPhone: isPhone,
111
- isTablet: isTablet,
112
- isDesktop: isDesktop,
113
- getDeviceType: getDeviceType
114
- }); }, [
115
- width,
116
- media,
117
- setMedia,
118
- isPhone,
119
- isTablet,
120
- isDesktop,
121
- getDeviceType,
122
- ]);
123
- return (React.createElement(exports.ScreenContext.Provider, { value: value }, props.children));
124
- }
125
- exports.ComponentsContext = React.createContext({});
126
- var defaultComponents = {
60
+ var ScreenProvider_1 = __importDefault(require("../providers/ScreenProvider"));
61
+ var useComponents_1 = __importDefault(require("./useComponents"));
62
+ exports.defaultComponents = {
127
63
  clientStorage: {
128
64
  className: ClientStorageComponent_1["default"]
129
65
  },
@@ -151,31 +87,30 @@ var defaultComponents = {
151
87
  };
152
88
  function useApplication(config) {
153
89
  if (config === void 0) { config = {}; }
154
- var components;
155
- // Store global (in global mode)
156
- var useGlobal = config.useGlobal !== false && typeof window !== 'undefined';
157
- if (useGlobal) {
90
+ var useGlobal = config.useGlobal !== false;
91
+ var components = useComponents_1["default"]();
92
+ if (useGlobal && !process.env.IS_SSR) {
158
93
  components = window.SteroidsComponents || null;
159
94
  }
160
95
  // Create components
161
96
  if (!components) {
162
97
  components = {};
163
- var componentsConfig_1 = merge_1["default"]({}, defaultComponents, config.components);
98
+ var componentsConfig_1 = merge_1["default"]({}, exports.defaultComponents, config.components);
164
99
  Object.keys(componentsConfig_1).forEach(function (name) {
165
100
  if (typeof componentsConfig_1[name] === 'function') {
166
101
  componentsConfig_1[name] = { className: componentsConfig_1[name] };
167
102
  }
168
103
  var _a = componentsConfig_1[name], className = _a.className, componentConfig = __rest(_a, ["className"]);
169
104
  // Append reducers to store
170
- if (name === 'store' && config.reducers) {
171
- componentConfig.reducers = config.reducers;
105
+ if (name === 'store') {
106
+ if (config.reducers) {
107
+ componentConfig.reducers = config.reducers;
108
+ }
172
109
  }
173
110
  // eslint-disable-next-line new-cap
174
111
  components[name] = new className(components, componentConfig);
175
112
  });
176
- if (useGlobal) {
177
- window.SteroidsComponents = components;
178
- }
113
+ window.SteroidsComponents = components;
179
114
  // Init callback
180
115
  if (config.onInit) {
181
116
  config.onInit(components);
@@ -190,10 +125,10 @@ function useApplication(config) {
190
125
  content = (React.createElement(Router_1["default"], { routes: config.routes(), wrapperView: config.layoutView(), wrapperProps: config.layoutProps }));
191
126
  }
192
127
  if (config.screen) {
193
- content = (React.createElement(ScreenProvider, __assign({}, config.screen), content));
128
+ content = (React.createElement(ScreenProvider_1["default"], __assign({}, config.screen), content));
194
129
  }
195
- if (!useGlobal) {
196
- content = (React.createElement(exports.ComponentsContext.Provider, { value: components }, content));
130
+ if (!(useGlobal || process.env.IS_SSR)) {
131
+ content = (React.createElement(ComponentsProvider_1["default"], { components: components }, content));
197
132
  }
198
133
  return (React.createElement(react_redux_1.Provider, { store: components.store.store }, content));
199
134
  }, [components, config, useGlobal]);
@@ -1,15 +1,2 @@
1
- export interface IComponents {
2
- api?: any;
3
- clientStorage?: any;
4
- html?: any;
5
- http?: any;
6
- locale?: any;
7
- store?: any;
8
- ui?: any;
9
- resource?: any;
10
- ws?: any;
11
- pushNotification?: any;
12
- meta?: any;
13
- [key: string]: any;
14
- }
1
+ import { IComponents } from '../providers/ComponentsProvider';
15
2
  export default function useComponents(): IComponents;
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
- //import {useContext} from 'react';
3
2
  exports.__esModule = true;
3
+ var react_1 = require("react");
4
+ var ComponentsProvider_1 = require("../providers/ComponentsProvider");
4
5
  function useComponents() {
5
- if (typeof window !== 'undefined' && window.SteroidsComponents) {
6
+ var components = react_1.useContext(ComponentsProvider_1.ComponentsContext);
7
+ if (!process.env.IS_SSR) {
6
8
  return window.SteroidsComponents;
7
9
  }
8
- // TODO Get components from context
9
- //return useContext(ComponentsContext);
10
- return null;
10
+ return components;
11
11
  }
12
12
  exports["default"] = useComponents;
@@ -58,6 +58,7 @@ var data_1 = require("../utils/data");
58
58
  var index_1 = require("./index");
59
59
  var fields_1 = require("../reducers/fields");
60
60
  var text_1 = require("../utils/text");
61
+ var react_use_1 = require("react-use");
61
62
  var defaultProps = {
62
63
  autoComplete: {
63
64
  enable: false,
@@ -88,6 +89,7 @@ function useDataProvider(config) {
88
89
  // Fetch data
89
90
  var delayTimerRef = react_1.useRef(null);
90
91
  var isAutoFetchedRef = react_1.useRef(false);
92
+ var prevQuery = react_use_1.usePrevious(config.query);
91
93
  react_1.useEffect(function () {
92
94
  var fetchRemote = function () { return __awaiter(_this, void 0, void 0, function () {
93
95
  var searchHandler, result, newItems;
@@ -129,8 +131,8 @@ function useDataProvider(config) {
129
131
  if (delayTimerRef.current) {
130
132
  clearTimeout(delayTimerRef.current);
131
133
  }
132
- // Min length query logic
133
- if (config.query && config.query.length >= autoComplete.minLength) {
134
+ // Changed query logic
135
+ if (prevQuery !== config.query) {
134
136
  // Search with delay
135
137
  delayTimerRef.current = setTimeout(fetchRemote, autoComplete.delay);
136
138
  }
@@ -1,3 +1,8 @@
1
+ interface IDataSelectItem {
2
+ id: number | string | boolean;
3
+ label?: string;
4
+ [key: string]: unknown;
5
+ }
1
6
  export interface IDataSelectConfig {
2
7
  /**
3
8
  * Возможность множественного выбора
@@ -5,14 +10,10 @@ export interface IDataSelectConfig {
5
10
  */
6
11
  multiple?: boolean;
7
12
  /**
8
- * Список с элементами
13
+ * Список с видимыми элементами
9
14
  * @example [{id: 1, label: 'Krasnoyarsk'}, {id: 2, label: 'Moscow'}]
10
15
  */
11
- items: {
12
- id: number | string | boolean;
13
- label?: string;
14
- [key: string]: unknown;
15
- }[];
16
+ items: IDataSelectItem[];
16
17
  /**
17
18
  * Сделать активным первый элемент в списке
18
19
  * @example true
@@ -32,6 +33,10 @@ export interface IDataSelectConfig {
32
33
  * Значение поля в форме
33
34
  */
34
35
  inputValue: any;
36
+ /**
37
+ * Список со всеми элементами
38
+ */
39
+ sourceItems?: IDataSelectItem[];
35
40
  }
36
41
  export interface IDataSelectResult {
37
42
  isOpened: boolean;
@@ -44,3 +49,4 @@ export interface IDataSelectResult {
44
49
  setSelectedIds: (ids: PrimaryKey | PrimaryKey[], skipToggle?: boolean) => void;
45
50
  }
46
51
  export default function useDataSelect(config: IDataSelectConfig): IDataSelectResult;
52
+ export {};
@@ -21,7 +21,8 @@ function useDataSelect(config) {
21
21
  var primaryKey = config.primaryKey || defaultProps.primaryKey;
22
22
  // Initial select
23
23
  var initialSelectedIds = react_1.useMemo(function () {
24
- if (config.selectedIds) {
24
+ var _a;
25
+ if (((_a = config.selectedIds) === null || _a === void 0 ? void 0 : _a.length) > 0) {
25
26
  return [].concat(config.selectedIds || []);
26
27
  }
27
28
  if (!isNil_1["default"](config.inputValue)) {
@@ -31,6 +32,7 @@ function useDataSelect(config) {
31
32
  ? [config.items[0][primaryKey]]
32
33
  : [];
33
34
  }, [config.items, config.selectFirst, config.selectedIds, primaryKey, config.inputValue]);
35
+ // console.log(initialSelectedIds);
34
36
  // State
35
37
  var _a = react_1.useState(false), isOpened = _a[0], setIsOpened = _a[1];
36
38
  var _b = react_1.useState(false), isFocused = _b[0], setIsFocused = _b[1];
@@ -78,9 +80,9 @@ function useDataSelect(config) {
78
80
  // Update selected items on change value
79
81
  var prevConfigSelectedIds = react_use_1.usePrevious(config.selectedIds || []);
80
82
  react_use_1.useUpdateEffect(function () {
81
- // console.log(config.selectedIds, prevConfigSelectedIds);
83
+ var itemsForSelect = config.sourceItems || config.items;
82
84
  var newSelectedIds = config.selectedIds && config.selectedIds.length > 0
83
- ? config.items.map(function (item) { return item[primaryKey]; }).filter(function (id) { return config.selectedIds.includes(id); })
85
+ ? itemsForSelect.map(function (item) { return item[primaryKey]; }).filter(function (id) { return config.selectedIds.includes(id); })
84
86
  : [];
85
87
  if (!isEqual_1["default"](prevConfigSelectedIds, newSelectedIds) && newSelectedIds.length !== 0) {
86
88
  setSelectedIdsInternal(newSelectedIds);
@@ -1,5 +1,10 @@
1
- import { IComponents } from './useComponents';
1
+ import { IComponents } from '../providers/ComponentsProvider';
2
2
  import { IApiMethod } from '../components/ApiComponent';
3
+ declare global {
4
+ interface Window {
5
+ APP_PRELOADED_DATA: any;
6
+ }
7
+ }
3
8
  export interface IFetchConfig {
4
9
  id?: string | number;
5
10
  url?: string | IApiMethod;
@@ -18,6 +23,10 @@ export interface IFetchResult {
18
23
  isLoading: boolean;
19
24
  fetch?: (newParams?: Record<string, unknown>) => void;
20
25
  }
26
+ export declare const normalizeConfig: (config: any) => any;
27
+ export declare const getConfigId: (config: any) => any;
28
+ export declare const defaultFetchHandler: (config: any, components: any, addCancelToken: any) => any;
29
+ export declare const fetchData: (config: any, components: any, addCancelToken: any) => any;
21
30
  /**
22
31
  * Fetch
23
32
  * Используется для подгрузки данных с бекенда перед рендером компонента, на котором он применяется.
@@ -25,7 +34,6 @@ export interface IFetchResult {
25
34
  * которые описывают откуда нужно подтянуть данные.
26
35
  *
27
36
  * В процесс загрузки HOC будет отображать "Загрузка...", а после уже отрендерит компонент, передав данные в указанный
28
- * ключ `key`. Все данные сохраняются в Redux Store, что позволяет избежать дополнительных запросов при использовании
29
- * SSR.
37
+ * ключ `key`.
30
38
  */
31
39
  export default function useFetch(rawConfig?: IFetchConfig): IFetchResult;
package/hooks/useFetch.js CHANGED
@@ -50,12 +50,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
50
50
  return (mod && mod.__esModule) ? mod : { "default": mod };
51
51
  };
52
52
  exports.__esModule = true;
53
+ exports.fetchData = exports.defaultFetchHandler = exports.getConfigId = exports.normalizeConfig = void 0;
53
54
  var react_1 = require("react");
54
55
  var react_use_1 = require("react-use");
56
+ var trim_1 = __importDefault(require("lodash-es/trim"));
55
57
  var axios_1 = __importDefault(require("axios"));
56
58
  var index_1 = require("./index");
57
59
  var normalizeConfig = function (config) { return (config
58
60
  ? __assign({ id: null, url: '', method: 'get', params: {}, options: null, onFetch: null }, config) : null); };
61
+ exports.normalizeConfig = normalizeConfig;
62
+ var getConfigId = function (config) {
63
+ var result = trim_1["default"](config.id || config.url, '/');
64
+ if (!result) {
65
+ // eslint-disable-next-line no-console
66
+ console.warn('Please set id for fetch config, it`s necessary for SSR to work properly');
67
+ }
68
+ return result;
69
+ };
70
+ exports.getConfigId = getConfigId;
59
71
  var defaultFetchHandler = function (config, components, addCancelToken) {
60
72
  var cancelToken = new axios_1["default"].CancelToken(function (cancel) {
61
73
  addCancelToken(cancel);
@@ -67,6 +79,9 @@ var defaultFetchHandler = function (config, components, addCancelToken) {
67
79
  .send(config.method, config.url, config.params, __assign(__assign({}, config.options), { cancelToken: cancelToken }))
68
80
  .then(function (result) { return result.data; });
69
81
  };
82
+ exports.defaultFetchHandler = defaultFetchHandler;
83
+ var fetchData = function (config, components, addCancelToken) { return ((config.onFetch || exports.defaultFetchHandler).call(null, config, components, addCancelToken)); };
84
+ exports.fetchData = fetchData;
70
85
  /**
71
86
  * Fetch
72
87
  * Используется для подгрузки данных с бекенда перед рендером компонента, на котором он применяется.
@@ -74,26 +89,26 @@ var defaultFetchHandler = function (config, components, addCancelToken) {
74
89
  * которые описывают откуда нужно подтянуть данные.
75
90
  *
76
91
  * В процесс загрузки HOC будет отображать "Загрузка...", а после уже отрендерит компонент, передав данные в указанный
77
- * ключ `key`. Все данные сохраняются в Redux Store, что позволяет избежать дополнительных запросов при использовании
78
- * SSR.
92
+ * ключ `key`.
79
93
  */
80
94
  function useFetch(rawConfig) {
81
95
  var _this = this;
82
96
  if (rawConfig === void 0) { rawConfig = null; }
83
97
  var components = index_1.useComponents();
84
98
  // Store config in state
85
- var _a = react_1.useState(normalizeConfig(rawConfig)), config = _a[0], setConfig = _a[1];
99
+ var _a = react_1.useState(exports.normalizeConfig(rawConfig)), config = _a[0], setConfig = _a[1];
86
100
  // Update config in state on raw config updated
87
101
  react_use_1.useUpdateEffect(function () {
88
102
  setConfig(rawConfig);
89
103
  }, [rawConfig]);
90
- // Resolve config id
91
- // TODO Get initial state from HttpComponent (for SSR) by configId
92
- //const idRef = useRef(_uniqueId('fetch'));
93
- //const configId = config ? _trim(config.id || config.url || idRef.current, '/') : null;
104
+ // Get preloaded data
105
+ var configId = exports.getConfigId(config);
106
+ var ssrValueContext = index_1.useSsr();
107
+ var preloadedData = process.env.IS_SSR ? ssrValueContext.preloadedData : window.APP_PRELOADED_DATA;
108
+ var preloadedDataByConfigId = (preloadedData && configId) ? preloadedData[configId] : null;
94
109
  // State for data and loading flag
95
- var _b = react_1.useState(null), data = _b[0], setData = _b[1];
96
- var _c = react_1.useState(!!config), isLoading = _c[0], setIsLoading = _c[1];
110
+ var _b = react_1.useState(preloadedDataByConfigId || null), data = _b[0], setData = _b[1];
111
+ var _c = react_1.useState(!!config && !data), isLoading = _c[0], setIsLoading = _c[1];
97
112
  // Cancel tokens
98
113
  var cancelTokens = react_1.useRef([]);
99
114
  var addCancelToken = function (token) { return cancelTokens.current.push(token); };
@@ -109,10 +124,11 @@ function useFetch(rawConfig) {
109
124
  if (newConfig) {
110
125
  setConfig(__assign(__assign(__assign({}, config), newConfig), { params: __assign(__assign({}, config === null || config === void 0 ? void 0 : config.params), newConfig === null || newConfig === void 0 ? void 0 : newConfig.params) }));
111
126
  }
127
+ setData(null);
112
128
  if (!config) return [3 /*break*/, 2];
113
129
  setIsLoading(true);
114
130
  _a = setData;
115
- return [4 /*yield*/, (config.onFetch || defaultFetchHandler).call(null, config, components, addCancelToken)];
131
+ return [4 /*yield*/, exports.fetchData(config, components, addCancelToken)];
116
132
  case 1:
117
133
  _a.apply(void 0, [_b.sent()]);
118
134
  setIsLoading(false);
@@ -122,28 +138,15 @@ function useFetch(rawConfig) {
122
138
  });
123
139
  });
124
140
  }, [components, config]);
141
+ react_use_1.useEffectOnce(function () {
142
+ if (!data) {
143
+ fetch();
144
+ }
145
+ });
125
146
  // Fetch data on config update
126
- react_1.useLayoutEffect(function () {
127
- var fetchData = function () { return __awaiter(_this, void 0, void 0, function () {
128
- var _a;
129
- return __generator(this, function (_b) {
130
- switch (_b.label) {
131
- case 0:
132
- setData(null);
133
- if (!config) return [3 /*break*/, 2];
134
- setIsLoading(true);
135
- _a = setData;
136
- return [4 /*yield*/, (config.onFetch || defaultFetchHandler).call(null, config, components, addCancelToken)];
137
- case 1:
138
- _a.apply(void 0, [_b.sent()]);
139
- setIsLoading(false);
140
- _b.label = 2;
141
- case 2: return [2 /*return*/];
142
- }
143
- });
144
- }); };
145
- fetchData();
146
- }, [components, config]);
147
+ react_use_1.useUpdateEffect(function () {
148
+ fetch();
149
+ }, [fetch]);
147
150
  return { data: data, isLoading: isLoading, fetch: fetch };
148
151
  }
149
152
  exports["default"] = useFetch;
package/hooks/useFile.js CHANGED
@@ -39,6 +39,7 @@ function generateBackendUrl(props) {
39
39
  });
40
40
  }
41
41
  function useFile(props) {
42
+ console.log(props.imagesOnly);
42
43
  var uploader = useInitial_1["default"](function () { return new fileup_core_1["default"](__assign(__assign({ dropArea: {}, backendUrl: generateBackendUrl(props) }, props.uploader), { form: __assign(__assign({}, (props.uploader && props.uploader.form)), { multiple: props.multiple }) })); });
43
44
  /**
44
45
  * Force component update when file status or progress changes
@@ -178,18 +179,29 @@ function useFile(props) {
178
179
  /**
179
180
  * Remove selected file from uploader
180
181
  * @param {File} fileToRemove
181
- * @private
182
182
  */
183
183
  var onRemove = function (fileToRemove) {
184
184
  uploader.queue.remove([fileToRemove]);
185
185
  forceUpdate();
186
186
  };
187
187
  var files = [].concat(uploader.queue.getFiles());
188
+ /**
189
+ * Add file to uploader
190
+ * @param {File} newFile
191
+ */
192
+ var onAdd = function (newFile) {
193
+ if (!props.multiple) {
194
+ uploader.queue.remove(files);
195
+ }
196
+ uploader.queue.add([newFile]);
197
+ forceUpdate();
198
+ };
188
199
  return {
189
200
  uploader: uploader,
190
201
  files: files,
191
202
  onBrowse: onBrowse,
192
- onRemove: onRemove
203
+ onRemove: onRemove,
204
+ onAdd: onAdd
193
205
  };
194
206
  }
195
207
  exports["default"] = useFile;
@@ -1,3 +1,5 @@
1
+ import { Dispatch } from 'redux';
2
+ import { IComponents } from '../providers/ComponentsProvider';
1
3
  export interface ILayout {
2
4
  status?: string;
3
5
  error?: any;
@@ -9,4 +11,11 @@ export declare const STATUS_RENDER_ERROR = "render_error";
9
11
  export declare const STATUS_HTTP_ERROR = "render_error";
10
12
  export declare const STATUS_ACCESS_DENIED = "access_denied";
11
13
  export declare const STATUS_OK = "ok";
14
+ export declare const HTTP_STATUS_CODES: {
15
+ not_found: number;
16
+ access_denied: number;
17
+ ok: number;
18
+ render_error: number;
19
+ };
20
+ export declare const runInitAction: (initAction: (...args: any[]) => Promise<any>, components: IComponents, dispatch: Dispatch<any>) => Promise<void>;
12
21
  export default function useLayout(initAction?: any): ILayout;
@@ -2,8 +2,9 @@
2
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
+ var _a;
5
6
  exports.__esModule = true;
6
- exports.STATUS_OK = exports.STATUS_ACCESS_DENIED = exports.STATUS_HTTP_ERROR = exports.STATUS_RENDER_ERROR = exports.STATUS_NOT_FOUND = exports.STATUS_LOADING = void 0;
7
+ exports.runInitAction = exports.HTTP_STATUS_CODES = exports.STATUS_OK = exports.STATUS_ACCESS_DENIED = exports.STATUS_HTTP_ERROR = exports.STATUS_RENDER_ERROR = exports.STATUS_NOT_FOUND = exports.STATUS_LOADING = void 0;
7
8
  var react_1 = require("react");
8
9
  var isFunction_1 = __importDefault(require("lodash-es/isFunction"));
9
10
  var isObject_1 = __importDefault(require("lodash-es/isObject"));
@@ -11,6 +12,7 @@ var upperFirst_1 = __importDefault(require("lodash-es/upperFirst"));
11
12
  var merge_1 = __importDefault(require("lodash-es/merge"));
12
13
  var intersection_1 = __importDefault(require("lodash-es/intersection"));
13
14
  var react_use_1 = require("react-use");
15
+ var useSsr_1 = __importDefault(require("./useSsr"));
14
16
  var useComponents_1 = __importDefault(require("./useComponents"));
15
17
  var router_1 = require("../reducers/router");
16
18
  var auth_1 = require("../reducers/auth");
@@ -25,6 +27,58 @@ exports.STATUS_RENDER_ERROR = 'render_error';
25
27
  exports.STATUS_HTTP_ERROR = 'render_error';
26
28
  exports.STATUS_ACCESS_DENIED = 'access_denied';
27
29
  exports.STATUS_OK = 'ok';
30
+ exports.HTTP_STATUS_CODES = (_a = {},
31
+ _a[exports.STATUS_NOT_FOUND] = 404,
32
+ _a[exports.STATUS_ACCESS_DENIED] = 403,
33
+ _a[exports.STATUS_OK] = 200,
34
+ _a[exports.STATUS_RENDER_ERROR] = 500,
35
+ _a[exports.STATUS_HTTP_ERROR] = 500,
36
+ _a);
37
+ var runInitAction = function (initAction, components, dispatch) { return (initAction(null, dispatch, components)
38
+ .then(function (result) {
39
+ // Configure components
40
+ if (isObject_1["default"](result.config)) {
41
+ Object.keys(result.config).forEach(function (name) {
42
+ if (!components[name]) {
43
+ return;
44
+ }
45
+ Object.keys(result.config[name]).forEach(function (key) {
46
+ var value = result.config[name][key];
47
+ var setter = 'set' + upperFirst_1["default"](key);
48
+ if (isFunction_1["default"](components[name][setter])) {
49
+ components[name][setter](value);
50
+ }
51
+ else if (isObject_1["default"](components[name][key])
52
+ && isObject_1["default"](value)) {
53
+ merge_1["default"](components[name][key], value);
54
+ }
55
+ else {
56
+ components[name][key] = value;
57
+ }
58
+ });
59
+ });
60
+ }
61
+ var resultMeta = result.meta;
62
+ var resultUser = result.user;
63
+ delete result.user;
64
+ delete result.meta;
65
+ if (resultMeta) {
66
+ Object.keys(resultMeta).forEach(function (modelName) {
67
+ if (resultMeta[modelName].attributes) {
68
+ components.meta.setModel(modelName, resultMeta[modelName]);
69
+ }
70
+ });
71
+ }
72
+ dispatch([
73
+ // Meta models & enums
74
+ Boolean(resultMeta) && fields_1.setMeta(resultMeta),
75
+ // User auth
76
+ auth_2.setData(result),
77
+ // User auth
78
+ auth_2.setUser(resultUser),
79
+ ].filter(Boolean));
80
+ })); };
81
+ exports.runInitAction = runInitAction;
28
82
  function useLayout(initAction) {
29
83
  if (initAction === void 0) { initAction = null; }
30
84
  var _a = useSelector_1["default"](function (state) { return ({
@@ -52,50 +106,11 @@ function useLayout(initAction) {
52
106
  if (!isFunction_1["default"](initAction) || initializeCounter <= initializeCounterPrev) {
53
107
  return;
54
108
  }
55
- initAction(null, dispatch)
56
- .then(function (result) {
57
- // Configure components
58
- if (isObject_1["default"](result.config)) {
59
- Object.keys(result.config).forEach(function (name) {
60
- if (!components[name]) {
61
- return;
62
- }
63
- Object.keys(result.config[name]).forEach(function (key) {
64
- var value = result.config[name][key];
65
- var setter = 'set' + upperFirst_1["default"](key);
66
- if (isFunction_1["default"](components[name][setter])) {
67
- components[name][setter](value);
68
- }
69
- else if (isObject_1["default"](components[name][key])
70
- && isObject_1["default"](value)) {
71
- merge_1["default"](components[name][key], value);
72
- }
73
- else {
74
- components[name][key] = value;
75
- }
76
- });
77
- });
109
+ exports.runInitAction(initAction, components, dispatch)
110
+ .then(function () {
111
+ if (redirectPageId) {
112
+ dispatch(router_2.goToRoute(redirectPageId));
78
113
  }
79
- var resultMeta = result.meta;
80
- var resultUser = result.user;
81
- delete result.user;
82
- delete result.meta;
83
- if (resultMeta) {
84
- Object.keys(resultMeta).forEach(function (modelName) {
85
- if (resultMeta[modelName].attributes) {
86
- components.meta.setModel(modelName, resultMeta[modelName]);
87
- }
88
- });
89
- }
90
- dispatch([
91
- // Meta models & enums
92
- Boolean(resultMeta) && fields_1.setMeta(resultMeta),
93
- // User auth
94
- auth_2.setData(result),
95
- // User auth
96
- auth_2.setUser(resultUser),
97
- redirectPageId && router_2.goToRoute(redirectPageId),
98
- ].filter(Boolean));
99
114
  })["catch"](function (e) {
100
115
  setError(e);
101
116
  throw e;
@@ -125,6 +140,11 @@ function useLayout(initAction) {
125
140
  }
126
141
  }
127
142
  }
143
+ //save status code for ssr
144
+ var ssrContextValue = useSsr_1["default"]();
145
+ if (process.env.IS_SSR) {
146
+ ssrContextValue.staticContext.statusCode = exports.HTTP_STATUS_CODES[status];
147
+ }
128
148
  return {
129
149
  status: status,
130
150
  error: error,