@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.
Files changed (86) hide show
  1. package/build/cjs/lib/core/components/View/DynamicView.js +8 -2
  2. package/build/cjs/lib/core/components/View/index.js +3 -0
  3. package/build/cjs/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.css +18 -0
  4. package/build/cjs/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.js +40 -0
  5. package/build/cjs/lib/kit/components/Inputs/CheckboxGroup/index.js +4 -0
  6. package/build/cjs/lib/kit/components/Inputs/DateInput/DateInput.css +3 -0
  7. package/build/cjs/lib/kit/components/Inputs/DateInput/DateInput.js +50 -0
  8. package/build/cjs/lib/kit/components/Inputs/DateInput/index.js +4 -0
  9. package/build/cjs/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.js +7 -2
  10. package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/TimeRangeSelector.js +81 -0
  11. package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.css +6 -0
  12. package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.js +33 -0
  13. package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.js +4 -0
  14. package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/components/index.js +4 -0
  15. package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/index.js +4 -0
  16. package/build/cjs/lib/kit/components/Inputs/TimeRangeSelector/utils.js +26 -0
  17. package/build/cjs/lib/kit/components/Inputs/index.js +3 -0
  18. package/build/cjs/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.js +5 -1
  19. package/build/cjs/lib/kit/components/ViewLayouts/ViewRow/ViewRow.css +3 -0
  20. package/build/cjs/lib/kit/components/ViewLayouts/ViewRow/ViewRow.js +4 -0
  21. package/build/cjs/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.css +27 -0
  22. package/build/cjs/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.js +19 -0
  23. package/build/cjs/lib/kit/components/Views/CheckboxGroupView/index.js +4 -0
  24. package/build/cjs/lib/kit/components/Views/DateView/DateView.js +22 -0
  25. package/build/cjs/lib/kit/components/Views/DateView/index.js +4 -0
  26. package/build/cjs/lib/kit/components/Views/TableArrayView/TableArrayView.js +9 -3
  27. package/build/cjs/lib/kit/components/Views/TimeRangeSelectorView/TimeRangeSelectorView.js +34 -0
  28. package/build/cjs/lib/kit/components/Views/TimeRangeSelectorView/index.js +4 -0
  29. package/build/cjs/lib/kit/components/Views/index.js +3 -0
  30. package/build/cjs/lib/kit/constants/common.js +3 -1
  31. package/build/cjs/lib/kit/constants/config.js +6 -0
  32. package/build/esm/lib/core/components/View/DynamicView.d.ts +2 -1
  33. package/build/esm/lib/core/components/View/DynamicView.js +8 -2
  34. package/build/esm/lib/core/components/View/index.d.ts +1 -0
  35. package/build/esm/lib/core/components/View/index.js +1 -0
  36. package/build/esm/lib/core/components/View/types/context.d.ts +1 -0
  37. package/build/esm/lib/core/types/specs.d.ts +9 -0
  38. package/build/esm/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.css +18 -0
  39. package/build/esm/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.d.ts +6 -0
  40. package/build/esm/lib/kit/components/Inputs/CheckboxGroup/CheckboxGroup.js +36 -0
  41. package/build/esm/lib/kit/components/Inputs/CheckboxGroup/index.d.ts +1 -0
  42. package/build/esm/lib/kit/components/Inputs/CheckboxGroup/index.js +1 -0
  43. package/build/esm/lib/kit/components/Inputs/DateInput/DateInput.css +3 -0
  44. package/build/esm/lib/kit/components/Inputs/DateInput/DateInput.d.ts +9 -0
  45. package/build/esm/lib/kit/components/Inputs/DateInput/DateInput.js +46 -0
  46. package/build/esm/lib/kit/components/Inputs/DateInput/index.d.ts +1 -0
  47. package/build/esm/lib/kit/components/Inputs/DateInput/index.js +1 -0
  48. package/build/esm/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.js +8 -3
  49. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/TimeRangeSelector.d.ts +2 -0
  50. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/TimeRangeSelector.js +76 -0
  51. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.css +6 -0
  52. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.d.ts +14 -0
  53. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/TimeRangeSelect.js +29 -0
  54. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.d.ts +1 -0
  55. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/TimeRangeSelect/index.js +1 -0
  56. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/index.d.ts +1 -0
  57. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/components/index.js +1 -0
  58. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/index.d.ts +1 -0
  59. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/index.js +1 -0
  60. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/utils.d.ts +15 -0
  61. package/build/esm/lib/kit/components/Inputs/TimeRangeSelector/utils.js +20 -0
  62. package/build/esm/lib/kit/components/Inputs/index.d.ts +3 -0
  63. package/build/esm/lib/kit/components/Inputs/index.js +3 -0
  64. package/build/esm/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.js +5 -1
  65. package/build/esm/lib/kit/components/ViewLayouts/ViewRow/ViewRow.css +3 -0
  66. package/build/esm/lib/kit/components/ViewLayouts/ViewRow/ViewRow.js +4 -0
  67. package/build/esm/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.css +27 -0
  68. package/build/esm/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.d.ts +3 -0
  69. package/build/esm/lib/kit/components/Views/CheckboxGroupView/CheckboxGroupView.js +15 -0
  70. package/build/esm/lib/kit/components/Views/CheckboxGroupView/index.d.ts +1 -0
  71. package/build/esm/lib/kit/components/Views/CheckboxGroupView/index.js +1 -0
  72. package/build/esm/lib/kit/components/Views/DateView/DateView.d.ts +3 -0
  73. package/build/esm/lib/kit/components/Views/DateView/DateView.js +18 -0
  74. package/build/esm/lib/kit/components/Views/DateView/index.d.ts +1 -0
  75. package/build/esm/lib/kit/components/Views/DateView/index.js +1 -0
  76. package/build/esm/lib/kit/components/Views/TableArrayView/TableArrayView.js +11 -5
  77. package/build/esm/lib/kit/components/Views/TimeRangeSelectorView/TimeRangeSelectorView.d.ts +2 -0
  78. package/build/esm/lib/kit/components/Views/TimeRangeSelectorView/TimeRangeSelectorView.js +30 -0
  79. package/build/esm/lib/kit/components/Views/TimeRangeSelectorView/index.d.ts +1 -0
  80. package/build/esm/lib/kit/components/Views/TimeRangeSelectorView/index.js +1 -0
  81. package/build/esm/lib/kit/components/Views/index.d.ts +3 -0
  82. package/build/esm/lib/kit/components/Views/index.js +3 -0
  83. package/build/esm/lib/kit/constants/common.d.ts +2 -0
  84. package/build/esm/lib/kit/constants/common.js +2 -0
  85. package/build/esm/lib/kit/constants/config.js +7 -1
  86. 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(() => ({ config, value, Link, Monaco: isValidElementType(Monaco) ? Monaco : undefined }), [config, value, Link, Monaco]);
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: "" })));
@@ -2,3 +2,4 @@ export * from './DynamicView';
2
2
  export * from './ViewController';
3
3
  export * from './helpers';
4
4
  export * from './types';
5
+ export { useDynamicFormsCtx } from './hooks';
@@ -2,3 +2,4 @@ export * from './DynamicView';
2
2
  export * from './ViewController';
3
3
  export * from './helpers';
4
4
  export * from './types';
5
+ export { useDynamicFormsCtx } from './hooks';
@@ -5,6 +5,7 @@ import { DynamicViewConfig } from './';
5
5
  export interface DynamicViewContext {
6
6
  config: DynamicViewConfig;
7
7
  value: FormValue;
8
+ showLayoutDescription?: boolean;
8
9
  Link?: React.ComponentType<{
9
10
  value: FormValue;
10
11
  link: Spec['viewSpec']['link'];
@@ -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,3 @@
1
+ .df-date-input {
2
+ width: 100%;
3
+ }
@@ -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: label,
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,2 @@
1
+ import { ObjectIndependentInput } from '../../../../core';
2
+ export declare const TimeRangeSelector: ObjectIndependentInput;
@@ -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,6 @@
1
+ .df-time-range-select__select {
2
+ min-width: 100px;
3
+ }
4
+ .df-time-range-select__select-popup {
5
+ max-height: 250px;
6
+ }
@@ -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
+ };
@@ -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 || '', open: open, onOpenChange: setOpen, hideInsteadOfDestroy: true, withBranchView: true, viewLayout: true }, children));
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
  };
@@ -14,6 +14,9 @@
14
14
  align-items: baseline;
15
15
  overflow: hidden;
16
16
  }
17
+ .df-view-row__note {
18
+ margin-inline-start: var(--g-spacing-half);
19
+ }
17
20
  .df-view-row__dots {
18
21
  min-width: 40px;
19
22
  flex-grow: 1;
@@ -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,3 @@
1
+ import { ArrayView } from '../../../../core';
2
+ import './CheckboxGroupView.css';
3
+ export declare const CheckboxGroupView: ArrayView;
@@ -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';
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { StringViewProps } from '../../../../core';
3
+ export declare const DateView: React.FC<StringViewProps>;