@steroidsjs/core 2.2.29 → 2.2.32
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/fields.d.ts +6 -0
- package/actions/fields.js +8 -1
- package/hooks/useDataProvider.d.ts +6 -0
- package/hooks/useDataProvider.js +19 -4
- package/package.json +1 -1
- package/reducers/fields.d.ts +3 -0
- package/reducers/fields.js +7 -1
- package/ui/form/Field/fieldWrapper.d.ts +1 -0
- package/ui/form/Field/fieldWrapper.js +29 -7
- package/ui/form/Form/Form.js +21 -16
- package/ui/layout/Meta/Meta.js +1 -3
package/actions/fields.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export declare const FIELDS_SET_META = "FIELDS_SET_META";
|
|
2
|
+
export declare const FIELDS_DATA_PROVIDER_SET_ITEMS = "@fields/data_provider_set_items";
|
|
2
3
|
export declare const setMeta: (meta: any) => {
|
|
3
4
|
type: string;
|
|
4
5
|
meta: any;
|
|
5
6
|
};
|
|
7
|
+
export declare const fieldsDataProviderSetItems: (dataProviderId: any, items: any) => {
|
|
8
|
+
type: string;
|
|
9
|
+
dataProviderId: any;
|
|
10
|
+
items: any;
|
|
11
|
+
};
|
package/actions/fields.js
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
exports.__esModule = true;
|
|
3
|
-
exports.setMeta = exports.FIELDS_SET_META = void 0;
|
|
3
|
+
exports.fieldsDataProviderSetItems = exports.setMeta = exports.FIELDS_DATA_PROVIDER_SET_ITEMS = exports.FIELDS_SET_META = void 0;
|
|
4
4
|
exports.FIELDS_SET_META = 'FIELDS_SET_META';
|
|
5
|
+
exports.FIELDS_DATA_PROVIDER_SET_ITEMS = '@fields/data_provider_set_items';
|
|
5
6
|
var setMeta = function (meta) { return ({
|
|
6
7
|
type: exports.FIELDS_SET_META,
|
|
7
8
|
meta: meta
|
|
8
9
|
}); };
|
|
9
10
|
exports.setMeta = setMeta;
|
|
11
|
+
var fieldsDataProviderSetItems = function (dataProviderId, items) { return ({
|
|
12
|
+
type: exports.FIELDS_DATA_PROVIDER_SET_ITEMS,
|
|
13
|
+
dataProviderId: dataProviderId,
|
|
14
|
+
items: items
|
|
15
|
+
}); };
|
|
16
|
+
exports.fieldsDataProviderSetItems = fieldsDataProviderSetItems;
|
|
@@ -35,6 +35,12 @@ export interface IDataProviderConfig {
|
|
|
35
35
|
* Если dataProvider не передан, то поиск данных по запросу происходит локально.
|
|
36
36
|
*/
|
|
37
37
|
dataProvider?: {
|
|
38
|
+
/**
|
|
39
|
+
* Уникальный (глобально) идентификатор, под которых будут храниться
|
|
40
|
+
* подгруженные данные в redux (при включенном флаге useRedux). Если
|
|
41
|
+
* не задан - данные будут храниться в локальном стейте
|
|
42
|
+
*/
|
|
43
|
+
reduxId?: string;
|
|
38
44
|
/**
|
|
39
45
|
* URL для подгрузки новой коллекции данных
|
|
40
46
|
* @example '/api/v1/search'
|
package/hooks/useDataProvider.js
CHANGED
|
@@ -56,9 +56,10 @@ var isFunction_1 = __importDefault(require("lodash-es/isFunction"));
|
|
|
56
56
|
var isEqual_1 = __importDefault(require("lodash-es/isEqual"));
|
|
57
57
|
var react_1 = require("react");
|
|
58
58
|
var react_use_1 = require("react-use");
|
|
59
|
+
var fields_1 = require("../actions/fields");
|
|
59
60
|
var data_1 = require("../utils/data");
|
|
60
61
|
var index_1 = require("./index");
|
|
61
|
-
var
|
|
62
|
+
var fields_2 = require("../reducers/fields");
|
|
62
63
|
var text_1 = require("../utils/text");
|
|
63
64
|
var defaultProps = {
|
|
64
65
|
autoComplete: {
|
|
@@ -75,15 +76,29 @@ var defaultProps = {
|
|
|
75
76
|
*/
|
|
76
77
|
function useDataProvider(config) {
|
|
77
78
|
var _this = this;
|
|
79
|
+
var _a;
|
|
78
80
|
var components = index_1.useComponents();
|
|
81
|
+
var dispatch = index_1.useDispatch();
|
|
82
|
+
var reduxDataProviderId = (_a = config.dataProvider) === null || _a === void 0 ? void 0 : _a.reduxId;
|
|
79
83
|
// Check enum
|
|
80
|
-
var enumItems = react_redux_1.useSelector(function (state) { return isString_1["default"](config.items) ?
|
|
84
|
+
var enumItems = react_redux_1.useSelector(function (state) { return isString_1["default"](config.items) ? fields_2.getEnumLabels(state, config.items) : null; });
|
|
81
85
|
// Initial items
|
|
82
86
|
var initialItems = data_1.normalizeItems(enumItems || config.items);
|
|
83
87
|
// Items state
|
|
84
|
-
var _a = react_1.useState(initialItems), sourceItems = _a[0], setSourceItems = _a[1];
|
|
85
88
|
var _b = react_1.useState(initialItems), items = _b[0], setItems = _b[1];
|
|
86
89
|
var _c = react_1.useState(false), isLoading = _c[0], setIsLoading = _c[1];
|
|
90
|
+
// Source items state (redux or local)
|
|
91
|
+
var _d = react_1.useState(initialItems), sourceInternalItems = _d[0], setSourceInternalItems = _d[1];
|
|
92
|
+
var sourceReduxItems = react_redux_1.useSelector(function (state) { return fields_2.getDataProviderItems(state, reduxDataProviderId); });
|
|
93
|
+
var sourceItems = reduxDataProviderId ? sourceReduxItems : sourceInternalItems;
|
|
94
|
+
var setSourceItems = react_1.useCallback(function (value) {
|
|
95
|
+
if (reduxDataProviderId) {
|
|
96
|
+
dispatch(fields_1.fieldsDataProviderSetItems(reduxDataProviderId, value));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
setSourceInternalItems(value);
|
|
100
|
+
}
|
|
101
|
+
}, [reduxDataProviderId, dispatch]);
|
|
87
102
|
// Normalize autoComplete
|
|
88
103
|
var autoComplete = react_1.useMemo(function () { return (__assign(__assign({}, defaultProps.autoComplete), (typeof config.autoComplete === 'boolean') ? { enable: config.autoComplete } : config.autoComplete)); }, [config.autoComplete]);
|
|
89
104
|
var dataProvider = react_1.useMemo(function () { return (__assign({ action: '', actionMethod: 'get', params: null, onSearch: null }, config.dataProvider)); }, [config.dataProvider]);
|
|
@@ -143,7 +158,7 @@ function useDataProvider(config) {
|
|
|
143
158
|
delayTimerRef.current = setTimeout(fetchRemote, autoComplete.delay);
|
|
144
159
|
}
|
|
145
160
|
}
|
|
146
|
-
}, [autoComplete, components.api, components.http, config.autoFetch, config.dataProvider, config.initialSelectedIds, config.query, dataProvider, dataProvider.action, dataProvider.onSearch, prevQuery, sourceItems]);
|
|
161
|
+
}, [autoComplete, components.api, components.http, config.autoFetch, config.dataProvider, config.initialSelectedIds, config.query, dataProvider, dataProvider.action, dataProvider.onSearch, prevParams, prevQuery, prevValues, setSourceItems, sourceItems]);
|
|
147
162
|
return {
|
|
148
163
|
sourceItems: sourceItems,
|
|
149
164
|
items: items,
|
package/package.json
CHANGED
package/reducers/fields.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
declare const _default: (state: {
|
|
2
2
|
props: {};
|
|
3
|
+
dataProvider: {};
|
|
3
4
|
meta: any;
|
|
4
5
|
}, action: any) => {
|
|
5
6
|
props: {};
|
|
7
|
+
dataProvider: {};
|
|
6
8
|
meta: any;
|
|
7
9
|
};
|
|
8
10
|
export default _default;
|
|
9
11
|
export declare const isMetaFetched: (state: any) => boolean;
|
|
10
12
|
export declare const getEnumLabels: (state: any, name: any) => any;
|
|
11
13
|
export declare const getModel: (state: any, name: any) => any;
|
|
14
|
+
export declare const getDataProviderItems: (state: any, dataProviderId: any) => any;
|
package/reducers/fields.js
CHANGED
|
@@ -14,16 +14,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
16
|
exports.__esModule = true;
|
|
17
|
-
exports.getModel = exports.getEnumLabels = exports.isMetaFetched = void 0;
|
|
17
|
+
exports.getDataProviderItems = exports.getModel = exports.getEnumLabels = exports.isMetaFetched = void 0;
|
|
18
18
|
var isString_1 = __importDefault(require("lodash-es/isString"));
|
|
19
19
|
var get_1 = __importDefault(require("lodash-es/get"));
|
|
20
20
|
var fields_1 = require("../actions/fields");
|
|
21
21
|
var initialState = {
|
|
22
22
|
props: {},
|
|
23
|
+
dataProvider: {},
|
|
23
24
|
meta: null
|
|
24
25
|
};
|
|
25
26
|
var normalizeName = function (name) { return name.replace(/\\/g, '.').replace(/^\./, ''); };
|
|
26
27
|
exports["default"] = (function (state, action) {
|
|
28
|
+
var _a;
|
|
27
29
|
if (state === void 0) { state = initialState; }
|
|
28
30
|
switch (action.type) {
|
|
29
31
|
case fields_1.FIELDS_SET_META:
|
|
@@ -31,6 +33,8 @@ exports["default"] = (function (state, action) {
|
|
|
31
33
|
action.meta[name].className = name;
|
|
32
34
|
});
|
|
33
35
|
return __assign(__assign({}, state), { meta: __assign(__assign({}, state.meta), action.meta) });
|
|
36
|
+
case fields_1.FIELDS_DATA_PROVIDER_SET_ITEMS:
|
|
37
|
+
return __assign(__assign({}, state), { dataProvider: __assign(__assign({}, state.dataProvider), (_a = {}, _a[action.dataProviderId] = action.items, _a)) });
|
|
34
38
|
default:
|
|
35
39
|
return state;
|
|
36
40
|
}
|
|
@@ -53,3 +57,5 @@ var getModel = function (state, name) {
|
|
|
53
57
|
return name || null;
|
|
54
58
|
};
|
|
55
59
|
exports.getModel = getModel;
|
|
60
|
+
var getDataProviderItems = function (state, dataProviderId) { var _a, _b; return ((_b = (_a = state === null || state === void 0 ? void 0 : state.fields) === null || _a === void 0 ? void 0 : _a.dataProvider) === null || _b === void 0 ? void 0 : _b[dataProviderId]) || null; };
|
|
61
|
+
exports.getDataProviderItems = getDataProviderItems;
|
|
@@ -46,8 +46,9 @@ var createDynamicField = function (componentId, Component, options) {
|
|
|
46
46
|
var DynamicField = function (props) {
|
|
47
47
|
var components = hooks_1.useComponents();
|
|
48
48
|
// Get context, formId
|
|
49
|
-
|
|
50
|
-
var
|
|
49
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
50
|
+
var context = props.formId !== false ? react_1.useContext(Form_1.FormContext) : null;
|
|
51
|
+
var formId = props.formId || props.formId === false ? props.formId : ((context === null || context === void 0 ? void 0 : context.formId) || null);
|
|
51
52
|
var model = props.model || (context === null || context === void 0 ? void 0 : context.model) || null;
|
|
52
53
|
// Result wrapper props
|
|
53
54
|
var wrapperProps = {
|
|
@@ -61,11 +62,32 @@ var createDynamicField = function (componentId, Component, options) {
|
|
|
61
62
|
// Get full name (attribute with prefix)
|
|
62
63
|
var name = [props.prefix, props[attributeKey]].filter(Boolean).join('.');
|
|
63
64
|
// Register field
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
if (formId) {
|
|
66
|
+
components.ui.registerField(formId, name, componentId);
|
|
67
|
+
}
|
|
68
|
+
var errors;
|
|
69
|
+
var value;
|
|
70
|
+
var setValue;
|
|
71
|
+
if (context === null || context === void 0 ? void 0 : context.provider) {
|
|
72
|
+
// Resolve data provider
|
|
73
|
+
var providerResult = context === null || context === void 0 ? void 0 : context.provider.useField(formId, name, options.list);
|
|
74
|
+
errors = providerResult.errors;
|
|
75
|
+
value = providerResult.value;
|
|
76
|
+
setValue = providerResult.setValue;
|
|
77
|
+
}
|
|
78
|
+
else if (has_1["default"](props, 'value') && has_1["default"](props, 'onChange')) {
|
|
79
|
+
// Controlled component via props
|
|
80
|
+
errors = null;
|
|
81
|
+
value = props.value;
|
|
82
|
+
setValue = props.onChange;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Uncontrolled component
|
|
86
|
+
var stateResult = form_1.providers.state.useField(props.value);
|
|
87
|
+
errors = stateResult.errors;
|
|
88
|
+
value = stateResult.value;
|
|
89
|
+
setValue = stateResult.setValue;
|
|
90
|
+
}
|
|
69
91
|
// Set errors
|
|
70
92
|
wrapperProps[errorsKey] = errors;
|
|
71
93
|
// Input object
|
package/ui/form/Form/Form.js
CHANGED
|
@@ -158,7 +158,7 @@ function Form(props) {
|
|
|
158
158
|
var onSubmit = react_1.useCallback(function (e) {
|
|
159
159
|
if (e === void 0) { e = null; }
|
|
160
160
|
return __awaiter(_this, void 0, void 0, function () {
|
|
161
|
-
var cleanedValues, captchaAttribute, googleCaptcha, captchaToken, options, response, _a, data;
|
|
161
|
+
var cleanedValues, submitResult, captchaAttribute, googleCaptcha, captchaToken, options, response, _a, data;
|
|
162
162
|
var _b;
|
|
163
163
|
var _this = this;
|
|
164
164
|
return __generator(this, function (_c) {
|
|
@@ -181,14 +181,19 @@ function Form(props) {
|
|
|
181
181
|
cleanedValues = form_1.cleanEmptyObject(values);
|
|
182
182
|
// Event onBeforeSubmit
|
|
183
183
|
if (props.onBeforeSubmit && props.onBeforeSubmit.call(null, cleanedValues) === false) {
|
|
184
|
+
dispatch(form_2.formSetSubmitting(props.formId, false));
|
|
184
185
|
return [2 /*return*/, null];
|
|
185
186
|
}
|
|
186
187
|
if (props.validators) {
|
|
187
188
|
validate_1["default"](cleanedValues, props.validators);
|
|
188
189
|
}
|
|
189
|
-
if (props.onSubmit)
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
if (!props.onSubmit) return [3 /*break*/, 2];
|
|
191
|
+
return [4 /*yield*/, props.onSubmit.call(null, cleanedValues)];
|
|
192
|
+
case 1:
|
|
193
|
+
submitResult = _c.sent();
|
|
194
|
+
dispatch(form_2.formSetSubmitting(props.formId, false));
|
|
195
|
+
return [2 /*return*/, submitResult];
|
|
196
|
+
case 2:
|
|
192
197
|
captchaAttribute = null;
|
|
193
198
|
Object.entries(components.ui.getRegisteredFields(props.formId) || {}).forEach(function (_a) {
|
|
194
199
|
var attribute = _a[0], fieldType = _a[1];
|
|
@@ -196,20 +201,20 @@ function Form(props) {
|
|
|
196
201
|
captchaAttribute = attribute;
|
|
197
202
|
}
|
|
198
203
|
});
|
|
199
|
-
if (!(captchaAttribute && components.resource.googleCaptchaSiteKey)) return [3 /*break*/,
|
|
204
|
+
if (!(captchaAttribute && components.resource.googleCaptchaSiteKey)) return [3 /*break*/, 5];
|
|
200
205
|
return [4 /*yield*/, components.resource.loadGoogleCaptcha()];
|
|
201
|
-
case
|
|
206
|
+
case 3:
|
|
202
207
|
googleCaptcha = _c.sent();
|
|
203
208
|
return [4 /*yield*/, getCaptchaToken({
|
|
204
209
|
googleCaptcha: googleCaptcha,
|
|
205
210
|
siteKey: components.resource.googleCaptchaSiteKey,
|
|
206
211
|
actionName: props.captchaActionName
|
|
207
212
|
})];
|
|
208
|
-
case
|
|
213
|
+
case 4:
|
|
209
214
|
captchaToken = _c.sent();
|
|
210
215
|
cleanedValues = __assign(__assign({}, cleanedValues), (_b = {}, _b[captchaAttribute] = captchaToken, _b));
|
|
211
|
-
_c.label =
|
|
212
|
-
case
|
|
216
|
+
_c.label = 5;
|
|
217
|
+
case 5:
|
|
213
218
|
options = {
|
|
214
219
|
onTwoFactor: props.onTwoFactor
|
|
215
220
|
? function (providerName) { return __awaiter(_this, void 0, void 0, function () {
|
|
@@ -234,16 +239,16 @@ function Form(props) {
|
|
|
234
239
|
}); }
|
|
235
240
|
: undefined
|
|
236
241
|
};
|
|
237
|
-
if (!(typeof props.action === 'function')) return [3 /*break*/,
|
|
242
|
+
if (!(typeof props.action === 'function')) return [3 /*break*/, 7];
|
|
238
243
|
return [4 /*yield*/, props.action.call(null, components.api, cleanedValues, options)];
|
|
239
|
-
case 4:
|
|
240
|
-
_a = _c.sent();
|
|
241
|
-
return [3 /*break*/, 7];
|
|
242
|
-
case 5: return [4 /*yield*/, components.http.send(props.actionMethod, props.action || window.location.pathname, cleanedValues, options)];
|
|
243
244
|
case 6:
|
|
244
245
|
_a = _c.sent();
|
|
245
|
-
|
|
246
|
-
case 7:
|
|
246
|
+
return [3 /*break*/, 9];
|
|
247
|
+
case 7: return [4 /*yield*/, components.http.send(props.actionMethod, props.action || window.location.pathname, cleanedValues, options)];
|
|
248
|
+
case 8:
|
|
249
|
+
_a = _c.sent();
|
|
250
|
+
_c.label = 9;
|
|
251
|
+
case 9:
|
|
247
252
|
response = _a;
|
|
248
253
|
dispatch(form_2.formSetSubmitting(props.formId, false));
|
|
249
254
|
// Skip on 2fa
|
package/ui/layout/Meta/Meta.js
CHANGED
|
@@ -27,9 +27,7 @@ function Meta(props) {
|
|
|
27
27
|
_c.map(function (attrs, index) { return (react_1["default"].createElement("style", __assign({ key: index }, attrs, { dangerouslySetInnerHTML: {
|
|
28
28
|
__html: attrs.innerHtml
|
|
29
29
|
} }))); }), (_d = props.scripts) === null || _d === void 0 ? void 0 :
|
|
30
|
-
_d.map(function (attrs, index) { return (react_1["default"].createElement("script", __assign({ key: index }, attrs,
|
|
31
|
-
__html: attrs.innerHtml
|
|
32
|
-
} }))); }), (_e = props.noScripts) === null || _e === void 0 ? void 0 :
|
|
30
|
+
_d.map(function (attrs, index) { return (react_1["default"].createElement("script", __assign({ key: index }, attrs), attrs.innerHtml || '')); }), (_e = props.noScripts) === null || _e === void 0 ? void 0 :
|
|
33
31
|
_e.map(function (attrs, index) { return (react_1["default"].createElement("noscript", { key: index, dangerouslySetInnerHTML: {
|
|
34
32
|
__html: attrs.innerHtml
|
|
35
33
|
} })); }),
|