Загрузка данных
import { memo, useRef, useState } from 'react';
import { Flex, InputText, Select } from 'exchange-elements/v2';
import { MaIndicatorSettings, MaSource } from '@src/core/Indicators/settings';
import styles from './index.module.scss';
interface IndicatorSettingsModalProps {
settings: MaIndicatorSettings;
onSettingsChange?: (settings: MaIndicatorSettings) => void;
}
interface IndicatorNumberFieldProps {
label: string;
initialValue: string;
onValueChange: (value: string) => void;
allowNegative?: boolean;
}
const sourceOptions: { label: string; value: MaSource }[] = [
{ label: 'Цена открытия', value: 'open' },
{ label: 'Максимум', value: 'high' },
{ label: 'Минимум', value: 'low' },
{ label: 'Цена закрытия', value: 'close' },
];
const IndicatorNumberField = memo(function IndicatorNumberField({
label,
initialValue,
onValueChange,
allowNegative = false,
}: IndicatorNumberFieldProps) {
const [value, setValue] = useState(initialValue);
return (
<InputText
className={styles.input}
value={value}
onChange={(event) => {
const rawValue = event.currentTarget.value;
const nextValue = allowNegative ? rawValue.replace(/[^\d-]/g, '') : rawValue.replace(/[^\d]/g, '');
setValue(nextValue);
onValueChange(nextValue);
}}
label={label}
labelPos="top"
size="sm"
/>
);
});
interface IndicatorSourceFieldProps {
initialValue: MaSource;
onValueChange: (value: MaSource) => void;
}
const IndicatorSourceField = memo(function IndicatorSourceField({
initialValue,
onValueChange,
}: IndicatorSourceFieldProps) {
const [value, setValue] = useState<MaSource>(initialValue);
return (
<Select
classNames={{ dropdown: styles.dropdown, input: styles.input_wrapper }}
value={value}
onChange={(nextSource: MaSource) => {
setValue(nextSource);
onValueChange(nextSource);
}}
options={sourceOptions}
label="Данные"
labelPos="top"
size="sm"
/>
);
});
export function IndicatorSettingsModal({ settings, onSettingsChange }: IndicatorSettingsModalProps) {
const draftSettingsRef = useRef<MaIndicatorSettings>({ ...settings });
const emitSettingsChange = (): void => {
onSettingsChange?.({ ...draftSettingsRef.current });
};
return (
<Flex
direction="column"
divider={null}
spacing="0500"
wrap="nowrap"
>
<IndicatorNumberField
label="Длина"
initialValue={String(settings.length)}
onValueChange={(nextLengthValue) => {
const nextLength = Number(nextLengthValue);
draftSettingsRef.current = {
...draftSettingsRef.current,
length: Number.isFinite(nextLength) && nextLength > 0 ? nextLength : 1,
};
emitSettingsChange();
}}
/>
<IndicatorSourceField
initialValue={settings.source}
onValueChange={(nextSource) => {
draftSettingsRef.current = {
...draftSettingsRef.current,
source: nextSource,
};
emitSettingsChange();
}}
/>
<IndicatorNumberField
label="Отступ"
initialValue={String(settings.offset)}
allowNegative
onValueChange={(nextOffsetValue) => {
const nextOffset = Number(nextOffsetValue);
draftSettingsRef.current = {
...draftSettingsRef.current,
offset: Number.isFinite(nextOffset) ? nextOffset : 0,
};
emitSettingsChange();
}}
/>
</Flex>
);
}