Calculation: fix elements-render & builders types
This commit is contained in:
parent
a6dac59364
commit
1295b94b25
@ -33,7 +33,7 @@
|
||||
],
|
||||
"import/extensions": "off",
|
||||
"object-curly-newline": [
|
||||
"error",
|
||||
"warn",
|
||||
{
|
||||
"ObjectExpression": "always",
|
||||
"ObjectPattern": { "multiline": true },
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import type { FC } from 'react';
|
||||
import type { ComponentType } from 'react';
|
||||
import { useStatus } from 'stores/calculation/statuses/hooks';
|
||||
import type { Elements } from '../config/map/actions';
|
||||
import type { ElementsProps } from '../types/elements-props';
|
||||
|
||||
type BuilderProps = {
|
||||
elementName: Elements;
|
||||
valueName: string;
|
||||
};
|
||||
|
||||
export default function buildAction(
|
||||
Component: FC<any>,
|
||||
export default function buildAction<T>(
|
||||
Component: ComponentType<T>,
|
||||
{ elementName, valueName: actionName }: BuilderProps
|
||||
) {
|
||||
return observer<ElementsProps[typeof elementName]>((props) => {
|
||||
return observer((props: T) => {
|
||||
const status = useStatus(elementName);
|
||||
|
||||
return (
|
||||
|
||||
@ -1,21 +1,20 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import type { FC } from 'react';
|
||||
import type { ComponentType } from 'react';
|
||||
import { useStatus } from 'stores/calculation/statuses/hooks';
|
||||
import type { ComputedValues } from 'stores/calculation/values/computed';
|
||||
import { useComputedValue } from 'stores/calculation/values/hooks';
|
||||
import type { Elements } from '../config/map/computed';
|
||||
import type { ElementsProps } from '../types/elements-props';
|
||||
|
||||
type BuilderProps = {
|
||||
elementName: Elements;
|
||||
valueName: ComputedValues;
|
||||
};
|
||||
|
||||
export default function buildComputedValue(
|
||||
Component: FC<any>,
|
||||
export default function buildComputedValue<T>(
|
||||
Component: ComponentType<T>,
|
||||
{ elementName, valueName: computedValueName }: BuilderProps
|
||||
) {
|
||||
return observer<ElementsProps[typeof elementName]>((props) => {
|
||||
return observer((props: T) => {
|
||||
const computedValue = useComputedValue(computedValueName);
|
||||
const status = useStatus(elementName);
|
||||
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import type { FC } from 'react';
|
||||
import type { ComponentType } from 'react';
|
||||
import { useOptions } from 'stores/calculation/options/hooks';
|
||||
import { useStatus } from 'stores/calculation/statuses/hooks';
|
||||
import { useValidation } from 'stores/calculation/validation/hooks';
|
||||
import type { Values } from 'stores/calculation/values/types';
|
||||
import type { Elements } from '../config/map/values';
|
||||
import type { ElementsProps } from '../types/elements-props';
|
||||
import { useStoreValue } from './hooks';
|
||||
|
||||
type BuilderProps = {
|
||||
@ -13,8 +12,11 @@ type BuilderProps = {
|
||||
valueName: Values;
|
||||
};
|
||||
|
||||
export default function buildOptions(Component: FC<any>, { elementName, valueName }: BuilderProps) {
|
||||
return observer<ElementsProps[typeof elementName]>((props) => {
|
||||
export default function buildOptions<T>(
|
||||
Component: ComponentType<T>,
|
||||
{ elementName, valueName }: BuilderProps
|
||||
) {
|
||||
return observer((props: T) => {
|
||||
const [value, setValue] = useStoreValue(valueName);
|
||||
const status = useStatus(elementName);
|
||||
const { isValid, help } = useValidation(elementName);
|
||||
|
||||
@ -1,19 +1,14 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import type { FC } from 'react';
|
||||
import type { ComponentType } from 'react';
|
||||
import { useValue } from 'stores/calculation/values/hooks';
|
||||
import type { Values } from 'stores/calculation/values/types';
|
||||
import type { ElementsProps } from '../types/elements-props';
|
||||
|
||||
type BuilderProps = {
|
||||
elementName: keyof ElementsProps;
|
||||
valueName: Values;
|
||||
};
|
||||
|
||||
export default function buildReadonly(
|
||||
Component: FC<any>,
|
||||
{ elementName, valueName }: BuilderProps
|
||||
) {
|
||||
return observer<ElementsProps[typeof elementName]>((props) => {
|
||||
export default function buildReadonly<T>(Component: ComponentType<T>, { valueName }: BuilderProps) {
|
||||
return observer((props: T) => {
|
||||
const [value] = useValue(valueName);
|
||||
|
||||
return <Component value={value} readOnly {...props} />;
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import type { FC } from 'react';
|
||||
import type { ComponentType } from 'react';
|
||||
import { useStatus } from 'stores/calculation/statuses/hooks';
|
||||
import { useValidation } from 'stores/calculation/validation/hooks';
|
||||
import type { Values } from 'stores/calculation/values/types';
|
||||
import type { Elements } from '../config/map/values';
|
||||
import type { ElementsProps } from '../types/elements-props';
|
||||
import { useStoreValue } from './hooks';
|
||||
|
||||
export type BuilderProps = {
|
||||
@ -12,8 +11,11 @@ export type BuilderProps = {
|
||||
valueName: Values;
|
||||
};
|
||||
|
||||
export default function buildValue(Component: FC<any>, { elementName, valueName }: BuilderProps) {
|
||||
return observer<ElementsProps[typeof elementName]>((props) => {
|
||||
export default function buildValue<T>(
|
||||
Component: ComponentType<T>,
|
||||
{ elementName, valueName }: BuilderProps
|
||||
) {
|
||||
return observer((props: T) => {
|
||||
const [value, setValue] = useStoreValue(valueName);
|
||||
const status = useStatus(elementName);
|
||||
const { isValid, help } = useValidation(elementName);
|
||||
|
||||
@ -3,9 +3,12 @@ import buildComputed from '../builders/build-computed';
|
||||
import buildOptions from '../builders/build-options';
|
||||
import buildReadonly from '../builders/build-readonly';
|
||||
import buildValue from '../builders/build-value';
|
||||
import type components from './elements-components';
|
||||
|
||||
const builders: Record<keyof typeof components, any> = {
|
||||
function wrapElementsBuilders<C, T extends Record<string, C>>(arg: T) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
const builders = wrapElementsBuilders({
|
||||
cbxRecalcWithRevision: buildValue,
|
||||
tbxLeaseObjectPrice: buildValue,
|
||||
tbxLeaseObjectPriceWthtVAT: buildValue,
|
||||
@ -154,6 +157,6 @@ const builders: Record<keyof typeof components, any> = {
|
||||
labelResultBonusDopProd: buildReadonly,
|
||||
labelResultBonusSafeFinance: buildReadonly,
|
||||
labelResultFirstPaymentRiskPolicy: buildReadonly,
|
||||
};
|
||||
});
|
||||
|
||||
export default builders;
|
||||
|
||||
7
Components/Calculation/config/elements-render/index.ts
Normal file
7
Components/Calculation/config/elements-render/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
/* eslint-disable object-curly-newline */
|
||||
import type map from '../map';
|
||||
import overrideRender from './override';
|
||||
import render from './render';
|
||||
import type { RenderProps } from './types';
|
||||
|
||||
export default Object.assign(render, overrideRender) as Record<keyof typeof map, RenderProps>;
|
||||
36
Components/Calculation/config/elements-render/layout.tsx
Normal file
36
Components/Calculation/config/elements-render/layout.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Flex } from 'UIKit/grid';
|
||||
import { min } from 'UIKit/mq';
|
||||
|
||||
const ElementTitle = styled.h5`
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
margin: 0 8px 3px 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
${min('laptop')} {
|
||||
font-size: 14px;
|
||||
}
|
||||
`;
|
||||
|
||||
export function Head({ title, addon }: { title: string; addon?: ReactNode }) {
|
||||
return (
|
||||
<Flex
|
||||
flexDirection={['column', 'row']}
|
||||
justifyContent={['', 'space-between']}
|
||||
alignItems={['', 'center']}
|
||||
>
|
||||
<ElementTitle>{title}</ElementTitle>
|
||||
{addon}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
export function Container({ children }: { children: ReactNode }) {
|
||||
return <Flex flexDirection="column">{children}</Flex>;
|
||||
}
|
||||
@ -1,81 +1,22 @@
|
||||
/* eslint-disable object-curly-newline */
|
||||
import Link from 'Elements/Link';
|
||||
import Tooltip from 'Elements/Tooltip';
|
||||
import type { ReactNode } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Flex } from 'UIKit/grid';
|
||||
import { min } from 'UIKit/mq';
|
||||
import buildReadonly from '../builders/build-readonly';
|
||||
import builders from './elements-builders';
|
||||
import components from './elements-components';
|
||||
import elementsProps from './elements-props';
|
||||
import titles from './elements-titles';
|
||||
import map from './map';
|
||||
import type { ComponentProps } from 'react';
|
||||
import buildReadonly from '../../builders/build-readonly';
|
||||
import builders from '../elements-builders';
|
||||
import components from '../elements-components';
|
||||
import elementsProps from '../elements-props';
|
||||
import titles from '../elements-titles';
|
||||
import map from '../map';
|
||||
import { Container, Head } from './layout';
|
||||
import type { RenderProps } from './types';
|
||||
|
||||
const ElementTitle = styled.h5`
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
margin: 0 8px 3px 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
${min('laptop')} {
|
||||
font-size: 14px;
|
||||
}
|
||||
`;
|
||||
|
||||
function Head({ title, addon }: { title: string; addon?: ReactNode }) {
|
||||
return (
|
||||
<Flex
|
||||
flexDirection={['column', 'row']}
|
||||
justifyContent={['', 'space-between']}
|
||||
alignItems={['', 'center']}
|
||||
>
|
||||
<ElementTitle>{title}</ElementTitle>
|
||||
{addon}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
function Container({ children }: { children: ReactNode }) {
|
||||
return <Flex flexDirection="column">{children}</Flex>;
|
||||
}
|
||||
|
||||
type RenderProps = { render: () => JSX.Element };
|
||||
|
||||
const renderElements = (Object.keys(map) as (keyof typeof map)[]).reduce((acc, elementName) => {
|
||||
const title = titles[elementName];
|
||||
const valueName = map[elementName];
|
||||
const Component = components[elementName];
|
||||
const props = elementsProps[elementName];
|
||||
const builder = builders[elementName];
|
||||
|
||||
const Element = builder(Component, {
|
||||
elementName,
|
||||
valueName,
|
||||
});
|
||||
|
||||
acc[elementName] = {
|
||||
render: () => (
|
||||
<Container key={elementName}>
|
||||
<Head title={title} />
|
||||
<Element {...props} />
|
||||
</Container>
|
||||
),
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {} as Record<keyof typeof map, RenderProps>);
|
||||
|
||||
const defaultLinkProps = {
|
||||
const defaultLinkProps: ComponentProps<typeof Link> = {
|
||||
text: 'Открыть в CRM',
|
||||
type: 'link',
|
||||
};
|
||||
|
||||
const overrideRenderElements: Partial<Record<keyof typeof map, RenderProps>> = {
|
||||
const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
|
||||
selectLead: {
|
||||
render: () => {
|
||||
const title = titles.selectLead;
|
||||
@ -90,7 +31,6 @@ const overrideRenderElements: Partial<Record<keyof typeof map, RenderProps>> = {
|
||||
});
|
||||
|
||||
const LinkComponent = buildReadonly(Link, {
|
||||
elementName: 'linkLeadUrl',
|
||||
valueName: 'leadUrl',
|
||||
});
|
||||
|
||||
@ -117,7 +57,6 @@ const overrideRenderElements: Partial<Record<keyof typeof map, RenderProps>> = {
|
||||
});
|
||||
|
||||
const LinkComponent = buildReadonly(Link, {
|
||||
elementName: 'linkOpportunityUrl',
|
||||
valueName: 'opportunityUrl',
|
||||
});
|
||||
|
||||
@ -144,7 +83,6 @@ const overrideRenderElements: Partial<Record<keyof typeof map, RenderProps>> = {
|
||||
});
|
||||
|
||||
const LinkComponent = buildReadonly(Link, {
|
||||
elementName: 'linkQuoteUrl',
|
||||
valueName: 'quoteUrl',
|
||||
});
|
||||
|
||||
@ -206,4 +144,4 @@ const overrideRenderElements: Partial<Record<keyof typeof map, RenderProps>> = {
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.assign(renderElements, overrideRenderElements);
|
||||
export default overrideRender;
|
||||
33
Components/Calculation/config/elements-render/render.jsx
Normal file
33
Components/Calculation/config/elements-render/render.jsx
Normal file
@ -0,0 +1,33 @@
|
||||
/* eslint-disable object-curly-newline */
|
||||
import builders from '../elements-builders';
|
||||
import components from '../elements-components';
|
||||
import elementsProps from '../elements-props';
|
||||
import titles from '../elements-titles';
|
||||
import map from '../map';
|
||||
import { Container, Head } from './layout';
|
||||
|
||||
const render = Object.keys(map).reduce((acc, elementName) => {
|
||||
const title = titles[elementName];
|
||||
const valueName = map[elementName];
|
||||
const Component = components[elementName];
|
||||
const props = elementsProps[elementName];
|
||||
const builder = builders[elementName];
|
||||
|
||||
const Element = builder(Component, {
|
||||
elementName,
|
||||
valueName,
|
||||
});
|
||||
|
||||
acc[elementName] = {
|
||||
render: () => (
|
||||
<Container key={elementName}>
|
||||
<Head title={title} />
|
||||
<Element {...props} />
|
||||
</Container>
|
||||
),
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
export default render;
|
||||
3
Components/Calculation/config/elements-render/types.ts
Normal file
3
Components/Calculation/config/elements-render/types.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import type { FC } from 'react';
|
||||
|
||||
export type RenderProps = { render: FC };
|
||||
Loading…
x
Reference in New Issue
Block a user