@gravity-ui/dynamic-forms 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/lib/core/components/View/DynamicView.js +8 -2
- package/build/cjs/lib/core/components/View/index.js +3 -0
- package/build/cjs/lib/kit/components/Inputs/DateInput/DateInput.css +3 -0
- package/build/cjs/lib/kit/components/Inputs/DateInput/DateInput.js +50 -0
- package/build/cjs/lib/kit/components/Inputs/DateInput/index.js +4 -0
- package/build/cjs/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.js +7 -2
- package/build/cjs/lib/kit/components/Inputs/index.js +1 -0
- package/build/cjs/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.js +5 -1
- package/build/cjs/lib/kit/components/ViewLayouts/ViewRow/ViewRow.css +3 -0
- package/build/cjs/lib/kit/components/ViewLayouts/ViewRow/ViewRow.js +4 -0
- package/build/cjs/lib/kit/components/Views/DateView/DateView.js +22 -0
- package/build/cjs/lib/kit/components/Views/DateView/index.js +4 -0
- package/build/cjs/lib/kit/components/Views/TableArrayView/TableArrayView.js +9 -3
- package/build/cjs/lib/kit/components/Views/index.js +1 -0
- package/build/cjs/lib/kit/constants/config.js +2 -0
- package/build/esm/lib/core/components/View/DynamicView.d.ts +2 -1
- package/build/esm/lib/core/components/View/DynamicView.js +8 -2
- package/build/esm/lib/core/components/View/index.d.ts +1 -0
- package/build/esm/lib/core/components/View/index.js +1 -0
- package/build/esm/lib/core/components/View/types/context.d.ts +1 -0
- package/build/esm/lib/core/types/specs.d.ts +5 -0
- package/build/esm/lib/kit/components/Inputs/DateInput/DateInput.css +3 -0
- package/build/esm/lib/kit/components/Inputs/DateInput/DateInput.d.ts +9 -0
- package/build/esm/lib/kit/components/Inputs/DateInput/DateInput.js +46 -0
- package/build/esm/lib/kit/components/Inputs/DateInput/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Inputs/DateInput/index.js +1 -0
- package/build/esm/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.js +8 -3
- package/build/esm/lib/kit/components/Inputs/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Inputs/index.js +1 -0
- package/build/esm/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.js +5 -1
- package/build/esm/lib/kit/components/ViewLayouts/ViewRow/ViewRow.css +3 -0
- package/build/esm/lib/kit/components/ViewLayouts/ViewRow/ViewRow.js +4 -0
- package/build/esm/lib/kit/components/Views/DateView/DateView.d.ts +3 -0
- package/build/esm/lib/kit/components/Views/DateView/DateView.js +18 -0
- package/build/esm/lib/kit/components/Views/DateView/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Views/DateView/index.js +1 -0
- package/build/esm/lib/kit/components/Views/TableArrayView/TableArrayView.js +11 -5
- package/build/esm/lib/kit/components/Views/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Views/index.js +1 -0
- package/build/esm/lib/kit/constants/config.js +3 -1
- package/package.json +3 -1
|
@@ -8,9 +8,15 @@ const helpers_1 = require("../../helpers");
|
|
|
8
8
|
const ViewController_1 = require("./ViewController");
|
|
9
9
|
const helpers_2 = require("./helpers");
|
|
10
10
|
const hooks_1 = require("./hooks");
|
|
11
|
-
const DynamicView = ({ value, spec, config, Link, Monaco }) => {
|
|
11
|
+
const DynamicView = ({ value, spec, config, Link, Monaco, showLayoutDescription, }) => {
|
|
12
12
|
const DynamicFormsCtx = (0, hooks_1.useCreateContext)();
|
|
13
|
-
const context = react_1.default.useMemo(() => ({
|
|
13
|
+
const context = react_1.default.useMemo(() => ({
|
|
14
|
+
config,
|
|
15
|
+
value,
|
|
16
|
+
showLayoutDescription,
|
|
17
|
+
Link,
|
|
18
|
+
Monaco: (0, react_is_1.isValidElementType)(Monaco) ? Monaco : undefined,
|
|
19
|
+
}), [config, value, Link, Monaco, showLayoutDescription]);
|
|
14
20
|
if ((0, helpers_1.isCorrectSpec)(spec) && (0, helpers_2.isCorrectViewConfig)(config)) {
|
|
15
21
|
return (react_1.default.createElement(DynamicFormsCtx.Provider, { value: context },
|
|
16
22
|
react_1.default.createElement(ViewController_1.ViewController, { spec: spec, name: "" })));
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useDynamicFormsCtx = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
tslib_1.__exportStar(require("./DynamicView"), exports);
|
|
5
6
|
tslib_1.__exportStar(require("./ViewController"), exports);
|
|
6
7
|
tslib_1.__exportStar(require("./helpers"), exports);
|
|
7
8
|
tslib_1.__exportStar(require("./types"), exports);
|
|
9
|
+
var hooks_1 = require("./hooks");
|
|
10
|
+
Object.defineProperty(exports, "useDynamicFormsCtx", { enumerable: true, get: function () { return hooks_1.useDynamicFormsCtx; } });
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DateInput = exports.DEFAULT_DATE_FORMAT = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importStar(require("react"));
|
|
6
|
+
const date_components_1 = require("@gravity-ui/date-components");
|
|
7
|
+
const date_utils_1 = require("@gravity-ui/date-utils");
|
|
8
|
+
const utils_1 = require("../../../utils");
|
|
9
|
+
exports.DEFAULT_DATE_FORMAT = 'DD-MM-YYYY';
|
|
10
|
+
const b = (0, utils_1.block)('date-input');
|
|
11
|
+
const DateInput = ({ name, input, spec, inputProps, }) => {
|
|
12
|
+
const { value, onChange, onBlur, onFocus } = input;
|
|
13
|
+
const dateInput = spec.viewSpec.dateInput;
|
|
14
|
+
const outputFormat = dateInput === null || dateInput === void 0 ? void 0 : dateInput.outputFormat;
|
|
15
|
+
const onUpdate = (0, react_1.useCallback)((date) => {
|
|
16
|
+
if (!date) {
|
|
17
|
+
onChange(undefined);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
switch (outputFormat) {
|
|
21
|
+
case 'date_time':
|
|
22
|
+
onChange(date);
|
|
23
|
+
break;
|
|
24
|
+
case 'date':
|
|
25
|
+
onChange(date.toDate());
|
|
26
|
+
break;
|
|
27
|
+
case 'timestamp':
|
|
28
|
+
onChange({
|
|
29
|
+
seconds: Math.floor((date === null || date === void 0 ? void 0 : date.toDate().getTime()) / 1000),
|
|
30
|
+
nanos: 0,
|
|
31
|
+
});
|
|
32
|
+
break;
|
|
33
|
+
case 'string':
|
|
34
|
+
case undefined:
|
|
35
|
+
case '':
|
|
36
|
+
onChange(date.toISOString());
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
onChange(date.format(outputFormat));
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}, [outputFormat]);
|
|
44
|
+
const props = Object.assign(Object.assign({ hasClear: true, format: (dateInput === null || dateInput === void 0 ? void 0 : dateInput.printFormat) || exports.DEFAULT_DATE_FORMAT }, inputProps), { onBlur: onBlur, onFocus: onFocus, value: value
|
|
45
|
+
? (0, date_utils_1.dateTimeParse)(value.seconds ? value.seconds * 1000 : value) || null
|
|
46
|
+
: null, onUpdate, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder });
|
|
47
|
+
return react_1.default.createElement(date_components_1.DatePicker, Object.assign({ className: b(), "data-qa": name }, props));
|
|
48
|
+
};
|
|
49
|
+
exports.DateInput = DateInput;
|
|
50
|
+
exports.default = exports.DateInput;
|
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const icons_1 = require("@gravity-ui/icons");
|
|
7
7
|
const uikit_1 = require("@gravity-ui/uikit");
|
|
8
|
+
const components_1 = require("@gravity-ui/components");
|
|
8
9
|
const noop_1 = tslib_1.__importDefault(require("lodash/noop"));
|
|
9
10
|
const set_1 = tslib_1.__importDefault(require("lodash/set"));
|
|
10
11
|
const core_1 = require("../../../../core");
|
|
@@ -45,9 +46,13 @@ const TableArrayInput = ({ spec, name, arrayInput, input }) => {
|
|
|
45
46
|
template: ({ key }) => (react_1.default.createElement(uikit_1.Button, { view: "flat-secondary", onClick: () => onItemRemove(key), key: `remove-${key}`, qa: `${name}-item-remove-${key}` },
|
|
46
47
|
react_1.default.createElement(uikit_1.Icon, { data: icons_1.TrashBin, size: 16 }))),
|
|
47
48
|
};
|
|
48
|
-
const columns = table.map(({ property, label }) => ({
|
|
49
|
+
const columns = table.map(({ property, label, description }) => ({
|
|
49
50
|
id: property,
|
|
50
|
-
name:
|
|
51
|
+
name: !description
|
|
52
|
+
? label
|
|
53
|
+
: () => (react_1.default.createElement(uikit_1.Flex, { gap: 0.5, alignItems: "center" },
|
|
54
|
+
label,
|
|
55
|
+
react_1.default.createElement(components_1.HelpPopover, { htmlContent: description, placement: ['bottom', 'top'] }))),
|
|
51
56
|
template: ({ key, }, idx) => {
|
|
52
57
|
var _a, _b, _c;
|
|
53
58
|
const entitySpec = (_a = items === null || items === void 0 ? void 0 : items.properties) === null || _a === void 0 ? void 0 : _a[property];
|
|
@@ -5,6 +5,7 @@ tslib_1.__exportStar(require("./ArrayBase"), exports);
|
|
|
5
5
|
tslib_1.__exportStar(require("./CardOneOf"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./Checkbox"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./FileInput"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./DateInput"), exports);
|
|
8
9
|
tslib_1.__exportStar(require("./MonacoInput"), exports);
|
|
9
10
|
tslib_1.__exportStar(require("./MultiOneOf"), exports);
|
|
10
11
|
tslib_1.__exportStar(require("./MultiSelect"), exports);
|
|
@@ -4,13 +4,17 @@ exports.ViewAccordeon = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const isBoolean_1 = tslib_1.__importDefault(require("lodash/isBoolean"));
|
|
7
|
+
const core_1 = require("../../../../core");
|
|
7
8
|
const utils_1 = require("../../../utils");
|
|
8
9
|
const SimpleVerticalAccordeon_1 = require("../../SimpleVerticalAccordeon");
|
|
9
10
|
const ViewAccordeon = ({ name, value, spec, children, }) => {
|
|
11
|
+
const { showLayoutDescription } = (0, core_1.useDynamicFormsCtx)();
|
|
10
12
|
const [open, setOpen] = react_1.default.useState((0, isBoolean_1.default)(spec.viewSpec.layoutOpen) ? spec.viewSpec.layoutOpen : true);
|
|
11
13
|
if (!(0, utils_1.isNotEmptyValue)(value, spec)) {
|
|
12
14
|
return null;
|
|
13
15
|
}
|
|
14
|
-
return (react_1.default.createElement(SimpleVerticalAccordeon_1.SimpleVerticalAccordeon, { name: name, title: spec.viewSpec.layoutTitle || '',
|
|
16
|
+
return (react_1.default.createElement(SimpleVerticalAccordeon_1.SimpleVerticalAccordeon, { name: name, title: spec.viewSpec.layoutTitle || '', note: showLayoutDescription && spec.viewSpec.layoutDescription
|
|
17
|
+
? spec.viewSpec.layoutDescription
|
|
18
|
+
: undefined, open: open, onOpenChange: setOpen, hideInsteadOfDestroy: true, withBranchView: true, viewLayout: true }, children));
|
|
15
19
|
};
|
|
16
20
|
exports.ViewAccordeon = ViewAccordeon;
|
|
@@ -4,16 +4,20 @@ exports.ViewRow = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
|
+
const components_1 = require("@gravity-ui/components");
|
|
8
|
+
const core_1 = require("../../../../core");
|
|
7
9
|
const kit_1 = require("../../../../kit");
|
|
8
10
|
const utils_1 = require("../../../utils");
|
|
9
11
|
const b = (0, utils_1.block)('view-row');
|
|
10
12
|
const ViewRow = ({ value, spec, children, }) => {
|
|
13
|
+
const { showLayoutDescription } = (0, core_1.useDynamicFormsCtx)();
|
|
11
14
|
if (!(0, utils_1.isNotEmptyValue)(value, spec)) {
|
|
12
15
|
return null;
|
|
13
16
|
}
|
|
14
17
|
return (react_1.default.createElement("div", { className: b() },
|
|
15
18
|
react_1.default.createElement("div", { className: b('left') },
|
|
16
19
|
react_1.default.createElement(uikit_1.Text, { whiteSpace: "nowrap", color: "secondary", ellipsis: true }, spec.viewSpec.layoutTitle),
|
|
20
|
+
showLayoutDescription && spec.viewSpec.layoutDescription ? (react_1.default.createElement(components_1.HelpPopover, { className: b('note'), htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })) : null,
|
|
17
21
|
react_1.default.createElement("div", { className: b('dots') })),
|
|
18
22
|
react_1.default.createElement("div", { className: b('right') }, children),
|
|
19
23
|
react_1.default.createElement(kit_1.CopyButton, { spec: spec, value: value })));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DateView = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const components_1 = require("../../../components");
|
|
7
|
+
const date_utils_1 = require("@gravity-ui/date-utils");
|
|
8
|
+
const isObject_1 = tslib_1.__importDefault(require("lodash/isObject"));
|
|
9
|
+
const DateView = (_a) => {
|
|
10
|
+
var _b, _c, _d;
|
|
11
|
+
var { value, spec } = _a, restProps = tslib_1.__rest(_a, ["value", "spec"]);
|
|
12
|
+
let formatedValue = value && (0, isObject_1.default)(value) && value.seconds
|
|
13
|
+
? (value === null || value === void 0 ? void 0 : value.seconds) * 1000
|
|
14
|
+
: value;
|
|
15
|
+
const localSpec = spec.viewSpec;
|
|
16
|
+
const format = ((_b = localSpec.inputProps) === null || _b === void 0 ? void 0 : _b.format) || ((_c = localSpec.dateInput) === null || _c === void 0 ? void 0 : _c.printFormat) || components_1.DEFAULT_DATE_FORMAT;
|
|
17
|
+
if (formatedValue && format) {
|
|
18
|
+
formatedValue = ((_d = (0, date_utils_1.dateTimeParse)(formatedValue)) === null || _d === void 0 ? void 0 : _d.format(format)) || formatedValue;
|
|
19
|
+
}
|
|
20
|
+
return react_1.default.createElement(components_1.BaseView, Object.assign({ spec: spec, value: String(formatedValue) }, restProps));
|
|
21
|
+
};
|
|
22
|
+
exports.DateView = DateView;
|
|
@@ -6,8 +6,10 @@ const react_1 = tslib_1.__importDefault(require("react"));
|
|
|
6
6
|
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
7
|
const core_1 = require("../../../../core");
|
|
8
8
|
const utils_1 = require("../../../utils");
|
|
9
|
+
const components_1 = require("@gravity-ui/components");
|
|
9
10
|
const b = (0, utils_1.block)('table-array-view');
|
|
10
11
|
const TableArrayView = ({ value = [], spec, name }) => {
|
|
12
|
+
const { showLayoutDescription } = (0, core_1.useDynamicFormsCtx)();
|
|
11
13
|
const columns = react_1.default.useMemo(() => {
|
|
12
14
|
const { items, viewSpec: { table }, } = spec;
|
|
13
15
|
if (!(table === null || table === void 0 ? void 0 : table.length) || !(0, core_1.isObjectSpec)(items)) {
|
|
@@ -19,9 +21,13 @@ const TableArrayView = ({ value = [], spec, name }) => {
|
|
|
19
21
|
sticky: 'left',
|
|
20
22
|
template: (__, idx) => (react_1.default.createElement("div", { className: b('idx'), key: `idx-${idx}` }, idx + 1)),
|
|
21
23
|
};
|
|
22
|
-
const columns = table.map(({ property, label }) => ({
|
|
24
|
+
const columns = table.map(({ property, label, description }) => ({
|
|
23
25
|
id: property,
|
|
24
|
-
name:
|
|
26
|
+
name: description && showLayoutDescription
|
|
27
|
+
? () => (react_1.default.createElement(uikit_1.Flex, { gap: 0.5, alignItems: "center" },
|
|
28
|
+
label,
|
|
29
|
+
react_1.default.createElement(components_1.HelpPopover, { htmlContent: description, placement: ['bottom', 'top'] })))
|
|
30
|
+
: label,
|
|
25
31
|
template: (_, idx) => {
|
|
26
32
|
var _a;
|
|
27
33
|
const entitySpec = (_a = items === null || items === void 0 ? void 0 : items.properties) === null || _a === void 0 ? void 0 : _a[property];
|
|
@@ -37,7 +43,7 @@ const TableArrayView = ({ value = [], spec, name }) => {
|
|
|
37
43
|
},
|
|
38
44
|
}));
|
|
39
45
|
return [idxColumn, ...columns];
|
|
40
|
-
}, [name, spec]);
|
|
46
|
+
}, [name, spec, showLayoutDescription]);
|
|
41
47
|
if (!columns) {
|
|
42
48
|
return null;
|
|
43
49
|
}
|
|
@@ -15,3 +15,4 @@ tslib_1.__exportStar(require("./OneOfView"), exports);
|
|
|
15
15
|
tslib_1.__exportStar(require("./TableArrayView"), exports);
|
|
16
16
|
tslib_1.__exportStar(require("./TextAreaView"), exports);
|
|
17
17
|
tslib_1.__exportStar(require("./TextLinkView"), exports);
|
|
18
|
+
tslib_1.__exportStar(require("./DateView"), exports);
|
|
@@ -94,6 +94,7 @@ exports.dynamicConfig = {
|
|
|
94
94
|
select: { Component: components_1.Select },
|
|
95
95
|
base: { Component: components_1.Text },
|
|
96
96
|
file_input: { Component: components_1.FileInput },
|
|
97
|
+
date_input: { Component: components_1.DateInput },
|
|
97
98
|
number_with_scale: { Component: components_1.NumberWithScale },
|
|
98
99
|
monaco_input: { Component: components_1.MonacoInput },
|
|
99
100
|
text_content: { Component: components_1.TextContent, independent: true },
|
|
@@ -193,6 +194,7 @@ exports.dynamicViewConfig = {
|
|
|
193
194
|
textarea: { Component: components_1.TextAreaView },
|
|
194
195
|
select: { Component: components_1.BaseView },
|
|
195
196
|
base: { Component: components_1.BaseView },
|
|
197
|
+
date_input: { Component: components_1.DateView },
|
|
196
198
|
file_input: { Component: components_1.FileInputView },
|
|
197
199
|
number_with_scale: { Component: components_1.NumberWithScaleView },
|
|
198
200
|
monaco_input: { Component: components_1.MonacoView },
|
|
@@ -11,5 +11,6 @@ export interface DynamicViewProps {
|
|
|
11
11
|
link: Spec['viewSpec']['link'];
|
|
12
12
|
}>;
|
|
13
13
|
Monaco?: React.ComponentType<MonacoEditorProps>;
|
|
14
|
+
showLayoutDescription?: boolean;
|
|
14
15
|
}
|
|
15
|
-
export declare const DynamicView: ({ value, spec, config, Link, Monaco }: DynamicViewProps) => JSX.Element | null;
|
|
16
|
+
export declare const DynamicView: ({ value, spec, config, Link, Monaco, showLayoutDescription, }: DynamicViewProps) => JSX.Element | null;
|
|
@@ -4,9 +4,15 @@ import { isCorrectSpec } from '../../helpers';
|
|
|
4
4
|
import { ViewController } from './ViewController';
|
|
5
5
|
import { isCorrectViewConfig } from './helpers';
|
|
6
6
|
import { useCreateContext } from './hooks';
|
|
7
|
-
export const DynamicView = ({ value, spec, config, Link, Monaco }) => {
|
|
7
|
+
export const DynamicView = ({ value, spec, config, Link, Monaco, showLayoutDescription, }) => {
|
|
8
8
|
const DynamicFormsCtx = useCreateContext();
|
|
9
|
-
const context = React.useMemo(() => ({
|
|
9
|
+
const context = React.useMemo(() => ({
|
|
10
|
+
config,
|
|
11
|
+
value,
|
|
12
|
+
showLayoutDescription,
|
|
13
|
+
Link,
|
|
14
|
+
Monaco: isValidElementType(Monaco) ? Monaco : undefined,
|
|
15
|
+
}), [config, value, Link, Monaco, showLayoutDescription]);
|
|
10
16
|
if (isCorrectSpec(spec) && isCorrectViewConfig(config)) {
|
|
11
17
|
return (React.createElement(DynamicFormsCtx.Provider, { value: context },
|
|
12
18
|
React.createElement(ViewController, { spec: spec, name: "" })));
|
|
@@ -24,6 +24,7 @@ export interface ArraySpec<LinkType = any, InputComponentProps extends Record<st
|
|
|
24
24
|
table?: {
|
|
25
25
|
label: string;
|
|
26
26
|
property: string;
|
|
27
|
+
description?: string;
|
|
27
28
|
}[];
|
|
28
29
|
link?: LinkType;
|
|
29
30
|
placeholder?: string;
|
|
@@ -150,6 +151,10 @@ export interface StringSpec<LinkType = any, InputComponentProps extends Record<s
|
|
|
150
151
|
readAsMethod?: ReadAsMethod;
|
|
151
152
|
ignoreText?: boolean;
|
|
152
153
|
};
|
|
154
|
+
dateInput?: {
|
|
155
|
+
outputFormat?: string;
|
|
156
|
+
printFormat?: string;
|
|
157
|
+
};
|
|
153
158
|
copy?: boolean;
|
|
154
159
|
selectParams?: {
|
|
155
160
|
filterPlaceholder?: string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DatePickerProps } from '@gravity-ui/date-components';
|
|
3
|
+
import { StringInputProps } from '../../../../core';
|
|
4
|
+
import './DateInput.css';
|
|
5
|
+
export declare const DEFAULT_DATE_FORMAT = "DD-MM-YYYY";
|
|
6
|
+
export interface DateProps extends Omit<DatePickerProps, 'value' | 'disabled' | 'placeholder' | 'qa'> {
|
|
7
|
+
}
|
|
8
|
+
export declare const DateInput: React.FC<StringInputProps<DateProps>>;
|
|
9
|
+
export default DateInput;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { DatePicker } from '@gravity-ui/date-components';
|
|
3
|
+
import { dateTimeParse } from '@gravity-ui/date-utils';
|
|
4
|
+
import { block } from '../../../utils';
|
|
5
|
+
import './DateInput.css';
|
|
6
|
+
export const DEFAULT_DATE_FORMAT = 'DD-MM-YYYY';
|
|
7
|
+
const b = block('date-input');
|
|
8
|
+
export const DateInput = ({ name, input, spec, inputProps, }) => {
|
|
9
|
+
const { value, onChange, onBlur, onFocus } = input;
|
|
10
|
+
const dateInput = spec.viewSpec.dateInput;
|
|
11
|
+
const outputFormat = dateInput === null || dateInput === void 0 ? void 0 : dateInput.outputFormat;
|
|
12
|
+
const onUpdate = useCallback((date) => {
|
|
13
|
+
if (!date) {
|
|
14
|
+
onChange(undefined);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
switch (outputFormat) {
|
|
18
|
+
case 'date_time':
|
|
19
|
+
onChange(date);
|
|
20
|
+
break;
|
|
21
|
+
case 'date':
|
|
22
|
+
onChange(date.toDate());
|
|
23
|
+
break;
|
|
24
|
+
case 'timestamp':
|
|
25
|
+
onChange({
|
|
26
|
+
seconds: Math.floor((date === null || date === void 0 ? void 0 : date.toDate().getTime()) / 1000),
|
|
27
|
+
nanos: 0,
|
|
28
|
+
});
|
|
29
|
+
break;
|
|
30
|
+
case 'string':
|
|
31
|
+
case undefined:
|
|
32
|
+
case '':
|
|
33
|
+
onChange(date.toISOString());
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
onChange(date.format(outputFormat));
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, [outputFormat]);
|
|
41
|
+
const props = Object.assign(Object.assign({ hasClear: true, format: (dateInput === null || dateInput === void 0 ? void 0 : dateInput.printFormat) || DEFAULT_DATE_FORMAT }, inputProps), { onBlur: onBlur, onFocus: onFocus, value: value
|
|
42
|
+
? dateTimeParse(value.seconds ? value.seconds * 1000 : value) || null
|
|
43
|
+
: null, onUpdate, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder });
|
|
44
|
+
return React.createElement(DatePicker, Object.assign({ className: b(), "data-qa": name }, props));
|
|
45
|
+
};
|
|
46
|
+
export default DateInput;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DateInput';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DateInput';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Plus, TrashBin } from '@gravity-ui/icons';
|
|
3
|
-
import { Button, Icon, Table } from '@gravity-ui/uikit';
|
|
3
|
+
import { Button, Flex, Icon, Table } from '@gravity-ui/uikit';
|
|
4
|
+
import { HelpPopover } from '@gravity-ui/components';
|
|
4
5
|
import noop from 'lodash/noop';
|
|
5
6
|
import set from 'lodash/set';
|
|
6
7
|
import { Controller, OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG, isArraySpec, isBooleanSpec, isObjectSpec, transformArrIn, } from '../../../../core';
|
|
@@ -42,9 +43,13 @@ export const TableArrayInput = ({ spec, name, arrayInput, input }) => {
|
|
|
42
43
|
template: ({ key }) => (React.createElement(Button, { view: "flat-secondary", onClick: () => onItemRemove(key), key: `remove-${key}`, qa: `${name}-item-remove-${key}` },
|
|
43
44
|
React.createElement(Icon, { data: TrashBin, size: 16 }))),
|
|
44
45
|
};
|
|
45
|
-
const columns = table.map(({ property, label }) => ({
|
|
46
|
+
const columns = table.map(({ property, label, description }) => ({
|
|
46
47
|
id: property,
|
|
47
|
-
name:
|
|
48
|
+
name: !description
|
|
49
|
+
? label
|
|
50
|
+
: () => (React.createElement(Flex, { gap: 0.5, alignItems: "center" },
|
|
51
|
+
label,
|
|
52
|
+
React.createElement(HelpPopover, { htmlContent: description, placement: ['bottom', 'top'] }))),
|
|
48
53
|
template: ({ key, }, idx) => {
|
|
49
54
|
var _a, _b, _c;
|
|
50
55
|
const entitySpec = (_a = items === null || items === void 0 ? void 0 : items.properties) === null || _a === void 0 ? void 0 : _a[property];
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import isBoolean from 'lodash/isBoolean';
|
|
3
|
+
import { useDynamicFormsCtx } from '../../../../core';
|
|
3
4
|
import { isNotEmptyValue } from '../../../utils';
|
|
4
5
|
import { SimpleVerticalAccordeon } from '../../SimpleVerticalAccordeon';
|
|
5
6
|
export const ViewAccordeon = ({ name, value, spec, children, }) => {
|
|
7
|
+
const { showLayoutDescription } = useDynamicFormsCtx();
|
|
6
8
|
const [open, setOpen] = React.useState(isBoolean(spec.viewSpec.layoutOpen) ? spec.viewSpec.layoutOpen : true);
|
|
7
9
|
if (!isNotEmptyValue(value, spec)) {
|
|
8
10
|
return null;
|
|
9
11
|
}
|
|
10
|
-
return (React.createElement(SimpleVerticalAccordeon, { name: name, title: spec.viewSpec.layoutTitle || '',
|
|
12
|
+
return (React.createElement(SimpleVerticalAccordeon, { name: name, title: spec.viewSpec.layoutTitle || '', note: showLayoutDescription && spec.viewSpec.layoutDescription
|
|
13
|
+
? spec.viewSpec.layoutDescription
|
|
14
|
+
: undefined, open: open, onOpenChange: setOpen, hideInsteadOfDestroy: true, withBranchView: true, viewLayout: true }, children));
|
|
11
15
|
};
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Text } from '@gravity-ui/uikit';
|
|
3
|
+
import { HelpPopover } from '@gravity-ui/components';
|
|
4
|
+
import { useDynamicFormsCtx } from '../../../../core';
|
|
3
5
|
import { CopyButton } from '../../../../kit';
|
|
4
6
|
import { block, isNotEmptyValue } from '../../../utils';
|
|
5
7
|
import './ViewRow.css';
|
|
6
8
|
const b = block('view-row');
|
|
7
9
|
export const ViewRow = ({ value, spec, children, }) => {
|
|
10
|
+
const { showLayoutDescription } = useDynamicFormsCtx();
|
|
8
11
|
if (!isNotEmptyValue(value, spec)) {
|
|
9
12
|
return null;
|
|
10
13
|
}
|
|
11
14
|
return (React.createElement("div", { className: b() },
|
|
12
15
|
React.createElement("div", { className: b('left') },
|
|
13
16
|
React.createElement(Text, { whiteSpace: "nowrap", color: "secondary", ellipsis: true }, spec.viewSpec.layoutTitle),
|
|
17
|
+
showLayoutDescription && spec.viewSpec.layoutDescription ? (React.createElement(HelpPopover, { className: b('note'), htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })) : null,
|
|
14
18
|
React.createElement("div", { className: b('dots') })),
|
|
15
19
|
React.createElement("div", { className: b('right') }, children),
|
|
16
20
|
React.createElement(CopyButton, { spec: spec, value: value })));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { __rest } from "tslib";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { BaseView, DEFAULT_DATE_FORMAT } from '../../../components';
|
|
4
|
+
import { dateTimeParse } from '@gravity-ui/date-utils';
|
|
5
|
+
import isObject from 'lodash/isObject';
|
|
6
|
+
export const DateView = (_a) => {
|
|
7
|
+
var _b, _c, _d;
|
|
8
|
+
var { value, spec } = _a, restProps = __rest(_a, ["value", "spec"]);
|
|
9
|
+
let formatedValue = value && isObject(value) && value.seconds
|
|
10
|
+
? (value === null || value === void 0 ? void 0 : value.seconds) * 1000
|
|
11
|
+
: value;
|
|
12
|
+
const localSpec = spec.viewSpec;
|
|
13
|
+
const format = ((_b = localSpec.inputProps) === null || _b === void 0 ? void 0 : _b.format) || ((_c = localSpec.dateInput) === null || _c === void 0 ? void 0 : _c.printFormat) || DEFAULT_DATE_FORMAT;
|
|
14
|
+
if (formatedValue && format) {
|
|
15
|
+
formatedValue = ((_d = dateTimeParse(formatedValue)) === null || _d === void 0 ? void 0 : _d.format(format)) || formatedValue;
|
|
16
|
+
}
|
|
17
|
+
return React.createElement(BaseView, Object.assign({ spec: spec, value: String(formatedValue) }, restProps));
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DateView';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DateView';
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Table } from '@gravity-ui/uikit';
|
|
3
|
-
import { ViewController, isArraySpec, isBooleanSpec, isObjectSpec, } from '../../../../core';
|
|
2
|
+
import { Flex, Table } from '@gravity-ui/uikit';
|
|
3
|
+
import { ViewController, isArraySpec, isBooleanSpec, isObjectSpec, useDynamicFormsCtx, } from '../../../../core';
|
|
4
4
|
import { block } from '../../../utils';
|
|
5
5
|
import './TableArrayView.css';
|
|
6
|
+
import { HelpPopover } from '@gravity-ui/components';
|
|
6
7
|
const b = block('table-array-view');
|
|
7
8
|
export const TableArrayView = ({ value = [], spec, name }) => {
|
|
9
|
+
const { showLayoutDescription } = useDynamicFormsCtx();
|
|
8
10
|
const columns = React.useMemo(() => {
|
|
9
11
|
const { items, viewSpec: { table }, } = spec;
|
|
10
12
|
if (!(table === null || table === void 0 ? void 0 : table.length) || !isObjectSpec(items)) {
|
|
@@ -16,9 +18,13 @@ export const TableArrayView = ({ value = [], spec, name }) => {
|
|
|
16
18
|
sticky: 'left',
|
|
17
19
|
template: (__, idx) => (React.createElement("div", { className: b('idx'), key: `idx-${idx}` }, idx + 1)),
|
|
18
20
|
};
|
|
19
|
-
const columns = table.map(({ property, label }) => ({
|
|
21
|
+
const columns = table.map(({ property, label, description }) => ({
|
|
20
22
|
id: property,
|
|
21
|
-
name:
|
|
23
|
+
name: description && showLayoutDescription
|
|
24
|
+
? () => (React.createElement(Flex, { gap: 0.5, alignItems: "center" },
|
|
25
|
+
label,
|
|
26
|
+
React.createElement(HelpPopover, { htmlContent: description, placement: ['bottom', 'top'] })))
|
|
27
|
+
: label,
|
|
22
28
|
template: (_, idx) => {
|
|
23
29
|
var _a;
|
|
24
30
|
const entitySpec = (_a = items === null || items === void 0 ? void 0 : items.properties) === null || _a === void 0 ? void 0 : _a[property];
|
|
@@ -34,7 +40,7 @@ export const TableArrayView = ({ value = [], spec, name }) => {
|
|
|
34
40
|
},
|
|
35
41
|
}));
|
|
36
42
|
return [idxColumn, ...columns];
|
|
37
|
-
}, [name, spec]);
|
|
43
|
+
}, [name, spec, showLayoutDescription]);
|
|
38
44
|
if (!columns) {
|
|
39
45
|
return null;
|
|
40
46
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Accordeon, AccordeonCardForm, ArrayBase, ArrayBaseView, BaseView, CardAccordeon, CardOneOf, CardOneOfView, CardSection, Checkbox, FileInput, FileInputView, Group, Group2, MonacoInput, MonacoView, MultiOneOf, MultiOneOfFlat, MultiOneOfFlatView, MultiOneOfView, MultiSelect, MultiSelectView, NumberWithScale, NumberWithScaleView, ObjectBase, ObjectBaseView, ObjectInline, ObjectInlineView, ObjectValueInput, ObjectValueInputView, OneOf, OneOfFlat, OneOfFlatView, OneOfView, Row, RowVerbose, Secret, Section, Section2, Select, Switch, TableArrayInput, TableArrayView, TableCell, Text, TextArea, TextAreaView, TextContent, TextLink, TextLinkView, Transparent, ViewAccordeon, ViewAccordeonCard, ViewCardAccordeon, ViewCardSection, ViewGroup, ViewGroup2, ViewRow, ViewSection, ViewSection2, ViewTableCell, ViewTransparent, } from '../components';
|
|
1
|
+
import { Accordeon, AccordeonCardForm, ArrayBase, ArrayBaseView, BaseView, CardAccordeon, CardOneOf, CardOneOfView, CardSection, Checkbox, DateInput, DateView, FileInput, FileInputView, Group, Group2, MonacoInput, MonacoView, MultiOneOf, MultiOneOfFlat, MultiOneOfFlatView, MultiOneOfView, MultiSelect, MultiSelectView, NumberWithScale, NumberWithScaleView, ObjectBase, ObjectBaseView, ObjectInline, ObjectInlineView, ObjectValueInput, ObjectValueInputView, OneOf, OneOfFlat, OneOfFlatView, OneOfView, Row, RowVerbose, Secret, Section, Section2, Select, Switch, TableArrayInput, TableArrayView, TableCell, Text, TextArea, TextAreaView, TextContent, TextLink, TextLinkView, Transparent, ViewAccordeon, ViewAccordeonCard, ViewCardAccordeon, ViewCardSection, ViewGroup, ViewGroup2, ViewRow, ViewSection, ViewSection2, ViewTableCell, ViewTransparent, } from '../components';
|
|
2
2
|
import { getArrayValidator, getBooleanValidator, getNumberValidator, getObjectValidator, getStringValidator, } from '../validators';
|
|
3
3
|
export const dynamicConfig = {
|
|
4
4
|
array: {
|
|
@@ -91,6 +91,7 @@ export const dynamicConfig = {
|
|
|
91
91
|
select: { Component: Select },
|
|
92
92
|
base: { Component: Text },
|
|
93
93
|
file_input: { Component: FileInput },
|
|
94
|
+
date_input: { Component: DateInput },
|
|
94
95
|
number_with_scale: { Component: NumberWithScale },
|
|
95
96
|
monaco_input: { Component: MonacoInput },
|
|
96
97
|
text_content: { Component: TextContent, independent: true },
|
|
@@ -190,6 +191,7 @@ export const dynamicViewConfig = {
|
|
|
190
191
|
textarea: { Component: TextAreaView },
|
|
191
192
|
select: { Component: BaseView },
|
|
192
193
|
base: { Component: BaseView },
|
|
194
|
+
date_input: { Component: DateView },
|
|
193
195
|
file_input: { Component: FileInputView },
|
|
194
196
|
number_with_scale: { Component: NumberWithScaleView },
|
|
195
197
|
monaco_input: { Component: MonacoView },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/dynamic-forms",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "build/cjs/index.js",
|
|
@@ -45,6 +45,8 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@bem-react/classname": "^1.6.0",
|
|
47
47
|
"@gravity-ui/components": "^3.0.0",
|
|
48
|
+
"@gravity-ui/date-components": "^2.5.0",
|
|
49
|
+
"@gravity-ui/date-utils": "^2.5.3",
|
|
48
50
|
"@gravity-ui/i18n": "^1.2.0",
|
|
49
51
|
"@gravity-ui/icons": "^2.8.1",
|
|
50
52
|
"lodash": "^4.17.20"
|