@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.
- package/actions/form.d.ts +9 -0
- package/actions/form.js +11 -1
- package/actions/list.d.ts +1 -0
- package/actions/list.js +1 -0
- package/components/ClientStorageComponent.d.ts +3 -3
- package/components/ClientStorageComponent.js +28 -22
- package/components/HttpComponent.js +32 -15
- package/components/LocaleComponent.js +9 -9
- package/components/MetricsComponent.js +3 -1
- package/components/StoreComponent.d.ts +6 -0
- package/components/StoreComponent.js +6 -7
- package/components/UiComponent.d.ts +1 -1
- package/components/WebSocketComponent.d.ts +1 -1
- package/hoc/components.d.ts +1 -1
- package/hoc/components.js +1 -1
- package/hoc/file.d.ts +1 -0
- package/hooks/index.d.ts +2 -1
- package/hooks/index.js +3 -1
- package/hooks/useAbsolutePositioning.d.ts +5 -0
- package/hooks/useAbsolutePositioning.js +6 -6
- package/hooks/useApplication.d.ts +29 -26
- package/hooks/useApplication.js +17 -82
- package/hooks/useComponents.d.ts +1 -14
- package/hooks/useComponents.js +5 -5
- package/hooks/useDataProvider.js +4 -2
- package/hooks/useDataSelect.d.ts +12 -6
- package/hooks/useDataSelect.js +5 -3
- package/hooks/useFetch.d.ts +11 -3
- package/hooks/useFetch.js +34 -31
- package/hooks/useFile.js +14 -2
- package/hooks/useLayout.d.ts +9 -0
- package/hooks/useLayout.js +64 -44
- package/hooks/useList.d.ts +45 -0
- package/hooks/useList.js +83 -53
- package/hooks/useModel.js +1 -1
- package/hooks/useScreen.d.ts +1 -1
- package/hooks/useScreen.js +2 -2
- package/hooks/useSsr.d.ts +2 -0
- package/hooks/useSsr.js +8 -0
- package/index.d.ts +8 -2
- package/package.json +6 -3
- package/providers/ComponentsProvider.d.ts +26 -0
- package/providers/ComponentsProvider.js +28 -0
- package/providers/ScreenProvider.d.ts +20 -0
- package/providers/ScreenProvider.js +87 -0
- package/providers/SsrProvider.d.ts +17 -0
- package/providers/SsrProvider.js +32 -0
- package/providers/index.d.ts +4 -0
- package/providers/index.js +12 -0
- package/reducers/form.d.ts +1 -1
- package/reducers/form.js +3 -1
- package/reducers/index.js +1 -1
- package/reducers/list.js +1 -3
- package/reducers/router.js +1 -1
- package/ui/content/Alert/Alert.d.ts +50 -0
- package/ui/content/Alert/Alert.js +39 -0
- package/ui/content/Alert/index.d.ts +2 -0
- package/ui/content/Alert/index.js +7 -0
- package/ui/content/Avatar/Avatar.d.ts +53 -12
- package/ui/content/Avatar/Avatar.js +25 -4
- package/ui/content/Avatar/index.d.ts +6 -1
- package/ui/content/Avatar/index.js +4 -0
- package/ui/content/Card/Card.d.ts +61 -13
- package/ui/content/Card/Card.js +3 -2
- package/ui/content/Collapse/Collapse.d.ts +63 -0
- package/ui/content/Collapse/Collapse.js +75 -0
- package/ui/content/Collapse/CollapseItem.d.ts +67 -0
- package/ui/content/Collapse/CollapseItem.js +22 -0
- package/ui/content/Collapse/index.d.ts +7 -0
- package/ui/content/Collapse/index.js +8 -0
- package/ui/content/Detail/Detail.d.ts +102 -0
- package/ui/content/Detail/Detail.js +155 -0
- package/ui/content/Detail/DetailItem.d.ts +43 -0
- package/ui/content/Detail/DetailItem.js +10 -0
- package/ui/content/Detail/demo/basic.d.ts +8 -0
- package/ui/content/Detail/demo/basic.js +56 -0
- package/ui/content/Detail/demo/controls.d.ts +8 -0
- package/ui/content/Detail/demo/controls.js +56 -0
- package/ui/content/Detail/demo/layout.d.ts +8 -0
- package/ui/content/Detail/demo/layout.js +56 -0
- package/ui/content/Detail/demo/responsive.d.ts +8 -0
- package/ui/content/Detail/demo/responsive.js +71 -0
- package/ui/content/Detail/demo/sizes.d.ts +8 -0
- package/ui/content/Detail/demo/sizes.js +61 -0
- package/ui/content/Detail/index.d.ts +3 -0
- package/ui/content/Detail/index.js +10 -0
- package/ui/content/DropDown/DropDown.d.ts +1 -0
- package/ui/content/DropDown/DropDown.js +1 -0
- package/ui/content/index.d.ts +13 -0
- package/ui/content/index.js +22 -0
- package/ui/crud/Crud/Crud.d.ts +1 -1
- package/ui/crud/Crud/Crud.js +1 -1
- package/ui/crud/index.d.ts +1 -0
- package/ui/form/Button/Button.d.ts +1 -0
- package/ui/form/Button/Button.js +1 -0
- package/ui/form/DateField/useDateInputState.d.ts +4 -0
- package/ui/form/DateField/useDateInputState.js +3 -3
- package/ui/form/DateField/useDateTime.js +9 -7
- package/ui/form/DateTimeField/DateTimeField.js +2 -1
- package/ui/form/DropDownField/DropDownField.js +10 -3
- package/ui/form/Form/Form.js +118 -106
- package/ui/form/ImageField/ImageField.d.ts +87 -0
- package/ui/form/ImageField/ImageField.js +145 -0
- package/ui/form/ImageField/index.d.ts +2 -0
- package/ui/form/ImageField/index.js +7 -0
- package/ui/form/InputField/InputField.d.ts +7 -0
- package/ui/form/InputField/InputField.js +26 -22
- package/ui/form/TextField/TextField.d.ts +2 -1
- package/ui/form/TextField/TextField.js +1 -1
- package/ui/icon/Icon/Icon.js +3 -0
- package/ui/layout/Meta/Meta.d.ts +56 -0
- package/ui/layout/Meta/Meta.js +38 -0
- package/ui/layout/Meta/index.d.ts +2 -0
- package/ui/layout/Meta/index.js +7 -0
- package/ui/layout/Notifications/Notifications.js +1 -1
- package/ui/layout/Portal.js +3 -0
- package/ui/layout/ProgressBar/ProgressBar.d.ts +55 -0
- package/ui/layout/ProgressBar/ProgressBar.js +52 -0
- package/ui/layout/ProgressBar/index.d.ts +2 -0
- package/ui/layout/ProgressBar/index.js +7 -0
- package/ui/layout/Skeleton/Skeleton.d.ts +25 -0
- package/ui/layout/Skeleton/Skeleton.js +11 -0
- package/ui/layout/Skeleton/index.d.ts +2 -0
- package/ui/layout/Skeleton/index.js +7 -0
- package/ui/list/Steps/Steps.d.ts +32 -0
- package/ui/list/Steps/Steps.js +23 -0
- package/ui/list/Steps/index.d.ts +2 -0
- package/ui/list/Steps/index.js +7 -0
- package/ui/nav/Router/Router.d.ts +13 -0
- package/ui/nav/Router/Router.js +1 -1
- package/utils/calendar.d.ts +1 -1
- package/utils/calendar.js +8 -1
- package/ui/content/Avatar/SizeContext.d.ts +0 -1
- package/ui/content/Avatar/SizeContext.js +0 -14
- package/ui/nav/Router/SsrProvider.d.ts +0 -15
- 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
|
+
};
|
package/ui/crud/Crud/Crud.d.ts
CHANGED
|
@@ -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 '../../../
|
|
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';
|
package/ui/crud/Crud/Crud.js
CHANGED
package/ui/crud/index.d.ts
CHANGED
|
@@ -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
|
};
|
package/ui/form/Button/Button.js
CHANGED
|
@@ -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,
|
|
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.
|
|
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
|
-
|
|
21
|
-
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
package/ui/form/Form/Form.js
CHANGED
|
@@ -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) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return [
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
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;
|