@gravity-ui/dynamic-forms 4.5.0 → 4.7.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/CheckboxGroup/CheckboxGroup.css +18 -0
- package/build/cjs/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.js +40 -0
- package/build/cjs/lib/kit/components/Inputs/CheckboxGroup/index.js +4 -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/TimeRangeSelector/TimeRangeSelector.js +81 -0
- package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.css +6 -0
- package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.js +33 -0
- package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.js +4 -0
- package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/index.js +4 -0
- package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/index.js +4 -0
- package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/utils.js +26 -0
- package/build/cjs/lib/kit/components/Inputs/index.js +3 -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/CheckboxGroupView/CheckboxGroupView.css +27 -0
- package/build/cjs/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.js +19 -0
- package/build/cjs/lib/kit/components/Views/CheckboxGroupView/index.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/TimeRangeSelectorView/TimeRangeSelectorView.js +34 -0
- package/build/cjs/lib/kit/components/Views/TimeRangeSelectorView/index.js +4 -0
- package/build/cjs/lib/kit/components/Views/index.js +3 -0
- package/build/cjs/lib/kit/constants/common.js +3 -1
- package/build/cjs/lib/kit/constants/config.js +6 -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 +9 -0
- package/build/esm/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.css +18 -0
- package/build/esm/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.d.ts +6 -0
- package/build/esm/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.js +36 -0
- package/build/esm/lib/kit/components/Inputs/CheckboxGroup/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Inputs/CheckboxGroup/index.js +1 -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/TimeRangeSelector/TimeRangeSelector.d.ts +2 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/TimeRangeSelector.js +76 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.css +6 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.d.ts +14 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.js +29 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.js +1 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/index.js +1 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/index.js +1 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/utils.d.ts +15 -0
- package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/utils.js +20 -0
- package/build/esm/lib/kit/components/Inputs/index.d.ts +3 -0
- package/build/esm/lib/kit/components/Inputs/index.js +3 -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/CheckboxGroupView/CheckboxGroupView.css +27 -0
- package/build/esm/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.d.ts +3 -0
- package/build/esm/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.js +15 -0
- package/build/esm/lib/kit/components/Views/CheckboxGroupView/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Views/CheckboxGroupView/index.js +1 -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/TimeRangeSelectorView/TimeRangeSelectorView.d.ts +2 -0
- package/build/esm/lib/kit/components/Views/TimeRangeSelectorView/TimeRangeSelectorView.js +30 -0
- package/build/esm/lib/kit/components/Views/TimeRangeSelectorView/index.d.ts +1 -0
- package/build/esm/lib/kit/components/Views/TimeRangeSelectorView/index.js +1 -0
- package/build/esm/lib/kit/components/Views/index.d.ts +3 -0
- package/build/esm/lib/kit/components/Views/index.js +3 -0
- package/build/esm/lib/kit/constants/common.d.ts +2 -0
- package/build/esm/lib/kit/constants/common.js +2 -0
- package/build/esm/lib/kit/constants/config.js +7 -1
- package/package.json +3 -1
|
@@ -9,6 +9,7 @@ exports.dynamicConfig = {
|
|
|
9
9
|
select: { Component: components_1.MultiSelect },
|
|
10
10
|
table: { Component: components_1.TableArrayInput },
|
|
11
11
|
base: { Component: components_1.ArrayBase },
|
|
12
|
+
checkbox_group: { Component: components_1.CheckboxGroup },
|
|
12
13
|
},
|
|
13
14
|
layouts: {
|
|
14
15
|
row: components_1.Row,
|
|
@@ -69,6 +70,7 @@ exports.dynamicConfig = {
|
|
|
69
70
|
multi_oneof: { Component: components_1.MultiOneOf, independent: true },
|
|
70
71
|
multi_oneof_flat: { Component: components_1.MultiOneOfFlat, independent: true },
|
|
71
72
|
inline: { Component: components_1.ObjectInline, independent: true },
|
|
73
|
+
time_range_selector: { Component: components_1.TimeRangeSelector, independent: true },
|
|
72
74
|
},
|
|
73
75
|
layouts: {
|
|
74
76
|
row: components_1.Row,
|
|
@@ -94,6 +96,7 @@ exports.dynamicConfig = {
|
|
|
94
96
|
select: { Component: components_1.Select },
|
|
95
97
|
base: { Component: components_1.Text },
|
|
96
98
|
file_input: { Component: components_1.FileInput },
|
|
99
|
+
date_input: { Component: components_1.DateInput },
|
|
97
100
|
number_with_scale: { Component: components_1.NumberWithScale },
|
|
98
101
|
monaco_input: { Component: components_1.MonacoInput },
|
|
99
102
|
text_content: { Component: components_1.TextContent, independent: true },
|
|
@@ -121,6 +124,7 @@ exports.dynamicViewConfig = {
|
|
|
121
124
|
select: { Component: components_1.MultiSelectView },
|
|
122
125
|
table: { Component: components_1.TableArrayView },
|
|
123
126
|
base: { Component: components_1.ArrayBaseView },
|
|
127
|
+
checkbox_group: { Component: components_1.CheckboxGroupView },
|
|
124
128
|
},
|
|
125
129
|
layouts: {
|
|
126
130
|
row: components_1.ViewRow,
|
|
@@ -172,6 +176,7 @@ exports.dynamicViewConfig = {
|
|
|
172
176
|
multi_oneof: { Component: components_1.MultiOneOfView, independent: true },
|
|
173
177
|
multi_oneof_flat: { Component: components_1.MultiOneOfFlatView, independent: true },
|
|
174
178
|
inline: { Component: components_1.ObjectInlineView, independent: true },
|
|
179
|
+
time_range_selector: { Component: components_1.TimeRangeSelectorView, independent: true },
|
|
175
180
|
},
|
|
176
181
|
layouts: {
|
|
177
182
|
row: components_1.ViewRow,
|
|
@@ -193,6 +198,7 @@ exports.dynamicViewConfig = {
|
|
|
193
198
|
textarea: { Component: components_1.TextAreaView },
|
|
194
199
|
select: { Component: components_1.BaseView },
|
|
195
200
|
base: { Component: components_1.BaseView },
|
|
201
|
+
date_input: { Component: components_1.DateView },
|
|
196
202
|
file_input: { Component: components_1.FileInputView },
|
|
197
203
|
number_with_scale: { Component: components_1.NumberWithScaleView },
|
|
198
204
|
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;
|
|
@@ -35,6 +36,10 @@ export interface ArraySpec<LinkType = any, InputComponentProps extends Record<st
|
|
|
35
36
|
};
|
|
36
37
|
inputProps?: InputComponentProps;
|
|
37
38
|
layoutProps?: LayoutComponentProps;
|
|
39
|
+
checkboxGroupParams?: {
|
|
40
|
+
placement?: 'horizontal' | 'vertical';
|
|
41
|
+
disabled?: Record<string, boolean>;
|
|
42
|
+
};
|
|
38
43
|
};
|
|
39
44
|
}
|
|
40
45
|
export interface BooleanSpec<LinkType = any, InputComponentProps extends Record<string, any> | undefined = undefined, LayoutComponentProps extends Record<string, any> | undefined = undefined> {
|
|
@@ -150,6 +155,10 @@ export interface StringSpec<LinkType = any, InputComponentProps extends Record<s
|
|
|
150
155
|
readAsMethod?: ReadAsMethod;
|
|
151
156
|
ignoreText?: boolean;
|
|
152
157
|
};
|
|
158
|
+
dateInput?: {
|
|
159
|
+
outputFormat?: string;
|
|
160
|
+
printFormat?: string;
|
|
161
|
+
};
|
|
153
162
|
copy?: boolean;
|
|
154
163
|
selectParams?: {
|
|
155
164
|
filterPlaceholder?: string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.df-checkbox-group {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
height: 28px;
|
|
5
|
+
}
|
|
6
|
+
.df-checkbox-group > *:not(:last-child) {
|
|
7
|
+
margin-right: 6px;
|
|
8
|
+
}
|
|
9
|
+
.df-checkbox-group_vertical {
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
align-items: flex-start;
|
|
12
|
+
margin-top: 8px;
|
|
13
|
+
height: auto;
|
|
14
|
+
}
|
|
15
|
+
.df-checkbox-group_vertical > *:not(:last-child) {
|
|
16
|
+
margin-right: 0px;
|
|
17
|
+
margin-bottom: 6px;
|
|
18
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ArrayInput } from '../../../../core';
|
|
2
|
+
import { type CheckboxProps as CheckboxBaseProps } from '@gravity-ui/uikit';
|
|
3
|
+
import './CheckboxGroup.css';
|
|
4
|
+
export interface CheckboxGroupProps extends Omit<CheckboxBaseProps, 'checked' | 'onChange' | 'onBlur' | 'onFocus' | 'disabled' | 'qa' | 'content'> {
|
|
5
|
+
}
|
|
6
|
+
export declare const CheckboxGroup: ArrayInput<CheckboxGroupProps>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { transformArrIn, transformArrOut } from '../../../../core';
|
|
3
|
+
import { Checkbox } from '@gravity-ui/uikit';
|
|
4
|
+
import { block } from '../../../utils';
|
|
5
|
+
import './CheckboxGroup.css';
|
|
6
|
+
const b = block('checkbox-group');
|
|
7
|
+
export const CheckboxGroup = ({ name, input, spec, inputProps }) => {
|
|
8
|
+
var _a;
|
|
9
|
+
const { value, onBlur, onChange, onFocus } = input;
|
|
10
|
+
const _value = React.useMemo(() => transformArrOut(value), [value]);
|
|
11
|
+
const options = React.useMemo(() => {
|
|
12
|
+
var _a;
|
|
13
|
+
return (_a = spec.enum) === null || _a === void 0 ? void 0 : _a.map((id) => {
|
|
14
|
+
var _a;
|
|
15
|
+
return ({
|
|
16
|
+
value: id,
|
|
17
|
+
text: ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[id]) || id,
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}, [spec.enum, spec.description]);
|
|
21
|
+
const handleUpdate = React.useCallback((optionValue, selected) => {
|
|
22
|
+
let newValue = _value || [];
|
|
23
|
+
if (selected) {
|
|
24
|
+
newValue.push(optionValue);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
newValue = newValue.filter((id) => id !== optionValue);
|
|
28
|
+
}
|
|
29
|
+
onChange(transformArrIn(newValue));
|
|
30
|
+
}, [_value, onChange]);
|
|
31
|
+
return (React.createElement("div", { className: b({ vertical: ((_a = spec.viewSpec.checkboxGroupParams) === null || _a === void 0 ? void 0 : _a.placement) === 'vertical' }), "data-qa": name }, options === null || options === void 0 ? void 0 : options.map(({ value: optionValue, text }) => {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
return (React.createElement(Checkbox, Object.assign({}, inputProps, { qa: name && `${name}-${optionValue}`, key: optionValue, checked: _value === null || _value === void 0 ? void 0 : _value.includes(optionValue), onUpdate: (selected) => handleUpdate(optionValue, selected), disabled: spec.viewSpec.disabled ||
|
|
34
|
+
((_b = (_a = spec.viewSpec.checkboxGroupParams) === null || _a === void 0 ? void 0 : _a.disabled) === null || _b === void 0 ? void 0 : _b[optionValue]), content: text, onBlur: onBlur, onFocus: onFocus })));
|
|
35
|
+
})));
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CheckboxGroup';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CheckboxGroup';
|
|
@@ -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];
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Text } from '@gravity-ui/uikit';
|
|
3
|
+
import isString from 'lodash/isString';
|
|
4
|
+
import set from 'lodash/set';
|
|
5
|
+
import { isStringSpec, } from '../../../../core';
|
|
6
|
+
import { END_TIME, START_TIME } from '../../../constants/common';
|
|
7
|
+
import { TimeRangeSelect } from './components';
|
|
8
|
+
import { filterTimeArray, validateArray } from './utils';
|
|
9
|
+
export const TimeRangeSelector = (props) => {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const { spec, input, name, Layout } = props;
|
|
12
|
+
const [startTimeSpec, endTimeSpec] = React.useMemo(() => [START_TIME, END_TIME].map((key) => {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
return isStringSpec((_a = spec.properties) === null || _a === void 0 ? void 0 : _a[key])
|
|
15
|
+
? (_b = spec.properties) === null || _b === void 0 ? void 0 : _b[key]
|
|
16
|
+
: undefined;
|
|
17
|
+
}), [spec.properties]);
|
|
18
|
+
const { initialStartTimeOptions, initialEndTimeOptions, canBeFiltered } = React.useMemo(() => {
|
|
19
|
+
const [initialStartTimeOptions, initialEndTimeOptions] = [startTimeSpec, endTimeSpec].map((spec) => {
|
|
20
|
+
if (spec && spec.enum) {
|
|
21
|
+
return spec.enum.map((id) => {
|
|
22
|
+
var _a, _b, _c, _d;
|
|
23
|
+
return ({
|
|
24
|
+
id,
|
|
25
|
+
value: id,
|
|
26
|
+
content: ((_b = (_a = spec.viewSpec.selectParams) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b[id]) ? (React.createElement("div", { key: id },
|
|
27
|
+
React.createElement(Text, null, ((_c = spec.description) === null || _c === void 0 ? void 0 : _c[id]) || id),
|
|
28
|
+
React.createElement(Text, { color: "secondary", as: "div" }, spec.viewSpec.selectParams.meta[id]))) : (((_d = spec.description) === null || _d === void 0 ? void 0 : _d[id]) || id),
|
|
29
|
+
key: id,
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
});
|
|
35
|
+
const canBeFiltered = initialStartTimeOptions &&
|
|
36
|
+
initialEndTimeOptions &&
|
|
37
|
+
validateArray(initialStartTimeOptions) &&
|
|
38
|
+
validateArray(initialEndTimeOptions);
|
|
39
|
+
return {
|
|
40
|
+
initialStartTimeOptions,
|
|
41
|
+
initialEndTimeOptions,
|
|
42
|
+
canBeFiltered,
|
|
43
|
+
};
|
|
44
|
+
}, [endTimeSpec, startTimeSpec]);
|
|
45
|
+
const { startTimeOptions, endTimeOptions } = React.useMemo(() => {
|
|
46
|
+
let startTimeOptions = initialStartTimeOptions;
|
|
47
|
+
let endTimeOptions = initialEndTimeOptions;
|
|
48
|
+
[START_TIME, END_TIME].forEach((key) => {
|
|
49
|
+
var _a;
|
|
50
|
+
const time = (_a = input.value) === null || _a === void 0 ? void 0 : _a[key];
|
|
51
|
+
if (isString(time) &&
|
|
52
|
+
canBeFiltered &&
|
|
53
|
+
initialEndTimeOptions &&
|
|
54
|
+
initialStartTimeOptions) {
|
|
55
|
+
if (START_TIME === key) {
|
|
56
|
+
endTimeOptions = filterTimeArray(initialEndTimeOptions, time, 'greater');
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
startTimeOptions = filterTimeArray(initialStartTimeOptions, time, 'less');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return { startTimeOptions, endTimeOptions };
|
|
64
|
+
}, [canBeFiltered, initialEndTimeOptions, initialStartTimeOptions, input.value]);
|
|
65
|
+
const parentOnChange = React.useCallback((childName, childValue, childErrors) => input.onChange((currentValue) => set(Object.assign({}, currentValue), childName.split(`${name}.`).join(''), childValue), childErrors), [input, name]);
|
|
66
|
+
if (!startTimeSpec || !endTimeSpec || !startTimeOptions || !endTimeOptions) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const content = (React.createElement(React.Fragment, null,
|
|
70
|
+
React.createElement(TimeRangeSelect, { spec: startTimeSpec, name: `${name}.${START_TIME}`, options: startTimeOptions, value: (_a = input.value) === null || _a === void 0 ? void 0 : _a[START_TIME], handleChange: (value) => parentOnChange(START_TIME, value[0]), props: props }),
|
|
71
|
+
React.createElement(TimeRangeSelect, { spec: endTimeSpec, name: `${name}.${END_TIME}`, options: endTimeOptions, value: (_b = input.value) === null || _b === void 0 ? void 0 : _b[END_TIME], handleChange: (value) => parentOnChange(END_TIME, value[0]), props: props })));
|
|
72
|
+
if (Layout) {
|
|
73
|
+
return React.createElement(Layout, Object.assign({}, props), content);
|
|
74
|
+
}
|
|
75
|
+
return React.createElement(React.Fragment, null, content);
|
|
76
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type SelectOption } from '@gravity-ui/uikit';
|
|
3
|
+
import { FieldObjectValue, FieldValue, IndependentInputProps, ObjectSpec, StringSpec } from '../../../../../../core';
|
|
4
|
+
import './TimeRangeSelect.css';
|
|
5
|
+
interface TimeRangeSelectProps {
|
|
6
|
+
spec: StringSpec<any, undefined, undefined>;
|
|
7
|
+
name: string;
|
|
8
|
+
options: SelectOption<string>[];
|
|
9
|
+
value?: FieldValue;
|
|
10
|
+
handleChange: (value: string[]) => void;
|
|
11
|
+
props: IndependentInputProps<FieldObjectValue, undefined, undefined, ObjectSpec<undefined, undefined, undefined>>;
|
|
12
|
+
}
|
|
13
|
+
export declare const TimeRangeSelect: React.FC<TimeRangeSelectProps>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import isString from 'lodash/isString';
|
|
3
|
+
import { Select } from '@gravity-ui/uikit';
|
|
4
|
+
import { block } from '../../../../../utils';
|
|
5
|
+
import { Row } from '../../../../Layouts/Row';
|
|
6
|
+
import './TimeRangeSelect.css';
|
|
7
|
+
const b = block('time-range-select');
|
|
8
|
+
export const TimeRangeSelect = ({ name, spec, options, value, props, handleChange, }) => {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
const filterable = React.useMemo(() => ((options === null || options === void 0 ? void 0 : options.length) || 0) > 9, [options === null || options === void 0 ? void 0 : options.length]);
|
|
11
|
+
const _value = React.useMemo(() => {
|
|
12
|
+
if (isString(value)) {
|
|
13
|
+
return [value];
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}, [value]);
|
|
17
|
+
const renderOption = React.useCallback((option) => {
|
|
18
|
+
return React.createElement(React.Fragment, { key: option.value }, option.content || option.value);
|
|
19
|
+
}, []);
|
|
20
|
+
const getOptionHeight = React.useCallback(() => {
|
|
21
|
+
var _a;
|
|
22
|
+
if ((_a = spec.viewSpec.selectParams) === null || _a === void 0 ? void 0 : _a.meta) {
|
|
23
|
+
return 44;
|
|
24
|
+
}
|
|
25
|
+
return 28;
|
|
26
|
+
}, [(_a = spec.viewSpec.selectParams) === null || _a === void 0 ? void 0 : _a.meta]);
|
|
27
|
+
return (React.createElement(Row, Object.assign({}, Object.assign(Object.assign({}, props), { spec })),
|
|
28
|
+
React.createElement(Select, { className: b('select'), filterable: filterable, value: _value, options: options, onUpdate: handleChange, disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, filterPlaceholder: (_b = spec.viewSpec.selectParams) === null || _b === void 0 ? void 0 : _b.filterPlaceholder, renderOption: renderOption, getOptionHeight: getOptionHeight, qa: name, popupClassName: b('select-popup') })));
|
|
29
|
+
};
|
package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimeRangeSelect';
|
package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimeRangeSelect';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimeRangeSelect';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimeRangeSelect';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimeRangeSelector';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimeRangeSelector';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const filterTimeArray: (times: {
|
|
2
|
+
id: string;
|
|
3
|
+
value: string;
|
|
4
|
+
content: string | JSX.Element;
|
|
5
|
+
key: string;
|
|
6
|
+
}[], cutoff: string, direction: 'greater' | 'less') => {
|
|
7
|
+
content: string | JSX.Element;
|
|
8
|
+
disabled: boolean;
|
|
9
|
+
id: string;
|
|
10
|
+
value: string;
|
|
11
|
+
key: string;
|
|
12
|
+
}[];
|
|
13
|
+
export declare const validateArray: (arr: {
|
|
14
|
+
value: string;
|
|
15
|
+
}[]) => boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Text } from '@gravity-ui/uikit';
|
|
3
|
+
export const filterTimeArray = (times, cutoff, direction) => {
|
|
4
|
+
const isTimeFormat = (value) => /^\d{1,2}:\d{2}$/.test(value);
|
|
5
|
+
const compareValues = (a, b) => {
|
|
6
|
+
if (isTimeFormat(a) && isTimeFormat(b)) {
|
|
7
|
+
return direction === 'less' ? a >= b : a <= b;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
const aNum = parseInt(a, 10);
|
|
11
|
+
const bNum = parseInt(b, 10);
|
|
12
|
+
return direction === 'less' ? aNum >= bNum : aNum <= bNum;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
return times.map((time) => {
|
|
16
|
+
const disabled = compareValues(time.value, cutoff);
|
|
17
|
+
return Object.assign(Object.assign({}, time), { content: disabled ? React.createElement(Text, { color: "secondary" }, time.content) : time.content, disabled });
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
export const validateArray = (arr) => arr.every((obj) => /^(\d+|\d{1,2}:\d{1,2})$/.test(obj.value));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './ArrayBase';
|
|
2
2
|
export * from './CardOneOf';
|
|
3
3
|
export * from './Checkbox';
|
|
4
|
+
export * from './CheckboxGroup';
|
|
4
5
|
export * from './FileInput';
|
|
6
|
+
export * from './DateInput';
|
|
5
7
|
export * from './MonacoInput';
|
|
6
8
|
export * from './MultiOneOf';
|
|
7
9
|
export * from './MultiSelect';
|
|
@@ -17,3 +19,4 @@ export * from './Text';
|
|
|
17
19
|
export * from './TextArea';
|
|
18
20
|
export * from './TextContent';
|
|
19
21
|
export * from './TextLink';
|
|
22
|
+
export * from './TimeRangeSelector';
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export * from './ArrayBase';
|
|
2
2
|
export * from './CardOneOf';
|
|
3
3
|
export * from './Checkbox';
|
|
4
|
+
export * from './CheckboxGroup';
|
|
4
5
|
export * from './FileInput';
|
|
6
|
+
export * from './DateInput';
|
|
5
7
|
export * from './MonacoInput';
|
|
6
8
|
export * from './MultiOneOf';
|
|
7
9
|
export * from './MultiSelect';
|
|
@@ -17,3 +19,4 @@ export * from './Text';
|
|
|
17
19
|
export * from './TextArea';
|
|
18
20
|
export * from './TextContent';
|
|
19
21
|
export * from './TextLink';
|
|
22
|
+
export * from './TimeRangeSelector';
|
|
@@ -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,27 @@
|
|
|
1
|
+
.df-checkbox-group-view {
|
|
2
|
+
display: flex;
|
|
3
|
+
}
|
|
4
|
+
.df-checkbox-group-view > *:not(:last-child) {
|
|
5
|
+
margin-right: 6px;
|
|
6
|
+
}
|
|
7
|
+
.df-checkbox-group-view_vertical {
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
}
|
|
11
|
+
.df-checkbox-group-view_vertical > *:not(:last-child) {
|
|
12
|
+
margin-right: 0px;
|
|
13
|
+
margin-bottom: 6px;
|
|
14
|
+
}
|
|
15
|
+
.df-checkbox-group-view__tooltip {
|
|
16
|
+
overflow-wrap: break-word;
|
|
17
|
+
}
|
|
18
|
+
.df-checkbox-group-view__tooltip-container {
|
|
19
|
+
max-width: 100%;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
text-overflow: ellipsis;
|
|
22
|
+
display: block;
|
|
23
|
+
margin-bottom: 6px;
|
|
24
|
+
}
|
|
25
|
+
.df-checkbox-group-view__tooltip-container:last-child {
|
|
26
|
+
margin-bottom: 0;
|
|
27
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Popover } from '@gravity-ui/uikit';
|
|
3
|
+
import { COMMON_POPOVER_PLACEMENT } from '../../../constants/common';
|
|
4
|
+
import { block } from '../../../utils';
|
|
5
|
+
import './CheckboxGroupView.css';
|
|
6
|
+
const b = block('checkbox-group-view');
|
|
7
|
+
export const CheckboxGroupView = ({ spec, value = [] }) => {
|
|
8
|
+
var _a;
|
|
9
|
+
const _value = value;
|
|
10
|
+
const items = React.useMemo(() => _value.map((item) => { var _a; return ((_a = spec.description) === null || _a === void 0 ? void 0 : _a[item]) || item; }), [spec.description, _value]);
|
|
11
|
+
const verticalPlacement = React.useMemo(() => { var _a; return ((_a = spec.viewSpec.checkboxGroupParams) === null || _a === void 0 ? void 0 : _a.placement) === 'vertical'; }, [(_a = spec.viewSpec.checkboxGroupParams) === null || _a === void 0 ? void 0 : _a.placement]);
|
|
12
|
+
return (React.createElement("div", { className: b({ vertical: verticalPlacement }) }, items.map((item, idx) => (React.createElement(Popover, { placement: COMMON_POPOVER_PLACEMENT, key: item, content: item, className: b('tooltip-container'), contentClassName: b('tooltip'), disabled: item.length < 51 },
|
|
13
|
+
item,
|
|
14
|
+
!verticalPlacement && idx !== items.length - 1 ? ', ' : null)))));
|
|
15
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CheckboxGroupView';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CheckboxGroupView';
|