@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
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ exports.__esModule = true;
6
+ exports.DetailItem = exports.Detail = void 0;
7
+ var Detail_1 = __importDefault(require("./Detail"));
8
+ exports.Detail = Detail_1["default"];
9
+ var DetailItem_1 = __importDefault(require("./DetailItem"));
10
+ exports.DetailItem = DetailItem_1["default"];
@@ -29,6 +29,7 @@ export interface IDropDownViewProps extends IDropDownProps, IAbsolutePositioning
29
29
  declare function DropDown(props: IDropDownProps): JSX.Element;
30
30
  declare namespace DropDown {
31
31
  var defaultProps: {
32
+ autoPositioning: boolean;
32
33
  componentDestroyDelay: number;
33
34
  defaultVisible: boolean;
34
35
  gap: number;
@@ -71,6 +71,7 @@ function DropDown(props) {
71
71
  React.createElement(DropDownView, { className: props.className, forwardedRef: forwardedRef, content: props.content, position: position, style: style, calculatePosition: calculatePosition, isComponentVisible: isComponentVisible })))));
72
72
  }
73
73
  DropDown.defaultProps = {
74
+ autoPositioning: false,
74
75
  componentDestroyDelay: 300,
75
76
  defaultVisible: false,
76
77
  gap: 15,
@@ -0,0 +1,13 @@
1
+ import { Avatar, AvatarGroup } from './Avatar';
2
+ import Card from './Card';
3
+ import DropDown from './DropDown';
4
+ import Alert from './Alert';
5
+ export { Avatar, AvatarGroup, Alert, Card, DropDown, };
6
+ declare const _default: {
7
+ Avatar: typeof Avatar;
8
+ AvatarGroup: typeof AvatarGroup;
9
+ Alert: typeof Alert;
10
+ Card: typeof Card;
11
+ DropDown: typeof DropDown;
12
+ };
13
+ export default _default;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ exports.__esModule = true;
6
+ exports.DropDown = exports.Card = exports.Alert = exports.AvatarGroup = exports.Avatar = void 0;
7
+ var Avatar_1 = require("./Avatar");
8
+ exports.Avatar = Avatar_1.Avatar;
9
+ exports.AvatarGroup = Avatar_1.AvatarGroup;
10
+ var Card_1 = __importDefault(require("./Card"));
11
+ exports.Card = Card_1["default"];
12
+ var DropDown_1 = __importDefault(require("./DropDown"));
13
+ exports.DropDown = DropDown_1["default"];
14
+ var Alert_1 = __importDefault(require("./Alert"));
15
+ exports.Alert = Alert_1["default"];
16
+ exports["default"] = {
17
+ Avatar: Avatar_1.Avatar,
18
+ AvatarGroup: Avatar_1.AvatarGroup,
19
+ Alert: Alert_1["default"],
20
+ Card: Card_1["default"],
21
+ DropDown: DropDown_1["default"]
22
+ };
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { IApiRest } from '../../../components/ApiComponent';
4
- import { IComponents } from '../../../hooks/useComponents';
4
+ import { IComponents } from '../../../providers/ComponentsProvider';
5
5
  import { IComponentsHocOutput } from '../../../hoc/components';
6
6
  import { IConnectHocOutput } from '../../../hoc/connect';
7
7
  import { IFormProps } from '../../form/Form/Form';
@@ -131,7 +131,7 @@ function Crud(props) {
131
131
  return;
132
132
  }
133
133
  }
134
- crudItem.onClick(e, localClickProps);
134
+ crudItem.onClick(e, __assign(__assign({}, clickProps), localClickProps));
135
135
  };
136
136
  }
137
137
  else {
@@ -31,4 +31,5 @@ export declare const generateCrud: (routeId: string, props: ICrudGeneratorProps)
31
31
  items?: IRouteItem[] | {
32
32
  [key: string]: IRouteItem;
33
33
  };
34
+ preloadData?: (match: Record<string, any>) => (import("../../hooks/useFetch").IFetchConfig | import("../list/List/List").IListProps)[];
34
35
  };
@@ -177,6 +177,7 @@ declare namespace Button {
177
177
  disabled: boolean;
178
178
  submitting: boolean;
179
179
  block: boolean;
180
+ size: string;
180
181
  className: string;
181
182
  resetFailedMs: number;
182
183
  showLabelOnLoading: boolean;
@@ -136,6 +136,7 @@ Button.defaultProps = {
136
136
  disabled: false,
137
137
  submitting: false,
138
138
  block: false,
139
+ size: 'md',
139
140
  className: '',
140
141
  resetFailedMs: 2000,
141
142
  showLabelOnLoading: true,
@@ -35,6 +35,10 @@ export interface IDateInputStateInput extends IFieldWrapperInputProps {
35
35
  * @example YYYY-MM-DD
36
36
  */
37
37
  valueFormat?: string;
38
+ /**
39
+ * Использовать всемирное время (UTC) вместо местного для даты, отправляемой на сервер
40
+ */
41
+ useUTC?: boolean;
38
42
  }
39
43
  export interface IDateInputStateOutput {
40
44
  /**
@@ -40,15 +40,15 @@ function useDateInputState(props) {
40
40
  // Display input change handler
41
41
  var onDisplayValueChange = react_1.useCallback(function (value) {
42
42
  setDisplayValue(value);
43
- var parsedValue = calendar_1.convertDate(value, props.displayFormat, props.valueFormat);
43
+ var parsedValue = calendar_1.convertDate(value, props.displayFormat, props.valueFormat, props.useUTC);
44
44
  var newValue = parsedValue || !value ? parsedValue || null : false;
45
45
  if (newValue !== false && newValue !== props.input.value) {
46
46
  props.input.onChange.call(null, newValue);
47
47
  if (props.onChange) {
48
- props.onChange.call(null, newValue);
48
+ props.onChange.call(null, value);
49
49
  }
50
50
  }
51
- }, [props.displayFormat, props.input.onChange, props.input.value, props.onChange, props.valueFormat]);
51
+ }, [props.displayFormat, props.input.onChange, props.input.value, props.onChange, props.useUTC, props.valueFormat]);
52
52
  // Dropdown opened state
53
53
  var _b = react_1.useState(false), isOpened = _b[0], setIsOpened = _b[1];
54
54
  // Focus/blur handlers
@@ -12,16 +12,18 @@ var calendar_1 = require("../../../utils/calendar");
12
12
  * Возвращает значения и обработчики для передачи в Calendar и TimePanel
13
13
  */
14
14
  function useDateTime(props) {
15
- var _a = props.displayFormat.split(props.dateTimeSeparator), dateValueFormat = _a[0], timeValueFormat = _a[1];
16
- var dateValue = calendar_1.convertDate(props.input.value, [props.displayFormat, props.valueFormat], dateValueFormat);
17
- var timeValue = calendar_1.convertDate(props.input.value, [props.displayFormat, props.valueFormat], timeValueFormat);
15
+ var _a = props.valueFormat.split(props.dateTimeSeparator), dateValueFormat = _a[0], timeValueFormat = _a[1];
16
+ var dateValue = react_1.useMemo(function () { return calendar_1.convertDate(props.input.value, [props.displayFormat, props.valueFormat], dateValueFormat); }, [dateValueFormat, props.displayFormat, props.input.value, props.valueFormat]);
17
+ var timeValue = react_1.useMemo(function () { return calendar_1.convertDate(props.input.value, [props.displayFormat, props.valueFormat], timeValueFormat); }, [props.displayFormat, props.input.value, props.valueFormat, timeValueFormat]);
18
18
  // Handler for calendar and time picker changes
19
19
  var onDateSelect = react_1.useCallback(function (date) {
20
- props.input.onChange.call(null, date + props.dateTimeSeparator + (timeValue || '00:00'));
21
- }, [props.dateTimeSeparator, props.input.onChange, timeValue]);
20
+ var result = date + props.dateTimeSeparator + (timeValue || '00:00');
21
+ props.input.onChange.call(null, calendar_1.convertDate(result, props.valueFormat, props.valueFormat, true));
22
+ }, [props.dateTimeSeparator, props.input.onChange, props.valueFormat, timeValue]);
22
23
  var onTimeSelect = react_1.useCallback(function (time) {
23
- props.input.onChange.call(null, (dateValue || moment_1["default"]().format(dateValueFormat)) + props.dateTimeSeparator + time);
24
- }, [dateValue, dateValueFormat, props.dateTimeSeparator, props.input.onChange]);
24
+ var result = (dateValue || moment_1["default"]().format(dateValueFormat)) + props.dateTimeSeparator + time;
25
+ props.input.onChange.call(null, calendar_1.convertDate(result, props.valueFormat, props.valueFormat, true));
26
+ }, [dateValue, dateValueFormat, props.dateTimeSeparator, props.input.onChange, props.valueFormat]);
25
27
  return {
26
28
  dateValue: dateValue,
27
29
  timeValue: timeValue,
@@ -34,7 +34,8 @@ function DateTimeField(props) {
34
34
  inputProps: props.inputProps,
35
35
  placeholder: props.placeholder,
36
36
  valueFormat: props.valueFormat,
37
- displayFormat: props.displayFormat
37
+ displayFormat: props.displayFormat,
38
+ useUTC: true
38
39
  }), onClear = _a.onClear, onClose = _a.onClose, isOpened = _a.isOpened, inputProps = _a.inputProps;
39
40
  var _b = useDateTime_1["default"]({
40
41
  displayFormat: props.displayFormat,
@@ -30,7 +30,7 @@ function DropDownField(props) {
30
30
  autoComplete: props.autoComplete,
31
31
  autoFetch: props.autoFetch,
32
32
  query: query
33
- }), items = _b.items, isLoading = _b.isLoading, isAutoComplete = _b.isAutoComplete;
33
+ }), items = _b.items, isLoading = _b.isLoading, isAutoComplete = _b.isAutoComplete, sourceItems = _b.sourceItems;
34
34
  var inputSelectedIds = react_1.useMemo(function () { return props.selectedIds || [].concat(props.input.value || []); }, [props.input.value, props.selectedIds]);
35
35
  // Data select
36
36
  var _c = hooks_1.useDataSelect({
@@ -39,6 +39,7 @@ function DropDownField(props) {
39
39
  selectedIds: inputSelectedIds,
40
40
  primaryKey: props.primaryKey,
41
41
  items: items,
42
+ sourceItems: sourceItems,
42
43
  inputValue: props.input.value
43
44
  }), isOpened = _c.isOpened, setIsOpened = _c.setIsOpened, setIsFocused = _c.setIsFocused, hoveredId = _c.hoveredId, setHoveredId = _c.setHoveredId, selectedIds = _c.selectedIds, setSelectedIds = _c.setSelectedIds;
44
45
  var onOpen = react_1.useCallback(function () {
@@ -65,7 +66,9 @@ function DropDownField(props) {
65
66
  }, [setIsFocused, setIsOpened]);
66
67
  // Outside click -> close
67
68
  var forwardedRef = react_1.useRef(null);
68
- react_use_1.useClickAway(forwardedRef, onClose);
69
+ if (process.env.PLATFORM !== 'mobile') {
70
+ react_use_1.useClickAway(forwardedRef, onClose);
71
+ }
69
72
  // Search input props
70
73
  var searchInputProps = react_1.useMemo(function () { return ({
71
74
  type: 'search',
@@ -84,7 +87,11 @@ function DropDownField(props) {
84
87
  props.onChange(newValues);
85
88
  }
86
89
  }
87
- }, [selectedIds, props.input.onChange, props.multiple, prevSelectedIds, props.attribute, props]);
90
+ //if form reset
91
+ if (props.input.value === undefined && selectedIds.length > 0) {
92
+ onReset();
93
+ }
94
+ }, [selectedIds, props.input.onChange, props.multiple, prevSelectedIds, props.attribute, props, onReset]);
88
95
  return components.ui.renderView(props.view || 'form.DropDownFieldView', __assign(__assign({}, props), { isAutoComplete: isAutoComplete,
89
96
  items: items,
90
97
  hoveredId: hoveredId,
@@ -123,7 +123,7 @@ function Form(props) {
123
123
  }
124
124
  // Init data provider
125
125
  var provider = props.useRedux ? form_1.providers.redux : form_1.providers.reducer;
126
- var _a = provider.useForm(props.formId, initialValues), values = _a.values, isInvalid = _a.isInvalid, isSubmitting = _a.isSubmitting, setErrors = _a.setErrors, reducer = _a.reducer, dispatch = _a.dispatch;
126
+ var _a = provider.useForm(props.formId, initialValues), values = _a.values, submitCounter = _a.submitCounter, isInvalid = _a.isInvalid, isSubmitting = _a.isSubmitting, setErrors = _a.setErrors, reducer = _a.reducer, dispatch = _a.dispatch;
127
127
  // Sync with address bar
128
128
  react_use_1.useUpdateEffect(function () {
129
129
  if (props.syncWithAddressBar) {
@@ -166,116 +166,128 @@ function Form(props) {
166
166
  }
167
167
  }, [props, values]);
168
168
  // OnSubmit handler
169
- var onSubmit = react_1.useCallback(function (e) { return __awaiter(_this, void 0, void 0, function () {
170
- var cleanedValues, captchaAttribute, googleCaptcha, captchaToken, options, response, _a, data;
171
- var _b;
172
- var _this = this;
173
- return __generator(this, function (_c) {
174
- switch (_c.label) {
175
- case 0:
176
- // TODO
177
- e.preventDefault();
178
- // Append non touched fields to values object
179
- if (props.formId) {
180
- Object.keys(components.ui.getRegisteredFields(props.formId) || {})
181
- .forEach(function (key) {
182
- if (isUndefined_1["default"](get_1["default"](values, key))) {
183
- set_1["default"](values, key, null);
169
+ var onSubmit = react_1.useCallback(function (e) {
170
+ if (e === void 0) { e = null; }
171
+ return __awaiter(_this, void 0, void 0, function () {
172
+ var cleanedValues, captchaAttribute, googleCaptcha, captchaToken, options, response, _a, data;
173
+ var _b;
174
+ var _this = this;
175
+ return __generator(this, function (_c) {
176
+ switch (_c.label) {
177
+ case 0:
178
+ // TODO
179
+ if (e) {
180
+ e.preventDefault();
181
+ }
182
+ // Append non touched fields to values object
183
+ if (props.formId) {
184
+ Object.keys(components.ui.getRegisteredFields(props.formId) || {})
185
+ .forEach(function (key) {
186
+ if (isUndefined_1["default"](get_1["default"](values, key))) {
187
+ set_1["default"](values, key, null);
188
+ }
189
+ });
190
+ }
191
+ cleanedValues = form_1.cleanEmptyObject(values);
192
+ // Event onBeforeSubmit
193
+ if (props.onBeforeSubmit && props.onBeforeSubmit.call(null, cleanedValues) === false) {
194
+ return [2 /*return*/, null];
195
+ }
196
+ if (props.validators) {
197
+ validate_1["default"](cleanedValues, props.validators);
198
+ }
199
+ if (props.onSubmit) {
200
+ return [2 /*return*/, props.onSubmit.call(null, cleanedValues)];
201
+ }
202
+ captchaAttribute = null;
203
+ Object.entries(components.ui.getRegisteredFields(props.formId) || {}).forEach(function (_a) {
204
+ var attribute = _a[0], fieldType = _a[1];
205
+ if (fieldType === 'ReCaptchaField') {
206
+ captchaAttribute = attribute;
184
207
  }
185
208
  });
186
- }
187
- cleanedValues = form_1.cleanEmptyObject(values);
188
- // Event onBeforeSubmit
189
- if (props.onBeforeSubmit && props.onBeforeSubmit.call(null, cleanedValues) === false) {
190
- return [2 /*return*/, null];
191
- }
192
- if (props.validators) {
193
- validate_1["default"](cleanedValues, props.validators);
194
- }
195
- if (props.onSubmit) {
196
- return [2 /*return*/, props.onSubmit.call(null, cleanedValues)];
197
- }
198
- captchaAttribute = null;
199
- Object.entries(components.ui.getRegisteredFields(props.formId) || {}).forEach(function (_a) {
200
- var attribute = _a[0], fieldType = _a[1];
201
- if (fieldType === 'ReCaptchaField') {
202
- captchaAttribute = attribute;
209
+ if (!(captchaAttribute && components.resource.googleCaptchaSiteKey)) return [3 /*break*/, 3];
210
+ return [4 /*yield*/, components.resource.loadGoogleCaptcha()];
211
+ case 1:
212
+ googleCaptcha = _c.sent();
213
+ return [4 /*yield*/, getCaptchaToken({
214
+ googleCaptcha: googleCaptcha,
215
+ siteKey: components.resource.googleCaptchaSiteKey,
216
+ actionName: props.captchaActionName
217
+ })];
218
+ case 2:
219
+ captchaToken = _c.sent();
220
+ cleanedValues = __assign(__assign({}, cleanedValues), (_b = {}, _b[captchaAttribute] = captchaToken, _b));
221
+ _c.label = 3;
222
+ case 3:
223
+ options = {
224
+ onTwoFactor: props.onTwoFactor
225
+ ? function (providerName) { return __awaiter(_this, void 0, void 0, function () {
226
+ var info, _a;
227
+ return __generator(this, function (_b) {
228
+ switch (_b.label) {
229
+ case 0:
230
+ if (!props.autoStartTwoFactor) return [3 /*break*/, 2];
231
+ return [4 /*yield*/, components.http.post("/api/v1/auth/2fa/" + providerName + "/send")];
232
+ case 1:
233
+ _a = _b.sent();
234
+ return [3 /*break*/, 3];
235
+ case 2:
236
+ _a = null;
237
+ _b.label = 3;
238
+ case 3:
239
+ info = _a;
240
+ props.onTwoFactor(providerName, info);
241
+ return [2 /*return*/];
242
+ }
243
+ });
244
+ }); }
245
+ : undefined
246
+ };
247
+ if (!(typeof props.action === 'function')) return [3 /*break*/, 5];
248
+ return [4 /*yield*/, props.action.call(null, components.api, cleanedValues, options)];
249
+ case 4:
250
+ _a = _c.sent();
251
+ return [3 /*break*/, 7];
252
+ case 5: return [4 /*yield*/, components.http.send(props.actionMethod, props.action || window.location.pathname, cleanedValues, options)];
253
+ case 6:
254
+ _a = _c.sent();
255
+ _c.label = 7;
256
+ case 7:
257
+ response = _a;
258
+ // Skip on 2fa
259
+ if (response.twoFactor) {
260
+ return [2 /*return*/, null];
261
+ }
262
+ data = response.data || {};
263
+ // Event onAfterSubmit
264
+ if (props.onAfterSubmit && props.onAfterSubmit.call(null, cleanedValues, data, response) === false) {
265
+ return [2 /*return*/, null];
266
+ }
267
+ if (data.errors) {
268
+ setErrors(data.errors);
269
+ return [2 /*return*/, null];
270
+ }
271
+ if (props.onComplete) {
272
+ props.onComplete.call(null, cleanedValues, data, response);
273
+ }
274
+ if (props.autoSave) {
275
+ // TODO
276
+ //const AutoSaveHelper = require('../ui/form/Form/AutoSaveHelper').default;
277
+ //AutoSaveHelper.remove(props.clientStorage, props.formId);
203
278
  }
204
- });
205
- if (!(captchaAttribute && components.resource.googleCaptchaSiteKey)) return [3 /*break*/, 3];
206
- return [4 /*yield*/, components.resource.loadGoogleCaptcha()];
207
- case 1:
208
- googleCaptcha = _c.sent();
209
- return [4 /*yield*/, getCaptchaToken({
210
- googleCaptcha: googleCaptcha,
211
- siteKey: components.resource.googleCaptchaSiteKey,
212
- actionName: props.captchaActionName
213
- })];
214
- case 2:
215
- captchaToken = _c.sent();
216
- cleanedValues = __assign(__assign({}, cleanedValues), (_b = {}, _b[captchaAttribute] = captchaToken, _b));
217
- _c.label = 3;
218
- case 3:
219
- options = {
220
- onTwoFactor: props.onTwoFactor
221
- ? function (providerName) { return __awaiter(_this, void 0, void 0, function () {
222
- var info, _a;
223
- return __generator(this, function (_b) {
224
- switch (_b.label) {
225
- case 0:
226
- if (!props.autoStartTwoFactor) return [3 /*break*/, 2];
227
- return [4 /*yield*/, components.http.post("/api/v1/auth/2fa/" + providerName + "/send")];
228
- case 1:
229
- _a = _b.sent();
230
- return [3 /*break*/, 3];
231
- case 2:
232
- _a = null;
233
- _b.label = 3;
234
- case 3:
235
- info = _a;
236
- props.onTwoFactor(providerName, info);
237
- return [2 /*return*/];
238
- }
239
- });
240
- }); }
241
- : undefined
242
- };
243
- if (!(typeof props.action === 'function')) return [3 /*break*/, 5];
244
- return [4 /*yield*/, props.action(components.api, cleanedValues, options)];
245
- case 4:
246
- _a = _c.sent();
247
- return [3 /*break*/, 7];
248
- case 5: return [4 /*yield*/, components.http.send(props.actionMethod, props.action || window.location.pathname, cleanedValues, options)];
249
- case 6:
250
- _a = _c.sent();
251
- _c.label = 7;
252
- case 7:
253
- response = _a;
254
- // Skip on 2fa
255
- if (response.twoFactor) {
256
- return [2 /*return*/, null];
257
- }
258
- data = response.data || {};
259
- // Event onAfterSubmit
260
- if (props.onAfterSubmit && props.onAfterSubmit.call(null, cleanedValues, data, response) === false) {
261
- return [2 /*return*/, null];
262
- }
263
- if (data.errors) {
264
- setErrors(data.errors);
265
279
  return [2 /*return*/, null];
266
- }
267
- if (props.onComplete) {
268
- props.onComplete.call(null, cleanedValues, data, response);
269
- }
270
- if (props.autoSave) {
271
- // TODO
272
- //const AutoSaveHelper = require('../ui/form/Form/AutoSaveHelper').default;
273
- //AutoSaveHelper.remove(props.clientStorage, props.formId);
274
- }
275
- return [2 /*return*/, null];
276
- }
280
+ }
281
+ });
277
282
  });
278
- }); }, [components.api, components.http, components.resource, components.ui, props, setErrors, values]);
283
+ }, [components.api, components.http, components.resource, components.ui, props, setErrors, values]);
284
+ // Manual submit form by reducer action
285
+ var prevSubmitCounter = react_use_1.usePrevious(submitCounter);
286
+ react_use_1.useUpdateEffect(function () {
287
+ if (submitCounter !== prevSubmitCounter) {
288
+ onSubmit.call(null);
289
+ }
290
+ }, [prevSubmitCounter, submitCounter, onSubmit]);
279
291
  var formContextValue = react_1.useMemo(function () { return ({
280
292
  formId: props.formId,
281
293
  model: props.model,
@@ -0,0 +1,87 @@
1
+ /// <reference types="react" />
2
+ import ReactCropProps, { Crop } from 'react-image-crop';
3
+ import { IModalProps } from '../../modal/Modal/Modal';
4
+ import { IFieldWrapperInputProps } from '../Field/fieldWrapper';
5
+ import { IFileHocInput, IFileHocOutput } from '../../../hoc/file';
6
+ export interface ICropInputProps {
7
+ /**
8
+ * Изначальные параметры обрезки изображения
9
+ * @example {unit: 'px', aspect: 1, x: 0, y: 0, width: 200, height: 200}
10
+ */
11
+ initialValues?: Crop;
12
+ /**
13
+ * Экшн для отправки параметров обрезки на бэкенд
14
+ * @example '/api/v1/user/avatar/crop'
15
+ */
16
+ backendUrl?: string;
17
+ /**
18
+ * Пропсы для модуля react-image-crop
19
+ * @example {maxWidth: 400, maxHeight: 400}
20
+ */
21
+ reactImageCropProps?: ReactCropProps;
22
+ }
23
+ export interface IImageFieldProps extends IFieldWrapperInputProps, Omit<IFileHocInput, 'multiple' | 'imagesOnly'>, IFileHocOutput {
24
+ /**
25
+ * Дополнительный CSS-класс для компонента
26
+ */
27
+ className?: CssClassName;
28
+ /**
29
+ * Переопределение внешнего вида компонента
30
+ * @example MyCustomView
31
+ */
32
+ view?: CustomView;
33
+ /**
34
+ * Переопределение внешнего вида модального окна
35
+ * @example MyCustomModalView
36
+ */
37
+ modalView?: CustomView;
38
+ /**
39
+ * Пропсы для модального окна
40
+ */
41
+ modalProps?: IModalProps;
42
+ /**
43
+ * Параметры обрезки
44
+ */
45
+ crop?: ICropInputProps;
46
+ /**
47
+ * Название кнопки
48
+ * @example 'Загрузить'
49
+ */
50
+ label?: string;
51
+ [key: string]: any;
52
+ }
53
+ export interface ICropOutputProps extends ICropInputProps {
54
+ onSubmit: (crop: Crop, imageId: any) => void;
55
+ }
56
+ export interface IImageFieldModalViewProps extends IModalProps {
57
+ crop: ICropOutputProps;
58
+ image: Record<string, any>;
59
+ }
60
+ export interface IImageFieldViewProps extends IImageFieldProps {
61
+ item: {
62
+ uid?: string;
63
+ fileId?: number | string;
64
+ title?: string;
65
+ size: number | string;
66
+ disabled?: boolean;
67
+ onRemove?: () => void;
68
+ error?: string;
69
+ image?: {
70
+ url: string;
71
+ width: string;
72
+ height: string;
73
+ };
74
+ progress?: {
75
+ bytesUploaded: number;
76
+ percent: number;
77
+ };
78
+ };
79
+ onClick: (e: Event) => void;
80
+ }
81
+ declare const _default: {
82
+ (props: IFieldWrapperInputProps): JSX.Element;
83
+ WrappedComponent: any;
84
+ displayName: any;
85
+ defaultProps: any;
86
+ };
87
+ export default _default;