Components: add basic input elements
This commit is contained in:
parent
d7f78af557
commit
5a23baa86c
30
Components/Calculation/builders/build-options.tsx
Normal file
30
Components/Calculation/builders/build-options.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useOptions } from 'stores/calculation/options/hooks';
|
||||
import { useStatus } from 'stores/calculation/statuses/hooks';
|
||||
import { useValidation } from 'stores/calculation/validation/hooks';
|
||||
import { useValue } from 'stores/calculation/values/hooks';
|
||||
import { getValueName } from '../config/map';
|
||||
import type { BuilderProps } from './types';
|
||||
|
||||
export default function buildValueElement({ elementName, Component, ...props }: BuilderProps) {
|
||||
const valueName = getValueName(elementName);
|
||||
|
||||
return observer(() => {
|
||||
const { value, setValue } = useValue(valueName);
|
||||
const { status } = useStatus(elementName);
|
||||
const { isValid, help } = useValidation(elementName);
|
||||
const { options } = useOptions(elementName);
|
||||
|
||||
return (
|
||||
<Component
|
||||
value={value}
|
||||
setValue={setValue}
|
||||
options={options}
|
||||
status={status}
|
||||
isValid={isValid}
|
||||
help={help}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
14
Components/Calculation/builders/build-readonly.tsx
Normal file
14
Components/Calculation/builders/build-readonly.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useValue } from 'stores/calculation/values/hooks';
|
||||
import { getValueName } from '../config/map';
|
||||
import type { BuilderProps } from './types';
|
||||
|
||||
export default function buildValueElement({ elementName, Component, ...props }: BuilderProps) {
|
||||
const valueName = getValueName(elementName);
|
||||
|
||||
return observer(() => {
|
||||
const { value } = useValue(valueName);
|
||||
|
||||
return <Component value={value} {...props} />;
|
||||
});
|
||||
}
|
||||
27
Components/Calculation/builders/build-value.tsx
Normal file
27
Components/Calculation/builders/build-value.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStatus } from 'stores/calculation/statuses/hooks';
|
||||
import { useValidation } from 'stores/calculation/validation/hooks';
|
||||
import { useValue } from 'stores/calculation/values/hooks';
|
||||
import { getValueName } from '../config/map';
|
||||
import type { BuilderProps } from './types';
|
||||
|
||||
export default function buildValueElement({ elementName, Component, ...props }: BuilderProps) {
|
||||
const valueName = getValueName(elementName);
|
||||
|
||||
return observer(() => {
|
||||
const { value, setValue } = useValue(valueName);
|
||||
const { status } = useStatus(elementName);
|
||||
const { isValid, help } = useValidation(elementName);
|
||||
|
||||
return (
|
||||
<Component
|
||||
value={value}
|
||||
setValue={setValue}
|
||||
status={status}
|
||||
isValid={isValid}
|
||||
help={help}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
8
Components/Calculation/builders/types.ts
Normal file
8
Components/Calculation/builders/types.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import type { FC } from 'react';
|
||||
import type { Elements } from '../config/map';
|
||||
|
||||
export interface BuilderProps {
|
||||
elementName: Elements;
|
||||
Component: FC<any>;
|
||||
style: React.CSSProperties;
|
||||
}
|
||||
27
Elements/Checkbox.tsx
Normal file
27
Elements/Checkbox.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import type { CheckboxProps } from 'antd';
|
||||
import { Checkbox, Form } from 'antd';
|
||||
import type { BaseElementProps } from './types';
|
||||
|
||||
const { Item: FormItem } = Form;
|
||||
|
||||
export default function Element({
|
||||
value,
|
||||
setValue,
|
||||
status,
|
||||
isValid,
|
||||
help,
|
||||
...props
|
||||
}: BaseElementProps<boolean>) {
|
||||
return (
|
||||
<FormItem hasFeedback validateStatus={isValid === false ? 'error' : ''} help={help}>
|
||||
<Checkbox
|
||||
checked={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
disabled={status === 'Disabled'}
|
||||
{...props}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
|
||||
export type { CheckboxProps };
|
||||
27
Elements/Input.tsx
Normal file
27
Elements/Input.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import type { InputProps } from 'antd';
|
||||
import { Form, Input } from 'antd';
|
||||
import type { BaseElementProps } from './types';
|
||||
|
||||
const { Item: FormItem } = Form;
|
||||
|
||||
export default function Element({
|
||||
value,
|
||||
setValue,
|
||||
status,
|
||||
isValid,
|
||||
help,
|
||||
...props
|
||||
}: BaseElementProps<string>) {
|
||||
return (
|
||||
<FormItem hasFeedback validateStatus={isValid === false ? 'error' : ''} help={help}>
|
||||
<Input
|
||||
defaultValue={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
disabled={status === 'Disabled'}
|
||||
{...props}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
|
||||
export type { InputProps };
|
||||
34
Elements/InputNumber.tsx
Normal file
34
Elements/InputNumber.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import type { InputNumberProps } from 'antd';
|
||||
import { Form, InputNumber } from 'antd';
|
||||
import type { BaseElementProps } from './types';
|
||||
|
||||
const { Item: FormItem } = Form;
|
||||
|
||||
const parser = (val?: string): number => {
|
||||
const res = val?.replace(/[^0-9.,]+/, '');
|
||||
if (!res || res === '') return 0;
|
||||
return parseFloat(res);
|
||||
};
|
||||
|
||||
export default function Element({
|
||||
value = 0,
|
||||
setValue,
|
||||
status,
|
||||
isValid,
|
||||
help,
|
||||
...props
|
||||
}: BaseElementProps<number>) {
|
||||
return (
|
||||
<FormItem hasFeedback validateStatus={isValid === false ? 'error' : ''} help={help}>
|
||||
<InputNumber
|
||||
defaultValue={value}
|
||||
onChange={(val) => setValue(val)}
|
||||
disabled={status === 'Disabled'}
|
||||
parser={parser}
|
||||
{...props}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
|
||||
export type { InputNumberProps };
|
||||
20
Elements/Link.tsx
Normal file
20
Elements/Link.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import DownloadOutlined from '@ant-design/icons/lib/icons/DownloadOutlined';
|
||||
import type { ButtonProps } from 'antd';
|
||||
import { Button } from 'antd';
|
||||
import type { BaseElementProps } from './types';
|
||||
|
||||
export default function Element({ value, setValue, status, ...props }: BaseElementProps<string>) {
|
||||
return (
|
||||
<Button
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
href={value}
|
||||
disabled={status === 'Disabled'}
|
||||
loading={status === 'Loading'}
|
||||
icon={<DownloadOutlined />}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export type { ButtonProps as LinkProps };
|
||||
33
Elements/Radio.tsx
Normal file
33
Elements/Radio.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import type { RadioProps } from 'antd';
|
||||
import { Form, Radio } from 'antd';
|
||||
import type { BaseElementProps, BaseOption } from './types';
|
||||
|
||||
const { Item: FormItem } = Form;
|
||||
|
||||
type ElementProps = BaseElementProps<string | null> & {
|
||||
options: BaseOption[];
|
||||
};
|
||||
|
||||
export default function Element({
|
||||
value = null,
|
||||
setValue,
|
||||
options,
|
||||
status,
|
||||
isValid,
|
||||
help,
|
||||
...props
|
||||
}: ElementProps) {
|
||||
return (
|
||||
<FormItem hasFeedback validateStatus={isValid === false ? 'error' : ''} help={help}>
|
||||
<Radio.Group
|
||||
defaultValue={value}
|
||||
options={options}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
disabled={status === 'Disabled'}
|
||||
{...props}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
|
||||
export type { RadioProps };
|
||||
40
Elements/Select.tsx
Normal file
40
Elements/Select.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import type { SelectProps } from 'antd';
|
||||
import { Form, Select } from 'antd';
|
||||
import type { BaseElementProps, BaseOption } from './types';
|
||||
|
||||
const { Item: FormItem } = Form;
|
||||
|
||||
type ElementProps = BaseElementProps<string | null> & {
|
||||
options: BaseOption[];
|
||||
};
|
||||
|
||||
export default function Element({
|
||||
value = null,
|
||||
setValue,
|
||||
options,
|
||||
status,
|
||||
isValid,
|
||||
help,
|
||||
...props
|
||||
}: ElementProps) {
|
||||
return (
|
||||
<FormItem hasFeedback validateStatus={isValid === false ? 'error' : ''} help={help}>
|
||||
<Select
|
||||
defaultValue={value}
|
||||
onChange={(val) => setValue(val)}
|
||||
disabled={status === 'Disabled'}
|
||||
loading={status === 'Loading'}
|
||||
optionFilterProp="children"
|
||||
options={[
|
||||
{
|
||||
label: 'Не выбрано',
|
||||
value: null,
|
||||
},
|
||||
].concat(options)}
|
||||
{...props}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
|
||||
export type { SelectProps };
|
||||
27
Elements/Switch.tsx
Normal file
27
Elements/Switch.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import type { SwitchProps } from 'antd';
|
||||
import { Form, Switch } from 'antd';
|
||||
import type { BaseElementProps } from './types';
|
||||
|
||||
const { Item: FormItem } = Form;
|
||||
|
||||
export default function Element({
|
||||
value,
|
||||
setValue,
|
||||
status,
|
||||
isValid,
|
||||
help,
|
||||
...props
|
||||
}: BaseElementProps<boolean>) {
|
||||
return (
|
||||
<FormItem hasFeedback validateStatus={isValid === false ? 'error' : ''} help={help}>
|
||||
<Switch
|
||||
checked={value}
|
||||
onChange={(enabled) => setValue(enabled)}
|
||||
disabled={status === 'Disabled'}
|
||||
{...props}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
|
||||
export type { SwitchProps };
|
||||
17
Elements/Text.tsx
Normal file
17
Elements/Text.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import styled from 'styled-components';
|
||||
import type { BaseElementProps } from './types';
|
||||
|
||||
const Text = styled.span`
|
||||
margin-bottom: 18px;
|
||||
font-size: 0.85rem;
|
||||
`;
|
||||
|
||||
export default function Element({ value, ...props }: BaseElementProps<string>) {
|
||||
return <Text {...props}>{value}</Text>;
|
||||
}
|
||||
|
||||
type TextProps = {
|
||||
middleware: (value: any) => string;
|
||||
};
|
||||
|
||||
export type { TextProps };
|
||||
15
Elements/types.ts
Normal file
15
Elements/types.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export type Status = 'Default' | 'Disabled' | 'Loading' | 'Hidden';
|
||||
|
||||
export type BaseElementProps<ValueType> = {
|
||||
value: ValueType;
|
||||
setValue: (value: ValueType) => void;
|
||||
status: Status;
|
||||
isValid: boolean;
|
||||
help: string;
|
||||
};
|
||||
|
||||
export type BaseOption = {
|
||||
name: string;
|
||||
label: string;
|
||||
value: any;
|
||||
};
|
||||
@ -4,10 +4,11 @@
|
||||
/* eslint-disable object-curly-newline */
|
||||
/* eslint-disable import/no-cycle */
|
||||
import type { Elements } from 'Components/Calculation/config/map';
|
||||
import type { BaseOption } from 'Elements/types';
|
||||
import { mergeWith } from 'lodash';
|
||||
import { makeAutoObservable } from 'mobx';
|
||||
import RootStore from 'stores/root';
|
||||
import { CalculationOptions, Filter, Options, OptionsFilters } from './types';
|
||||
import type { CalculationOptions, Filter, OptionsFilters } from './types';
|
||||
|
||||
const EXCLUDE_RESET_ELEMENTS: Elements[] = ['selectTechnicalCard', 'selectTownRegistration'];
|
||||
|
||||
@ -59,7 +60,7 @@ export default class OptionsStore {
|
||||
return filter ? options && filter(options) : options;
|
||||
}
|
||||
|
||||
setOptions = (elementName: Elements, options: Options) => {
|
||||
setOptions = (elementName: Elements, options: BaseOption[]) => {
|
||||
this.options[elementName] = options;
|
||||
};
|
||||
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
import type { Elements } from 'Components/Calculation/config/map';
|
||||
import type { BaseOption } from 'Elements/types';
|
||||
|
||||
export type BaseOption = {
|
||||
name: string;
|
||||
value: any;
|
||||
};
|
||||
export type CalculationOptions = Record<Elements, BaseOption[]>;
|
||||
|
||||
export type Options = BaseOption[];
|
||||
export type CalculationOptions = Record<Elements, Options>;
|
||||
|
||||
export type Filter = (options: Options) => Options;
|
||||
export type Filter = (options: BaseOption[]) => BaseOption[];
|
||||
export type OptionsFilters = Record<Elements, Filter>;
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
/* eslint-disable object-curly-newline */
|
||||
/* eslint-disable import/no-cycle */
|
||||
import type { Elements } from 'Components/Calculation/config/map';
|
||||
import type { Status } from 'Elements/types';
|
||||
import { makeAutoObservable } from 'mobx';
|
||||
import RootStore from 'stores/root';
|
||||
import type { CalculationStatuses, Status } from './types';
|
||||
import type { CalculationStatuses } from './types';
|
||||
|
||||
export default class StatusStore {
|
||||
root: RootStore;
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { Elements } from 'Components/Calculation/config/map';
|
||||
|
||||
export type Status = 'Default' | 'Disabled' | 'Loading' | 'Hidden';
|
||||
import type { Status } from 'Elements/types';
|
||||
|
||||
export type CalculationStatuses = Partial<Record<Elements, Status>>;
|
||||
|
||||
@ -11,5 +11,8 @@ export function useValidation(elementName) {
|
||||
[$calculation.$validation, elementName]
|
||||
);
|
||||
|
||||
return validationResult.get();
|
||||
return {
|
||||
...validationResult.get(),
|
||||
help: 'Некорректные данные',
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user