Skip to content

Commit 2acde25

Browse files
authored
feat(TimeRangeSelector): added new input Time Range Selector (#216)
1 parent 075e48b commit 2acde25

File tree

38 files changed

+771
-0
lines changed

38 files changed

+771
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import React from 'react';
2+
3+
import {Text} from '@gravity-ui/uikit';
4+
5+
import isString from 'lodash/isString';
6+
import set from 'lodash/set';
7+
8+
import {
9+
FieldValue,
10+
ObjectIndependentInput,
11+
StringSpec,
12+
ValidateError,
13+
isStringSpec,
14+
} from '../../../../core';
15+
import {END_TIME, START_TIME} from '../../../constants/common';
16+
17+
import {TimeRangeSelect} from './components';
18+
import {filterTimeArray, validateArray} from './utils';
19+
20+
export const TimeRangeSelector: ObjectIndependentInput = (props) => {
21+
const {spec, input, name, Layout} = props;
22+
23+
const [startTimeSpec, endTimeSpec] = React.useMemo(
24+
() =>
25+
[START_TIME, END_TIME].map((key) =>
26+
isStringSpec(spec.properties?.[key])
27+
? (spec.properties?.[key] as StringSpec<any, undefined, undefined>)
28+
: undefined,
29+
),
30+
[spec.properties],
31+
);
32+
33+
const {initialStartTimeOptions, initialEndTimeOptions, canBeFiltered} = React.useMemo(() => {
34+
const [initialStartTimeOptions, initialEndTimeOptions] = [startTimeSpec, endTimeSpec].map(
35+
(spec) => {
36+
if (spec && spec.enum) {
37+
return spec.enum.map((id) => ({
38+
id,
39+
value: id,
40+
content: spec.viewSpec.selectParams?.meta?.[id] ? (
41+
<div key={id}>
42+
<Text>{spec.description?.[id] || id}</Text>
43+
<Text color="secondary" as="div">
44+
{spec.viewSpec.selectParams.meta[id]}
45+
</Text>
46+
</div>
47+
) : (
48+
spec.description?.[id] || id
49+
),
50+
key: id,
51+
}));
52+
}
53+
54+
return undefined;
55+
},
56+
);
57+
58+
const canBeFiltered =
59+
initialStartTimeOptions &&
60+
initialEndTimeOptions &&
61+
validateArray(initialStartTimeOptions) &&
62+
validateArray(initialEndTimeOptions);
63+
64+
return {
65+
initialStartTimeOptions,
66+
initialEndTimeOptions,
67+
canBeFiltered,
68+
};
69+
}, [endTimeSpec, startTimeSpec]);
70+
71+
const {startTimeOptions, endTimeOptions} = React.useMemo(() => {
72+
let startTimeOptions = initialStartTimeOptions;
73+
let endTimeOptions = initialEndTimeOptions;
74+
75+
[START_TIME, END_TIME].forEach((key) => {
76+
const time = input.value?.[key];
77+
78+
if (
79+
isString(time) &&
80+
canBeFiltered &&
81+
initialEndTimeOptions &&
82+
initialStartTimeOptions
83+
) {
84+
if (START_TIME === key) {
85+
endTimeOptions = filterTimeArray(initialEndTimeOptions, time, 'greater');
86+
} else {
87+
startTimeOptions = filterTimeArray(initialStartTimeOptions, time, 'less');
88+
}
89+
}
90+
});
91+
92+
return {startTimeOptions, endTimeOptions};
93+
}, [canBeFiltered, initialEndTimeOptions, initialStartTimeOptions, input.value]);
94+
95+
const parentOnChange = React.useCallback(
96+
(childName: string, childValue: FieldValue, childErrors?: Record<string, ValidateError>) =>
97+
input.onChange(
98+
(currentValue) =>
99+
set({...currentValue}, childName.split(`${name}.`).join(''), childValue),
100+
childErrors,
101+
),
102+
[input, name],
103+
);
104+
105+
if (!startTimeSpec || !endTimeSpec || !startTimeOptions || !endTimeOptions) {
106+
return null;
107+
}
108+
109+
const content = (
110+
<React.Fragment>
111+
<TimeRangeSelect
112+
spec={startTimeSpec}
113+
name={`${name}.${START_TIME}`}
114+
options={startTimeOptions}
115+
value={input.value?.[START_TIME]}
116+
handleChange={(value) => parentOnChange(START_TIME, value[0])}
117+
props={props}
118+
/>
119+
<TimeRangeSelect
120+
spec={endTimeSpec}
121+
name={`${name}.${END_TIME}`}
122+
options={endTimeOptions}
123+
value={input.value?.[END_TIME]}
124+
handleChange={(value) => parentOnChange(END_TIME, value[0])}
125+
props={props}
126+
/>
127+
</React.Fragment>
128+
);
129+
130+
if (Layout) {
131+
return <Layout {...props}>{content}</Layout>;
132+
}
133+
134+
return <React.Fragment>{content}</React.Fragment>;
135+
};
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)