@gravity-ui/dynamic-forms 2.0.0 → 2.1.1
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/Form/hooks/useField.js +2 -2
- package/build/cjs/lib/kit/components/Card/Card.css +4 -0
- package/build/cjs/lib/kit/components/Card/Card.js +8 -3
- package/build/cjs/lib/kit/components/Inputs/FileInput/FileInput.css +1 -6
- package/build/cjs/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.css +14 -0
- package/build/cjs/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.js +73 -0
- package/build/cjs/lib/kit/components/Inputs/MultiOneOf/index.js +4 -0
- package/build/cjs/lib/kit/components/Inputs/index.js +3 -2
- package/build/cjs/lib/kit/components/Layouts/Section/Section.css +4 -0
- package/build/cjs/lib/kit/components/Layouts/Section/Section.js +8 -2
- package/build/cjs/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.css +1 -0
- package/build/cjs/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.js +10 -3
- package/build/cjs/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.css +21 -0
- package/build/cjs/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.js +43 -0
- package/build/cjs/lib/kit/components/Views/MultiOneOfView/index.js +4 -0
- package/build/cjs/lib/kit/components/Views/index.js +1 -0
- package/build/cjs/lib/kit/constants/common.js +5 -0
- package/build/cjs/lib/kit/constants/config.js +8 -0
- package/build/cjs/lib/kit/constants/index.js +1 -0
- package/build/cjs/lib/kit/utils/cn.js +4 -5
- package/build/cjs/lib/kit/utils/common.js +2 -1
- package/build/esm/lib/core/components/Form/hooks/useField.js +2 -2
- package/build/esm/lib/core/types/specs.d.ts +1 -0
- package/build/esm/lib/kit/components/Card/Card.css +4 -0
- package/build/esm/lib/kit/components/Card/Card.js +9 -4
- package/build/esm/lib/kit/components/Inputs/FileInput/FileInput.css +1 -6
- package/build/esm/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.css +14 -0
- package/build/esm/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.d.ts +8 -0
- package/build/esm/lib/kit/components/Inputs/MultiOneOf/MultiOneOf.js +68 -0
- package/build/esm/lib/kit/components/Inputs/MultiOneOf/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Inputs/MultiOneOf/index.js +1 -0
- package/build/esm/lib/kit/components/Inputs/index.d.ts +3 -2
- package/build/esm/lib/kit/components/Inputs/index.js +3 -2
- package/build/esm/lib/kit/components/Layouts/Section/Section.css +4 -0
- package/build/esm/lib/kit/components/Layouts/Section/Section.js +9 -3
- package/build/esm/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.css +1 -0
- package/build/esm/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.d.ts +1 -0
- package/build/esm/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.js +11 -4
- package/build/esm/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.css +21 -0
- package/build/esm/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.d.ts +8 -0
- package/build/esm/lib/kit/components/Views/MultiOneOfView/MultiOneOfView.js +38 -0
- package/build/esm/lib/kit/components/Views/MultiOneOfView/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Views/MultiOneOfView/index.js +1 -0
- 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/common.d.ts +3 -0
- package/build/esm/lib/kit/constants/common.js +2 -0
- package/build/esm/lib/kit/constants/config.js +9 -1
- package/build/esm/lib/kit/constants/index.d.ts +1 -0
- package/build/esm/lib/kit/constants/index.js +1 -0
- package/build/esm/lib/kit/utils/cn.d.ts +2 -2
- package/build/esm/lib/kit/utils/cn.js +3 -2
- package/build/esm/lib/kit/utils/common.js +3 -2
- package/package.json +6 -6
|
@@ -49,8 +49,8 @@ const useField = ({ name, spec, initialValue, value: externalValue, validate: pr
|
|
|
49
49
|
const _value = lodash_1.default.isFunction(valOrSetter) ? valOrSetter(state.value) : valOrSetter;
|
|
50
50
|
const error = validate === null || validate === void 0 ? void 0 : validate(_value);
|
|
51
51
|
let value = (0, utils_1.transformArrIn)(_value);
|
|
52
|
-
if ((0, helpers_1.isNumberSpec)(spec) &&
|
|
53
|
-
value = Number(value);
|
|
52
|
+
if ((0, helpers_1.isNumberSpec)(spec) && !error) {
|
|
53
|
+
value = (value ? Number(value) : undefined);
|
|
54
54
|
}
|
|
55
55
|
let newChildErrors = Object.assign({}, state.childErrors);
|
|
56
56
|
if (childErrors) {
|
|
@@ -51,6 +51,10 @@
|
|
|
51
51
|
font-size: var(--yc-text-subheader-2-font-size);
|
|
52
52
|
font-weight: var(--yc-text-subheader-font-weight);
|
|
53
53
|
line-height: var(--yc-text-subheader-2-line-height);
|
|
54
|
+
white-space: nowrap;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
text-overflow: ellipsis;
|
|
57
|
+
max-width: 533px;
|
|
54
58
|
}
|
|
55
59
|
.df-card__note {
|
|
56
60
|
margin-left: 5px;
|
|
@@ -7,10 +7,13 @@ const components_1 = require("@gravity-ui/components");
|
|
|
7
7
|
const icons_1 = require("@gravity-ui/icons");
|
|
8
8
|
const uikit_1 = require("@gravity-ui/uikit");
|
|
9
9
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
10
|
+
const common_1 = require("../../constants/common");
|
|
10
11
|
const utils_1 = require("../../utils");
|
|
11
12
|
const b = (0, utils_1.block)('card');
|
|
12
13
|
const Card = ({ name, title: propsTitle, description, actions, open: propsOpen, onToggle, alwaysOpen, disableHeaderToggle, checkEmptyBody, children, }) => {
|
|
14
|
+
var _a;
|
|
13
15
|
const containerRef = react_1.default.useRef(null);
|
|
16
|
+
const titleRef = react_1.default.useRef(null);
|
|
14
17
|
const bodyRef = react_1.default.useRef(null);
|
|
15
18
|
const [open, setOpen] = react_1.default.useState(alwaysOpen || propsOpen || false);
|
|
16
19
|
const emptyBody = Boolean(bodyRef.current && !bodyRef.current.childElementCount);
|
|
@@ -30,15 +33,17 @@ const Card = ({ name, title: propsTitle, description, actions, open: propsOpen,
|
|
|
30
33
|
return;
|
|
31
34
|
}, [disableHeaderToggle, handleToggle]);
|
|
32
35
|
const preventEvent = react_1.default.useCallback((e) => e.stopPropagation(), []);
|
|
36
|
+
const titlePopoverDisabled = (((_a = titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= common_1.COMMON_TITLE_MAX_WIDTH;
|
|
33
37
|
const title = react_1.default.useMemo(() => {
|
|
34
38
|
if (lodash_1.default.isString(propsTitle)) {
|
|
35
39
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
36
|
-
react_1.default.createElement(
|
|
40
|
+
react_1.default.createElement(uikit_1.Popover, { content: propsTitle, disabled: titlePopoverDisabled, placement: common_1.COMMON_POPOVER_PLACEMENT },
|
|
41
|
+
react_1.default.createElement("div", { ref: titleRef, className: b('title') }, propsTitle)),
|
|
37
42
|
description ? (react_1.default.createElement("div", { className: b('note') },
|
|
38
|
-
react_1.default.createElement(components_1.HelpPopover, { htmlContent: description, placement:
|
|
43
|
+
react_1.default.createElement(components_1.HelpPopover, { htmlContent: description, placement: common_1.COMMON_POPOVER_PLACEMENT }))) : null));
|
|
39
44
|
}
|
|
40
45
|
return propsTitle;
|
|
41
|
-
}, [propsTitle, description]);
|
|
46
|
+
}, [propsTitle, titlePopoverDisabled, description]);
|
|
42
47
|
react_1.default.useEffect(() => {
|
|
43
48
|
if (!alwaysOpen && propsOpen !== undefined && propsOpen !== open) {
|
|
44
49
|
setOpen(propsOpen);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.df-multi-oneof__select {
|
|
2
|
+
max-width: 305px;
|
|
3
|
+
}
|
|
4
|
+
.df-multi-oneof__content_flat > .df-group-indent {
|
|
5
|
+
margin: 0;
|
|
6
|
+
border-left: none;
|
|
7
|
+
padding: 0;
|
|
8
|
+
}
|
|
9
|
+
.df-multi-oneof__content_flat > .df-group-indent > .df-use-search {
|
|
10
|
+
margin-top: 15px;
|
|
11
|
+
}
|
|
12
|
+
.df-multi-oneof__content_flat > .df-group-indent > .df-use-search:empty {
|
|
13
|
+
display: none;
|
|
14
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiOneOfFlat = exports.MultiOneOf = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
8
|
+
const core_1 = require("../../../../core");
|
|
9
|
+
const utils_1 = require("../../../utils");
|
|
10
|
+
const GroupIndent_1 = require("../../GroupIndent");
|
|
11
|
+
const b = (0, utils_1.block)('multi-oneof');
|
|
12
|
+
const MultiOneOf = (props) => {
|
|
13
|
+
const { name, input, spec, Layout, withoutIndent } = props;
|
|
14
|
+
const { value, onBlur, onChange, onFocus, parentOnUnmount } = input;
|
|
15
|
+
const [valueSelect, setValueSelect] = react_1.default.useState(() => (value ? Object.keys(value) : []));
|
|
16
|
+
const handleOpenChange = react_1.default.useCallback((open) => {
|
|
17
|
+
if (open) {
|
|
18
|
+
onFocus();
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
onBlur();
|
|
22
|
+
}
|
|
23
|
+
}, [onFocus, onBlur]);
|
|
24
|
+
const parentOnChange = react_1.default.useCallback((childName, childValue, childErrors) => {
|
|
25
|
+
onChange((currentValue) => lodash_1.default.set(Object.assign({}, currentValue), childName.split(`${name}.`).join(''), childValue), childErrors);
|
|
26
|
+
}, [name, onChange]);
|
|
27
|
+
const specProperties = react_1.default.useMemo(() => (lodash_1.default.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
|
|
28
|
+
const options = react_1.default.useMemo(() => (spec.viewSpec.order || Object.keys(specProperties)).map((value) => {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
|
|
31
|
+
((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
|
|
32
|
+
value ||
|
|
33
|
+
'';
|
|
34
|
+
return {
|
|
35
|
+
value,
|
|
36
|
+
title,
|
|
37
|
+
content: title,
|
|
38
|
+
};
|
|
39
|
+
}), [spec.description, spec.viewSpec.order, specProperties]);
|
|
40
|
+
const filterable = react_1.default.useMemo(() => (options.length || 0) > 9, [options.length]);
|
|
41
|
+
const selectInput = react_1.default.useMemo(() => {
|
|
42
|
+
const select = (react_1.default.createElement(uikit_1.Select, { width: "max", value: valueSelect, options: options, onUpdate: setValueSelect, onOpenChange: handleOpenChange, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, filterable: filterable, multiple: true, className: b('select'), qa: name }));
|
|
43
|
+
if (Layout) {
|
|
44
|
+
return react_1.default.createElement(Layout, Object.assign({}, props), select);
|
|
45
|
+
}
|
|
46
|
+
return react_1.default.createElement(react_1.default.Fragment, null, select);
|
|
47
|
+
}, [
|
|
48
|
+
Layout,
|
|
49
|
+
filterable,
|
|
50
|
+
handleOpenChange,
|
|
51
|
+
name,
|
|
52
|
+
options,
|
|
53
|
+
props,
|
|
54
|
+
spec.viewSpec.disabled,
|
|
55
|
+
spec.viewSpec.placeholder,
|
|
56
|
+
valueSelect,
|
|
57
|
+
]);
|
|
58
|
+
if (!options) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
62
|
+
selectInput,
|
|
63
|
+
react_1.default.createElement("div", { className: b('content', {
|
|
64
|
+
flat: withoutIndent,
|
|
65
|
+
}) },
|
|
66
|
+
react_1.default.createElement(GroupIndent_1.GroupIndent, null, valueSelect.map((property) => {
|
|
67
|
+
var _a;
|
|
68
|
+
return (react_1.default.createElement(react_1.default.Fragment, { key: property }, specProperties && specProperties[property] ? (react_1.default.createElement(core_1.Controller, { name: `${name}.${property}`, spec: specProperties[property], parentOnUnmount: parentOnUnmount, parentOnChange: parentOnChange, value: (_a = input.value) === null || _a === void 0 ? void 0 : _a[property] })) : null));
|
|
69
|
+
})))));
|
|
70
|
+
};
|
|
71
|
+
exports.MultiOneOf = MultiOneOf;
|
|
72
|
+
const MultiOneOfFlat = (props) => (react_1.default.createElement(exports.MultiOneOf, Object.assign({}, props, { withoutIndent: true })));
|
|
73
|
+
exports.MultiOneOfFlat = MultiOneOfFlat;
|
|
@@ -5,7 +5,10 @@ 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("./MonacoInput"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./MultiOneOf"), exports);
|
|
8
10
|
tslib_1.__exportStar(require("./MultiSelect"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./NumberWithScale"), exports);
|
|
9
12
|
tslib_1.__exportStar(require("./ObjectBase"), exports);
|
|
10
13
|
tslib_1.__exportStar(require("./ObjectValueInput"), exports);
|
|
11
14
|
tslib_1.__exportStar(require("./OneOf"), exports);
|
|
@@ -18,5 +21,3 @@ tslib_1.__exportStar(require("./Text"), exports);
|
|
|
18
21
|
tslib_1.__exportStar(require("./TextArea"), exports);
|
|
19
22
|
tslib_1.__exportStar(require("./TextContent"), exports);
|
|
20
23
|
tslib_1.__exportStar(require("./TextLink"), exports);
|
|
21
|
-
tslib_1.__exportStar(require("./NumberWithScale"), exports);
|
|
22
|
-
tslib_1.__exportStar(require("./MonacoInput"), exports);
|
|
@@ -4,15 +4,18 @@ exports.Group2 = exports.Group = exports.SectionWithSubtitle2 = exports.SectionW
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
6
|
const components_1 = require("@gravity-ui/components");
|
|
7
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
8
|
const __1 = require("../../");
|
|
8
9
|
const __2 = require("../../../");
|
|
9
10
|
const core_1 = require("../../../../core");
|
|
10
11
|
const utils_1 = require("../../../utils");
|
|
11
12
|
const b = (0, utils_1.block)('section');
|
|
12
13
|
const SectionBase = (_a) => {
|
|
14
|
+
var _b;
|
|
13
15
|
var { name, spec, titleSize, withIndent, ignoreDescription, descriptionAsSubtitle, children } = _a, restProps = tslib_1.__rest(_a, ["name", "spec", "titleSize", "withIndent", "ignoreDescription", "descriptionAsSubtitle", "children"]);
|
|
14
16
|
const meta = restProps.meta;
|
|
15
17
|
const arrOrObjFlag = (0, core_1.isArraySpec)(spec) || (0, core_1.isObjectSpec)(spec);
|
|
18
|
+
const titleRef = react_1.default.useRef(null);
|
|
16
19
|
let content = children;
|
|
17
20
|
if (meta) {
|
|
18
21
|
content = (react_1.default.createElement(__2.ErrorWrapper, { name: name, meta: meta, withoutChildErrorStyles: arrOrObjFlag }, content));
|
|
@@ -32,11 +35,14 @@ const SectionBase = (_a) => {
|
|
|
32
35
|
react_1.default.createElement(components_1.HelpPopover, { htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })));
|
|
33
36
|
}
|
|
34
37
|
}
|
|
38
|
+
const layoutTitle = spec.viewSpec.layoutTitle;
|
|
39
|
+
const layoutTitlePopoverDisabled = (((_b = titleRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0) <= __2.COMMON_TITLE_MAX_WIDTH;
|
|
35
40
|
return (react_1.default.createElement("section", { className: b() },
|
|
36
|
-
|
|
41
|
+
layoutTitle ? (react_1.default.createElement("div", { className: b('header', {
|
|
37
42
|
'with-popover': !descriptionAsSubtitle,
|
|
38
43
|
}) },
|
|
39
|
-
react_1.default.createElement(
|
|
44
|
+
react_1.default.createElement(uikit_1.Popover, { content: layoutTitle, placement: __2.COMMON_POPOVER_PLACEMENT, disabled: layoutTitlePopoverDisabled },
|
|
45
|
+
react_1.default.createElement("h2", { className: b('title', { size: titleSize }), ref: titleRef }, layoutTitle)),
|
|
40
46
|
description)) : null,
|
|
41
47
|
react_1.default.createElement("div", { className: b('content') }, content)));
|
|
42
48
|
};
|
|
@@ -6,12 +6,15 @@ const react_1 = tslib_1.__importDefault(require("react"));
|
|
|
6
6
|
const components_1 = require("@gravity-ui/components");
|
|
7
7
|
const icons_1 = require("@gravity-ui/icons");
|
|
8
8
|
const uikit_1 = require("@gravity-ui/uikit");
|
|
9
|
+
const common_1 = require("../../constants/common");
|
|
9
10
|
const utils_1 = require("../../utils");
|
|
10
11
|
const b = (0, utils_1.block)('simple-vertical-accordeon');
|
|
12
|
+
const TITLE_TEXT_MAX_WIDTH = 485; /** 533px (COMMON_TITLE_MAX_WIDTH) - 48px of padding */
|
|
11
13
|
class SimpleVerticalAccordeon extends react_1.default.Component {
|
|
12
14
|
constructor(props) {
|
|
13
15
|
super(props);
|
|
14
16
|
this.componentRef = react_1.default.createRef();
|
|
17
|
+
this.titleRef = react_1.default.createRef();
|
|
15
18
|
this.checkVisibility = () => {
|
|
16
19
|
if (this.props.viewLayout) {
|
|
17
20
|
if (this.componentRef.current &&
|
|
@@ -48,17 +51,21 @@ class SimpleVerticalAccordeon extends react_1.default.Component {
|
|
|
48
51
|
this.checkVisibility();
|
|
49
52
|
}
|
|
50
53
|
render() {
|
|
54
|
+
var _a;
|
|
51
55
|
const { titleSize, children, headerActionsTemplate, className, contentClassName, buttonClassName, hideInsteadOfDestroy, withBranchView, viewLayout, name, } = this.props;
|
|
52
56
|
const { open, hidden, isFirstRender } = this.state;
|
|
53
57
|
const content = hideInsteadOfDestroy ? (react_1.default.createElement("div", { ref: this.componentRef, className: b('body', { hidden: !open }) }, children)) : (open && (react_1.default.createElement("div", { ref: this.componentRef, className: b('body', contentClassName) }, children)));
|
|
54
58
|
if (viewLayout && !isFirstRender && hidden) {
|
|
55
59
|
return null;
|
|
56
60
|
}
|
|
61
|
+
const title = this.getTitle();
|
|
62
|
+
const titlePopoverDisabled = (((_a = this.titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= TITLE_TEXT_MAX_WIDTH;
|
|
57
63
|
return (Boolean(react_1.default.Children.count(children)) && (react_1.default.createElement("div", { className: b({ branch: withBranchView, view: viewLayout }, className) },
|
|
58
64
|
react_1.default.createElement("div", { className: b('header') },
|
|
59
|
-
react_1.default.createElement(uikit_1.
|
|
60
|
-
react_1.default.createElement("
|
|
61
|
-
|
|
65
|
+
react_1.default.createElement(uikit_1.Popover, { content: title, disabled: titlePopoverDisabled, placement: common_1.COMMON_POPOVER_PLACEMENT },
|
|
66
|
+
react_1.default.createElement(uikit_1.Button, { view: "flat", className: b('header-inner', buttonClassName), onClick: this.handleClick, qa: `${name}-accordeon-toggler`, width: "auto" },
|
|
67
|
+
react_1.default.createElement("b", { ref: this.titleRef, className: b('title', { size: titleSize }) }, title),
|
|
68
|
+
react_1.default.createElement(uikit_1.Icon, { data: icons_1.ChevronDown, className: b('chevron', { open }), size: 16 }))),
|
|
62
69
|
this.getTooltip(),
|
|
63
70
|
headerActionsTemplate ? headerActionsTemplate : null),
|
|
64
71
|
content)));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.df-multi-oneof-view__tooltip {
|
|
2
|
+
overflow-wrap: break-word;
|
|
3
|
+
}
|
|
4
|
+
.df-multi-oneof-view__tooltip-container {
|
|
5
|
+
max-width: 100%;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
text-overflow: ellipsis;
|
|
8
|
+
display: block;
|
|
9
|
+
margin-bottom: 6px;
|
|
10
|
+
}
|
|
11
|
+
.df-multi-oneof-view__tooltip-container:last-child {
|
|
12
|
+
margin-bottom: 0;
|
|
13
|
+
}
|
|
14
|
+
.df-multi-oneof-view__content_multiple-values > .df-group-indent {
|
|
15
|
+
padding-top: 0px;
|
|
16
|
+
}
|
|
17
|
+
.df-multi-oneof-view__content_flat > .df-group-indent {
|
|
18
|
+
margin: 0 0 20px;
|
|
19
|
+
border-left: none;
|
|
20
|
+
padding: 0;
|
|
21
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiOneOfFlatView = exports.MultiOneOfView = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
|
+
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
8
|
+
const core_1 = require("../../../../core");
|
|
9
|
+
const utils_1 = require("../../../utils");
|
|
10
|
+
const GroupIndent_1 = require("../../GroupIndent");
|
|
11
|
+
const b = (0, utils_1.block)('multi-oneof-view');
|
|
12
|
+
const MultiOneOfView = (props) => {
|
|
13
|
+
const { name, value, Layout, spec, withoutIndent } = props;
|
|
14
|
+
const specProperties = react_1.default.useMemo(() => (lodash_1.default.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
|
|
15
|
+
const values = react_1.default.useMemo(() => Object.keys(value || []), [value]);
|
|
16
|
+
const items = react_1.default.useMemo(() => values.map((value) => {
|
|
17
|
+
var _a, _b;
|
|
18
|
+
const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
|
|
19
|
+
((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
|
|
20
|
+
value ||
|
|
21
|
+
'';
|
|
22
|
+
return title;
|
|
23
|
+
}), [spec.description, specProperties, values]);
|
|
24
|
+
const selectView = react_1.default.useMemo(() => {
|
|
25
|
+
const selectView = (react_1.default.createElement(react_1.default.Fragment, null, items.map((item) => {
|
|
26
|
+
return (react_1.default.createElement(uikit_1.Popover, { placement: ['bottom', 'top'], key: item, content: item, className: b('tooltip-container'), contentClassName: b('tooltip'), disabled: item.length < 51 }, item));
|
|
27
|
+
})));
|
|
28
|
+
if (Layout) {
|
|
29
|
+
return (react_1.default.createElement(Layout, Object.assign({}, props, { value: values }), selectView));
|
|
30
|
+
}
|
|
31
|
+
return react_1.default.createElement(react_1.default.Fragment, null, selectView);
|
|
32
|
+
}, [Layout, items, props, values]);
|
|
33
|
+
if (values.length === 0) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
37
|
+
selectView,
|
|
38
|
+
react_1.default.createElement("div", { className: b('content', { flat: withoutIndent, 'multiple-values': items.length > 1 }) },
|
|
39
|
+
react_1.default.createElement(GroupIndent_1.GroupIndent, null, values.map((value) => (react_1.default.createElement(react_1.default.Fragment, { key: value }, specProperties && specProperties[value] ? (react_1.default.createElement(core_1.ViewController, { name: `${name}.${value}`, spec: specProperties[value] })) : null)))))));
|
|
40
|
+
};
|
|
41
|
+
exports.MultiOneOfView = MultiOneOfView;
|
|
42
|
+
const MultiOneOfFlatView = (props) => (react_1.default.createElement(exports.MultiOneOfView, Object.assign({}, props, { withoutIndent: true })));
|
|
43
|
+
exports.MultiOneOfFlatView = MultiOneOfFlatView;
|
|
@@ -6,6 +6,7 @@ tslib_1.__exportStar(require("./BaseView"), exports);
|
|
|
6
6
|
tslib_1.__exportStar(require("./CardOneOfView"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./FileInputView"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./MonacoInputView"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./MultiOneOfView"), exports);
|
|
9
10
|
tslib_1.__exportStar(require("./MultiSelectView"), exports);
|
|
10
11
|
tslib_1.__exportStar(require("./NumberWithScaleView"), exports);
|
|
11
12
|
tslib_1.__exportStar(require("./ObjectBaseView"), exports);
|
|
@@ -64,6 +64,8 @@ exports.dynamicConfig = {
|
|
|
64
64
|
base: { Component: components_1.ObjectBase, independent: true },
|
|
65
65
|
text_link: { Component: components_1.TextLink, independent: true },
|
|
66
66
|
object_value: { Component: components_1.ObjectValueInput, independent: true },
|
|
67
|
+
multi_oneof: { Component: components_1.MultiOneOf, independent: true },
|
|
68
|
+
multi_oneof_flat: { Component: components_1.MultiOneOfFlat, independent: true },
|
|
67
69
|
},
|
|
68
70
|
layouts: {
|
|
69
71
|
row: components_1.Row,
|
|
@@ -163,6 +165,8 @@ exports.dynamicCardConfig = {
|
|
|
163
165
|
base: { Component: components_1.ObjectBase, independent: true },
|
|
164
166
|
text_link: { Component: components_1.TextLink, independent: true },
|
|
165
167
|
object_value: { Component: components_1.ObjectValueInput, independent: true },
|
|
168
|
+
multi_oneof: { Component: components_1.MultiOneOf, independent: true },
|
|
169
|
+
multi_oneof_flat: { Component: components_1.MultiOneOfFlat, independent: true },
|
|
166
170
|
},
|
|
167
171
|
layouts: {
|
|
168
172
|
row: components_1.Row2,
|
|
@@ -255,6 +259,8 @@ exports.dynamicViewConfig = {
|
|
|
255
259
|
base: { Component: components_1.ObjectBaseView, independent: true },
|
|
256
260
|
text_link: { Component: components_1.TextLinkView, independent: true },
|
|
257
261
|
object_value: { Component: components_1.ObjectValueInputView, independent: true },
|
|
262
|
+
multi_oneof: { Component: components_1.MultiOneOfView, independent: true },
|
|
263
|
+
multi_oneof_flat: { Component: components_1.MultiOneOfFlatView, independent: true },
|
|
258
264
|
},
|
|
259
265
|
layouts: {
|
|
260
266
|
row: components_1.ViewRow,
|
|
@@ -338,6 +344,8 @@ exports.dynamicViewCardConfig = {
|
|
|
338
344
|
base: { Component: components_1.ObjectBaseView, independent: true },
|
|
339
345
|
text_link: { Component: components_1.TextLinkView, independent: true },
|
|
340
346
|
object_value: { Component: components_1.ObjectValueInputView, independent: true },
|
|
347
|
+
multi_oneof: { Component: components_1.MultiOneOfView, independent: true },
|
|
348
|
+
multi_oneof_flat: { Component: components_1.MultiOneOfFlatView, independent: true },
|
|
341
349
|
},
|
|
342
350
|
layouts: {
|
|
343
351
|
row: components_1.ViewRow2,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.block = void 0;
|
|
4
|
-
const
|
|
5
|
-
const bem_cn_lite_1 = tslib_1.__importDefault(require("bem-cn-lite"));
|
|
3
|
+
exports.block = exports.cn = void 0;
|
|
4
|
+
const classname_1 = require("@bem-react/classname");
|
|
6
5
|
const NAMESPACE = 'df-';
|
|
7
|
-
|
|
8
|
-
exports.block =
|
|
6
|
+
exports.cn = (0, classname_1.withNaming)({ e: '__', m: '_' });
|
|
7
|
+
exports.block = (0, classname_1.withNaming)({ n: NAMESPACE, e: '__', m: '_' });
|
|
@@ -52,7 +52,8 @@ const prepareSpec = (spec, parseJsonDefaultValue) => {
|
|
|
52
52
|
_defaultValue = undefined;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
if (typeof _defaultValue === result.type
|
|
55
|
+
if (typeof _defaultValue === result.type ||
|
|
56
|
+
(lodash_1.default.isArray(_defaultValue) && result.type === core_1.SpecTypes.Array)) {
|
|
56
57
|
result.defaultValue = _defaultValue;
|
|
57
58
|
}
|
|
58
59
|
else {
|
|
@@ -45,8 +45,8 @@ export const useField = ({ name, spec, initialValue, value: externalValue, valid
|
|
|
45
45
|
const _value = _.isFunction(valOrSetter) ? valOrSetter(state.value) : valOrSetter;
|
|
46
46
|
const error = validate === null || validate === void 0 ? void 0 : validate(_value);
|
|
47
47
|
let value = transformArrIn(_value);
|
|
48
|
-
if (isNumberSpec(spec) &&
|
|
49
|
-
value = Number(value);
|
|
48
|
+
if (isNumberSpec(spec) && !error) {
|
|
49
|
+
value = (value ? Number(value) : undefined);
|
|
50
50
|
}
|
|
51
51
|
let newChildErrors = Object.assign({}, state.childErrors);
|
|
52
52
|
if (childErrors) {
|
|
@@ -51,6 +51,10 @@
|
|
|
51
51
|
font-size: var(--yc-text-subheader-2-font-size);
|
|
52
52
|
font-weight: var(--yc-text-subheader-font-weight);
|
|
53
53
|
line-height: var(--yc-text-subheader-2-line-height);
|
|
54
|
+
white-space: nowrap;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
text-overflow: ellipsis;
|
|
57
|
+
max-width: 533px;
|
|
54
58
|
}
|
|
55
59
|
.df-card__note {
|
|
56
60
|
margin-left: 5px;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { HelpPopover } from '@gravity-ui/components';
|
|
3
3
|
import { ChevronDown } from '@gravity-ui/icons';
|
|
4
|
-
import { Button, Card as CardBase, Icon } from '@gravity-ui/uikit';
|
|
4
|
+
import { Button, Card as CardBase, Icon, Popover } from '@gravity-ui/uikit';
|
|
5
5
|
import _ from 'lodash';
|
|
6
|
+
import { COMMON_POPOVER_PLACEMENT, COMMON_TITLE_MAX_WIDTH } from '../../constants/common';
|
|
6
7
|
import { block } from '../../utils';
|
|
7
8
|
import './Card.css';
|
|
8
9
|
const b = block('card');
|
|
9
10
|
export const Card = ({ name, title: propsTitle, description, actions, open: propsOpen, onToggle, alwaysOpen, disableHeaderToggle, checkEmptyBody, children, }) => {
|
|
11
|
+
var _a;
|
|
10
12
|
const containerRef = React.useRef(null);
|
|
13
|
+
const titleRef = React.useRef(null);
|
|
11
14
|
const bodyRef = React.useRef(null);
|
|
12
15
|
const [open, setOpen] = React.useState(alwaysOpen || propsOpen || false);
|
|
13
16
|
const emptyBody = Boolean(bodyRef.current && !bodyRef.current.childElementCount);
|
|
@@ -27,15 +30,17 @@ export const Card = ({ name, title: propsTitle, description, actions, open: prop
|
|
|
27
30
|
return;
|
|
28
31
|
}, [disableHeaderToggle, handleToggle]);
|
|
29
32
|
const preventEvent = React.useCallback((e) => e.stopPropagation(), []);
|
|
33
|
+
const titlePopoverDisabled = (((_a = titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= COMMON_TITLE_MAX_WIDTH;
|
|
30
34
|
const title = React.useMemo(() => {
|
|
31
35
|
if (_.isString(propsTitle)) {
|
|
32
36
|
return (React.createElement(React.Fragment, null,
|
|
33
|
-
React.createElement(
|
|
37
|
+
React.createElement(Popover, { content: propsTitle, disabled: titlePopoverDisabled, placement: COMMON_POPOVER_PLACEMENT },
|
|
38
|
+
React.createElement("div", { ref: titleRef, className: b('title') }, propsTitle)),
|
|
34
39
|
description ? (React.createElement("div", { className: b('note') },
|
|
35
|
-
React.createElement(HelpPopover, { htmlContent: description, placement:
|
|
40
|
+
React.createElement(HelpPopover, { htmlContent: description, placement: COMMON_POPOVER_PLACEMENT }))) : null));
|
|
36
41
|
}
|
|
37
42
|
return propsTitle;
|
|
38
|
-
}, [propsTitle, description]);
|
|
43
|
+
}, [propsTitle, titlePopoverDisabled, description]);
|
|
39
44
|
React.useEffect(() => {
|
|
40
45
|
if (!alwaysOpen && propsOpen !== undefined && propsOpen !== open) {
|
|
41
46
|
setOpen(propsOpen);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.df-multi-oneof__select {
|
|
2
|
+
max-width: 305px;
|
|
3
|
+
}
|
|
4
|
+
.df-multi-oneof__content_flat > .df-group-indent {
|
|
5
|
+
margin: 0;
|
|
6
|
+
border-left: none;
|
|
7
|
+
padding: 0;
|
|
8
|
+
}
|
|
9
|
+
.df-multi-oneof__content_flat > .df-group-indent > .df-use-search {
|
|
10
|
+
margin-top: 15px;
|
|
11
|
+
}
|
|
12
|
+
.df-multi-oneof__content_flat > .df-group-indent > .df-use-search:empty {
|
|
13
|
+
display: none;
|
|
14
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ObjectIndependentInput, ObjectIndependentInputProps } from '../../../../core';
|
|
3
|
+
import './MultiOneOf.css';
|
|
4
|
+
export interface MultiOneOfProps extends ObjectIndependentInputProps {
|
|
5
|
+
withoutIndent?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const MultiOneOf: React.FC<MultiOneOfProps>;
|
|
8
|
+
export declare const MultiOneOfFlat: ObjectIndependentInput;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Select } from '@gravity-ui/uikit';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
import { Controller, } from '../../../../core';
|
|
5
|
+
import { block } from '../../../utils';
|
|
6
|
+
import { GroupIndent } from '../../GroupIndent';
|
|
7
|
+
import './MultiOneOf.css';
|
|
8
|
+
const b = block('multi-oneof');
|
|
9
|
+
export const MultiOneOf = (props) => {
|
|
10
|
+
const { name, input, spec, Layout, withoutIndent } = props;
|
|
11
|
+
const { value, onBlur, onChange, onFocus, parentOnUnmount } = input;
|
|
12
|
+
const [valueSelect, setValueSelect] = React.useState(() => (value ? Object.keys(value) : []));
|
|
13
|
+
const handleOpenChange = React.useCallback((open) => {
|
|
14
|
+
if (open) {
|
|
15
|
+
onFocus();
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
onBlur();
|
|
19
|
+
}
|
|
20
|
+
}, [onFocus, onBlur]);
|
|
21
|
+
const parentOnChange = React.useCallback((childName, childValue, childErrors) => {
|
|
22
|
+
onChange((currentValue) => _.set(Object.assign({}, currentValue), childName.split(`${name}.`).join(''), childValue), childErrors);
|
|
23
|
+
}, [name, onChange]);
|
|
24
|
+
const specProperties = React.useMemo(() => (_.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
|
|
25
|
+
const options = React.useMemo(() => (spec.viewSpec.order || Object.keys(specProperties)).map((value) => {
|
|
26
|
+
var _a, _b;
|
|
27
|
+
const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
|
|
28
|
+
((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
|
|
29
|
+
value ||
|
|
30
|
+
'';
|
|
31
|
+
return {
|
|
32
|
+
value,
|
|
33
|
+
title,
|
|
34
|
+
content: title,
|
|
35
|
+
};
|
|
36
|
+
}), [spec.description, spec.viewSpec.order, specProperties]);
|
|
37
|
+
const filterable = React.useMemo(() => (options.length || 0) > 9, [options.length]);
|
|
38
|
+
const selectInput = React.useMemo(() => {
|
|
39
|
+
const select = (React.createElement(Select, { width: "max", value: valueSelect, options: options, onUpdate: setValueSelect, onOpenChange: handleOpenChange, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, filterable: filterable, multiple: true, className: b('select'), qa: name }));
|
|
40
|
+
if (Layout) {
|
|
41
|
+
return React.createElement(Layout, Object.assign({}, props), select);
|
|
42
|
+
}
|
|
43
|
+
return React.createElement(React.Fragment, null, select);
|
|
44
|
+
}, [
|
|
45
|
+
Layout,
|
|
46
|
+
filterable,
|
|
47
|
+
handleOpenChange,
|
|
48
|
+
name,
|
|
49
|
+
options,
|
|
50
|
+
props,
|
|
51
|
+
spec.viewSpec.disabled,
|
|
52
|
+
spec.viewSpec.placeholder,
|
|
53
|
+
valueSelect,
|
|
54
|
+
]);
|
|
55
|
+
if (!options) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return (React.createElement(React.Fragment, null,
|
|
59
|
+
selectInput,
|
|
60
|
+
React.createElement("div", { className: b('content', {
|
|
61
|
+
flat: withoutIndent,
|
|
62
|
+
}) },
|
|
63
|
+
React.createElement(GroupIndent, null, valueSelect.map((property) => {
|
|
64
|
+
var _a;
|
|
65
|
+
return (React.createElement(React.Fragment, { key: property }, specProperties && specProperties[property] ? (React.createElement(Controller, { name: `${name}.${property}`, spec: specProperties[property], parentOnUnmount: parentOnUnmount, parentOnChange: parentOnChange, value: (_a = input.value) === null || _a === void 0 ? void 0 : _a[property] })) : null));
|
|
66
|
+
})))));
|
|
67
|
+
};
|
|
68
|
+
export const MultiOneOfFlat = (props) => (React.createElement(MultiOneOf, Object.assign({}, props, { withoutIndent: true })));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './MultiOneOf';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './MultiOneOf';
|
|
@@ -2,7 +2,10 @@ export * from './ArrayBase';
|
|
|
2
2
|
export * from './CardOneOf';
|
|
3
3
|
export * from './Checkbox';
|
|
4
4
|
export * from './FileInput';
|
|
5
|
+
export * from './MonacoInput';
|
|
6
|
+
export * from './MultiOneOf';
|
|
5
7
|
export * from './MultiSelect';
|
|
8
|
+
export * from './NumberWithScale';
|
|
6
9
|
export * from './ObjectBase';
|
|
7
10
|
export * from './ObjectValueInput';
|
|
8
11
|
export * from './OneOf';
|
|
@@ -15,5 +18,3 @@ export * from './Text';
|
|
|
15
18
|
export * from './TextArea';
|
|
16
19
|
export * from './TextContent';
|
|
17
20
|
export * from './TextLink';
|
|
18
|
-
export * from './NumberWithScale';
|
|
19
|
-
export * from './MonacoInput';
|
|
@@ -2,7 +2,10 @@ export * from './ArrayBase';
|
|
|
2
2
|
export * from './CardOneOf';
|
|
3
3
|
export * from './Checkbox';
|
|
4
4
|
export * from './FileInput';
|
|
5
|
+
export * from './MonacoInput';
|
|
6
|
+
export * from './MultiOneOf';
|
|
5
7
|
export * from './MultiSelect';
|
|
8
|
+
export * from './NumberWithScale';
|
|
6
9
|
export * from './ObjectBase';
|
|
7
10
|
export * from './ObjectValueInput';
|
|
8
11
|
export * from './OneOf';
|
|
@@ -15,5 +18,3 @@ export * from './Text';
|
|
|
15
18
|
export * from './TextArea';
|
|
16
19
|
export * from './TextContent';
|
|
17
20
|
export * from './TextLink';
|
|
18
|
-
export * from './NumberWithScale';
|
|
19
|
-
export * from './MonacoInput';
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { __rest } from "tslib";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { HelpPopover } from '@gravity-ui/components';
|
|
4
|
+
import { Popover } from '@gravity-ui/uikit';
|
|
4
5
|
import { GroupIndent } from '../../';
|
|
5
|
-
import { ErrorWrapper } from '../../../';
|
|
6
|
+
import { COMMON_POPOVER_PLACEMENT, COMMON_TITLE_MAX_WIDTH, ErrorWrapper } from '../../../';
|
|
6
7
|
import { isArraySpec, isObjectSpec, } from '../../../../core';
|
|
7
8
|
import { block } from '../../../utils';
|
|
8
9
|
import './Section.css';
|
|
9
10
|
const b = block('section');
|
|
10
11
|
const SectionBase = (_a) => {
|
|
12
|
+
var _b;
|
|
11
13
|
var { name, spec, titleSize, withIndent, ignoreDescription, descriptionAsSubtitle, children } = _a, restProps = __rest(_a, ["name", "spec", "titleSize", "withIndent", "ignoreDescription", "descriptionAsSubtitle", "children"]);
|
|
12
14
|
const meta = restProps.meta;
|
|
13
15
|
const arrOrObjFlag = isArraySpec(spec) || isObjectSpec(spec);
|
|
16
|
+
const titleRef = React.useRef(null);
|
|
14
17
|
let content = children;
|
|
15
18
|
if (meta) {
|
|
16
19
|
content = (React.createElement(ErrorWrapper, { name: name, meta: meta, withoutChildErrorStyles: arrOrObjFlag }, content));
|
|
@@ -30,11 +33,14 @@ const SectionBase = (_a) => {
|
|
|
30
33
|
React.createElement(HelpPopover, { htmlContent: spec.viewSpec.layoutDescription, placement: ['bottom', 'top'] })));
|
|
31
34
|
}
|
|
32
35
|
}
|
|
36
|
+
const layoutTitle = spec.viewSpec.layoutTitle;
|
|
37
|
+
const layoutTitlePopoverDisabled = (((_b = titleRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0) <= COMMON_TITLE_MAX_WIDTH;
|
|
33
38
|
return (React.createElement("section", { className: b() },
|
|
34
|
-
|
|
39
|
+
layoutTitle ? (React.createElement("div", { className: b('header', {
|
|
35
40
|
'with-popover': !descriptionAsSubtitle,
|
|
36
41
|
}) },
|
|
37
|
-
React.createElement(
|
|
42
|
+
React.createElement(Popover, { content: layoutTitle, placement: COMMON_POPOVER_PLACEMENT, disabled: layoutTitlePopoverDisabled },
|
|
43
|
+
React.createElement("h2", { className: b('title', { size: titleSize }), ref: titleRef }, layoutTitle)),
|
|
38
44
|
description)) : null,
|
|
39
45
|
React.createElement("div", { className: b('content') }, content)));
|
|
40
46
|
};
|
|
@@ -29,6 +29,7 @@ export declare class SimpleVerticalAccordeon extends React.Component<SimpleVerti
|
|
|
29
29
|
withBranchView: boolean;
|
|
30
30
|
};
|
|
31
31
|
componentRef: React.RefObject<HTMLDivElement>;
|
|
32
|
+
titleRef: React.RefObject<HTMLElement>;
|
|
32
33
|
constructor(props: SimpleVerticalAccordeonProps);
|
|
33
34
|
componentDidUpdate(prevProps: Readonly<SimpleVerticalAccordeonProps>): void;
|
|
34
35
|
componentDidMount(): void;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { HelpPopover } from '@gravity-ui/components';
|
|
3
3
|
import { ChevronDown } from '@gravity-ui/icons';
|
|
4
|
-
import { Button, Icon } from '@gravity-ui/uikit';
|
|
4
|
+
import { Button, Icon, Popover } from '@gravity-ui/uikit';
|
|
5
|
+
import { COMMON_POPOVER_PLACEMENT } from '../../constants/common';
|
|
5
6
|
import { block } from '../../utils';
|
|
6
7
|
import './SimpleVerticalAccordeon.css';
|
|
7
8
|
const b = block('simple-vertical-accordeon');
|
|
9
|
+
const TITLE_TEXT_MAX_WIDTH = 485; /** 533px (COMMON_TITLE_MAX_WIDTH) - 48px of padding */
|
|
8
10
|
export class SimpleVerticalAccordeon extends React.Component {
|
|
9
11
|
constructor(props) {
|
|
10
12
|
super(props);
|
|
11
13
|
this.componentRef = React.createRef();
|
|
14
|
+
this.titleRef = React.createRef();
|
|
12
15
|
this.checkVisibility = () => {
|
|
13
16
|
if (this.props.viewLayout) {
|
|
14
17
|
if (this.componentRef.current &&
|
|
@@ -45,17 +48,21 @@ export class SimpleVerticalAccordeon extends React.Component {
|
|
|
45
48
|
this.checkVisibility();
|
|
46
49
|
}
|
|
47
50
|
render() {
|
|
51
|
+
var _a;
|
|
48
52
|
const { titleSize, children, headerActionsTemplate, className, contentClassName, buttonClassName, hideInsteadOfDestroy, withBranchView, viewLayout, name, } = this.props;
|
|
49
53
|
const { open, hidden, isFirstRender } = this.state;
|
|
50
54
|
const content = hideInsteadOfDestroy ? (React.createElement("div", { ref: this.componentRef, className: b('body', { hidden: !open }) }, children)) : (open && (React.createElement("div", { ref: this.componentRef, className: b('body', contentClassName) }, children)));
|
|
51
55
|
if (viewLayout && !isFirstRender && hidden) {
|
|
52
56
|
return null;
|
|
53
57
|
}
|
|
58
|
+
const title = this.getTitle();
|
|
59
|
+
const titlePopoverDisabled = (((_a = this.titleRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0) <= TITLE_TEXT_MAX_WIDTH;
|
|
54
60
|
return (Boolean(React.Children.count(children)) && (React.createElement("div", { className: b({ branch: withBranchView, view: viewLayout }, className) },
|
|
55
61
|
React.createElement("div", { className: b('header') },
|
|
56
|
-
React.createElement(
|
|
57
|
-
React.createElement("
|
|
58
|
-
|
|
62
|
+
React.createElement(Popover, { content: title, disabled: titlePopoverDisabled, placement: COMMON_POPOVER_PLACEMENT },
|
|
63
|
+
React.createElement(Button, { view: "flat", className: b('header-inner', buttonClassName), onClick: this.handleClick, qa: `${name}-accordeon-toggler`, width: "auto" },
|
|
64
|
+
React.createElement("b", { ref: this.titleRef, className: b('title', { size: titleSize }) }, title),
|
|
65
|
+
React.createElement(Icon, { data: ChevronDown, className: b('chevron', { open }), size: 16 }))),
|
|
59
66
|
this.getTooltip(),
|
|
60
67
|
headerActionsTemplate ? headerActionsTemplate : null),
|
|
61
68
|
content)));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.df-multi-oneof-view__tooltip {
|
|
2
|
+
overflow-wrap: break-word;
|
|
3
|
+
}
|
|
4
|
+
.df-multi-oneof-view__tooltip-container {
|
|
5
|
+
max-width: 100%;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
text-overflow: ellipsis;
|
|
8
|
+
display: block;
|
|
9
|
+
margin-bottom: 6px;
|
|
10
|
+
}
|
|
11
|
+
.df-multi-oneof-view__tooltip-container:last-child {
|
|
12
|
+
margin-bottom: 0;
|
|
13
|
+
}
|
|
14
|
+
.df-multi-oneof-view__content_multiple-values > .df-group-indent {
|
|
15
|
+
padding-top: 0px;
|
|
16
|
+
}
|
|
17
|
+
.df-multi-oneof-view__content_flat > .df-group-indent {
|
|
18
|
+
margin: 0 0 20px;
|
|
19
|
+
border-left: none;
|
|
20
|
+
padding: 0;
|
|
21
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ObjectIndependentView, ObjectIndependentViewProps } from '../../../../core';
|
|
3
|
+
import './MultiOneOfView.css';
|
|
4
|
+
export interface MultiOneOfViewProps extends ObjectIndependentViewProps {
|
|
5
|
+
withoutIndent?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const MultiOneOfView: React.FC<MultiOneOfViewProps>;
|
|
8
|
+
export declare const MultiOneOfFlatView: ObjectIndependentView;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Popover } from '@gravity-ui/uikit';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
import { ViewController } from '../../../../core';
|
|
5
|
+
import { block } from '../../../utils';
|
|
6
|
+
import { GroupIndent } from '../../GroupIndent';
|
|
7
|
+
import './MultiOneOfView.css';
|
|
8
|
+
const b = block('multi-oneof-view');
|
|
9
|
+
export const MultiOneOfView = (props) => {
|
|
10
|
+
const { name, value, Layout, spec, withoutIndent } = props;
|
|
11
|
+
const specProperties = React.useMemo(() => (_.isObjectLike(spec.properties) ? spec.properties : {}), [spec.properties]);
|
|
12
|
+
const values = React.useMemo(() => Object.keys(value || []), [value]);
|
|
13
|
+
const items = React.useMemo(() => values.map((value) => {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
const title = ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[value]) ||
|
|
16
|
+
((_b = specProperties[value]) === null || _b === void 0 ? void 0 : _b.viewSpec.layoutTitle) ||
|
|
17
|
+
value ||
|
|
18
|
+
'';
|
|
19
|
+
return title;
|
|
20
|
+
}), [spec.description, specProperties, values]);
|
|
21
|
+
const selectView = React.useMemo(() => {
|
|
22
|
+
const selectView = (React.createElement(React.Fragment, null, items.map((item) => {
|
|
23
|
+
return (React.createElement(Popover, { placement: ['bottom', 'top'], key: item, content: item, className: b('tooltip-container'), contentClassName: b('tooltip'), disabled: item.length < 51 }, item));
|
|
24
|
+
})));
|
|
25
|
+
if (Layout) {
|
|
26
|
+
return (React.createElement(Layout, Object.assign({}, props, { value: values }), selectView));
|
|
27
|
+
}
|
|
28
|
+
return React.createElement(React.Fragment, null, selectView);
|
|
29
|
+
}, [Layout, items, props, values]);
|
|
30
|
+
if (values.length === 0) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return (React.createElement(React.Fragment, null,
|
|
34
|
+
selectView,
|
|
35
|
+
React.createElement("div", { className: b('content', { flat: withoutIndent, 'multiple-values': items.length > 1 }) },
|
|
36
|
+
React.createElement(GroupIndent, null, values.map((value) => (React.createElement(React.Fragment, { key: value }, specProperties && specProperties[value] ? (React.createElement(ViewController, { name: `${name}.${value}`, spec: specProperties[value] })) : null)))))));
|
|
37
|
+
};
|
|
38
|
+
export const MultiOneOfFlatView = (props) => (React.createElement(MultiOneOfView, Object.assign({}, props, { withoutIndent: true })));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './MultiOneOfView';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './MultiOneOfView';
|
|
@@ -3,6 +3,7 @@ export * from './BaseView';
|
|
|
3
3
|
export * from './CardOneOfView';
|
|
4
4
|
export * from './FileInputView';
|
|
5
5
|
export * from './MonacoInputView';
|
|
6
|
+
export * from './MultiOneOfView';
|
|
6
7
|
export * from './MultiSelectView';
|
|
7
8
|
export * from './NumberWithScaleView';
|
|
8
9
|
export * from './ObjectBaseView';
|
|
@@ -3,6 +3,7 @@ export * from './BaseView';
|
|
|
3
3
|
export * from './CardOneOfView';
|
|
4
4
|
export * from './FileInputView';
|
|
5
5
|
export * from './MonacoInputView';
|
|
6
|
+
export * from './MultiOneOfView';
|
|
6
7
|
export * from './MultiSelectView';
|
|
7
8
|
export * from './NumberWithScaleView';
|
|
8
9
|
export * from './ObjectBaseView';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Accordeon, AccordeonCardLayout, ArrayBase, ArrayBaseView, BaseView, CardAccordeon, CardOneOf, CardOneOfView, CardSection, Checkbox, FileInput, FileInputView, Group, Group2, MonacoInput, MonacoInputCard, MonacoView, MonacoViewCard, MultiSelect, MultiSelectView, NumberWithScale, NumberWithScaleView, ObjectBase, ObjectBaseView, ObjectValueInput, ObjectValueInputView, OneOf, OneOfCard, OneOfCardView, OneOfFlat, OneOfFlatView, OneOfView, Row, Row2, RowVerbose, Secret, Section, Section2, SectionCard, SectionCard2, SectionWithSubtitle, SectionWithSubtitle2, Select, Switch, TableArrayInput, TableArrayView, TableCell, Text, TextArea, TextAreaView, TextContent, TextLink, TextLinkView, Transparent, ViewAccordeon, ViewAccordeonCard, ViewCardAccordeon, ViewCardSection, ViewGroup, ViewGroup2, ViewRow, ViewRow2, ViewSection, ViewSection2, ViewSectionCard, ViewSectionCard2, ViewTableCell, ViewTransparent, } from '../components';
|
|
1
|
+
import { Accordeon, AccordeonCardLayout, ArrayBase, ArrayBaseView, BaseView, CardAccordeon, CardOneOf, CardOneOfView, CardSection, Checkbox, FileInput, FileInputView, Group, Group2, MonacoInput, MonacoInputCard, MonacoView, MonacoViewCard, MultiOneOf, MultiOneOfFlat, MultiOneOfFlatView, MultiOneOfView, MultiSelect, MultiSelectView, NumberWithScale, NumberWithScaleView, ObjectBase, ObjectBaseView, ObjectValueInput, ObjectValueInputView, OneOf, OneOfCard, OneOfCardView, OneOfFlat, OneOfFlatView, OneOfView, Row, Row2, RowVerbose, Secret, Section, Section2, SectionCard, SectionCard2, SectionWithSubtitle, SectionWithSubtitle2, Select, Switch, TableArrayInput, TableArrayView, TableCell, Text, TextArea, TextAreaView, TextContent, TextLink, TextLinkView, Transparent, ViewAccordeon, ViewAccordeonCard, ViewCardAccordeon, ViewCardSection, ViewGroup, ViewGroup2, ViewRow, ViewRow2, ViewSection, ViewSection2, ViewSectionCard, ViewSectionCard2, ViewTableCell, ViewTransparent, } from '../components';
|
|
2
2
|
import { getArrayValidator, getBooleanValidator, getNumberValidator, getObjectValidator, getStringValidator, } from '../validators';
|
|
3
3
|
export const dynamicConfig = {
|
|
4
4
|
array: {
|
|
@@ -61,6 +61,8 @@ export const dynamicConfig = {
|
|
|
61
61
|
base: { Component: ObjectBase, independent: true },
|
|
62
62
|
text_link: { Component: TextLink, independent: true },
|
|
63
63
|
object_value: { Component: ObjectValueInput, independent: true },
|
|
64
|
+
multi_oneof: { Component: MultiOneOf, independent: true },
|
|
65
|
+
multi_oneof_flat: { Component: MultiOneOfFlat, independent: true },
|
|
64
66
|
},
|
|
65
67
|
layouts: {
|
|
66
68
|
row: Row,
|
|
@@ -160,6 +162,8 @@ export const dynamicCardConfig = {
|
|
|
160
162
|
base: { Component: ObjectBase, independent: true },
|
|
161
163
|
text_link: { Component: TextLink, independent: true },
|
|
162
164
|
object_value: { Component: ObjectValueInput, independent: true },
|
|
165
|
+
multi_oneof: { Component: MultiOneOf, independent: true },
|
|
166
|
+
multi_oneof_flat: { Component: MultiOneOfFlat, independent: true },
|
|
163
167
|
},
|
|
164
168
|
layouts: {
|
|
165
169
|
row: Row2,
|
|
@@ -252,6 +256,8 @@ export const dynamicViewConfig = {
|
|
|
252
256
|
base: { Component: ObjectBaseView, independent: true },
|
|
253
257
|
text_link: { Component: TextLinkView, independent: true },
|
|
254
258
|
object_value: { Component: ObjectValueInputView, independent: true },
|
|
259
|
+
multi_oneof: { Component: MultiOneOfView, independent: true },
|
|
260
|
+
multi_oneof_flat: { Component: MultiOneOfFlatView, independent: true },
|
|
255
261
|
},
|
|
256
262
|
layouts: {
|
|
257
263
|
row: ViewRow,
|
|
@@ -335,6 +341,8 @@ export const dynamicViewCardConfig = {
|
|
|
335
341
|
base: { Component: ObjectBaseView, independent: true },
|
|
336
342
|
text_link: { Component: TextLinkView, independent: true },
|
|
337
343
|
object_value: { Component: ObjectValueInputView, independent: true },
|
|
344
|
+
multi_oneof: { Component: MultiOneOfView, independent: true },
|
|
345
|
+
multi_oneof_flat: { Component: MultiOneOfFlatView, independent: true },
|
|
338
346
|
},
|
|
339
347
|
layouts: {
|
|
340
348
|
row: ViewRow2,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const block: (
|
|
1
|
+
export declare const cn: import("@bem-react/classname").ClassNameInitilizer;
|
|
2
|
+
export declare const block: import("@bem-react/classname").ClassNameInitilizer;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { withNaming } from '@bem-react/classname';
|
|
2
2
|
const NAMESPACE = 'df-';
|
|
3
|
-
export const
|
|
3
|
+
export const cn = withNaming({ e: '__', m: '_' });
|
|
4
|
+
export const block = withNaming({ n: NAMESPACE, e: '__', m: '_' });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import { isArraySpec, isObjectSpec, isStringSpec, } from '../../core';
|
|
2
|
+
import { SpecTypes, isArraySpec, isObjectSpec, isStringSpec, } from '../../core';
|
|
3
3
|
import { isFloat } from '../validators/helpers';
|
|
4
4
|
import { divide } from './bigIntMath';
|
|
5
5
|
export const isNotEmptyValue = (value, spec) => {
|
|
@@ -47,7 +47,8 @@ export const prepareSpec = (spec, parseJsonDefaultValue) => {
|
|
|
47
47
|
_defaultValue = undefined;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
if (typeof _defaultValue === result.type
|
|
50
|
+
if (typeof _defaultValue === result.type ||
|
|
51
|
+
(_.isArray(_defaultValue) && result.type === SpecTypes.Array)) {
|
|
51
52
|
result.defaultValue = _defaultValue;
|
|
52
53
|
}
|
|
53
54
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravity-ui/dynamic-forms",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "build/cjs/index.js",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"prepublishOnly": "npm run build"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"@gravity-ui/
|
|
42
|
-
"@gravity-ui/
|
|
43
|
-
"
|
|
40
|
+
"@bem-react/classname": "^1.6.0",
|
|
41
|
+
"@gravity-ui/components": "^2.4.0",
|
|
42
|
+
"@gravity-ui/i18n": "^1.1.0",
|
|
43
|
+
"@gravity-ui/icons": "^2.5.0",
|
|
44
44
|
"lodash": "^4.17.20"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@gravity-ui/prettier-config": "^1.0.1",
|
|
53
53
|
"@gravity-ui/stylelint-config": "^2.0.0",
|
|
54
54
|
"@gravity-ui/tsconfig": "^1.0.0",
|
|
55
|
-
"@gravity-ui/uikit": "^5.0
|
|
55
|
+
"@gravity-ui/uikit": "^5.8.0",
|
|
56
56
|
"@storybook/addon-essentials": "^7.0.27",
|
|
57
57
|
"@storybook/preset-scss": "^1.0.3",
|
|
58
58
|
"@storybook/react": "^7.0.27",
|