From 1295b94b2533b436a512d7a7986efcd9d6505982 Mon Sep 17 00:00:00 2001 From: Chika Date: Thu, 23 Jun 2022 11:39:02 +0300 Subject: [PATCH] Calculation: fix elements-render & builders types --- .eslintrc.json | 2 +- .../Calculation/builders/build-action.tsx | 9 +- .../Calculation/builders/build-computed.tsx | 9 +- .../Calculation/builders/build-options.tsx | 10 ++- .../Calculation/builders/build-readonly.tsx | 11 +-- .../Calculation/builders/build-value.tsx | 10 ++- .../Calculation/config/elements-builders.ts | 9 +- .../config/elements-render/index.ts | 7 ++ .../config/elements-render/layout.tsx | 36 ++++++++ .../override.tsx} | 86 +++---------------- .../config/elements-render/render.jsx | 33 +++++++ .../config/elements-render/types.ts | 3 + 12 files changed, 121 insertions(+), 104 deletions(-) create mode 100644 Components/Calculation/config/elements-render/index.ts create mode 100644 Components/Calculation/config/elements-render/layout.tsx rename Components/Calculation/config/{elements-render.tsx => elements-render/override.tsx} (64%) create mode 100644 Components/Calculation/config/elements-render/render.jsx create mode 100644 Components/Calculation/config/elements-render/types.ts diff --git a/.eslintrc.json b/.eslintrc.json index 6e2922a..72079c4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -33,7 +33,7 @@ ], "import/extensions": "off", "object-curly-newline": [ - "error", + "warn", { "ObjectExpression": "always", "ObjectPattern": { "multiline": true }, diff --git a/Components/Calculation/builders/build-action.tsx b/Components/Calculation/builders/build-action.tsx index 2c66572..5ae58d6 100644 --- a/Components/Calculation/builders/build-action.tsx +++ b/Components/Calculation/builders/build-action.tsx @@ -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, +export default function buildAction( + Component: ComponentType, { elementName, valueName: actionName }: BuilderProps ) { - return observer((props) => { + return observer((props: T) => { const status = useStatus(elementName); return ( diff --git a/Components/Calculation/builders/build-computed.tsx b/Components/Calculation/builders/build-computed.tsx index 9a76cea..f6751d2 100644 --- a/Components/Calculation/builders/build-computed.tsx +++ b/Components/Calculation/builders/build-computed.tsx @@ -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, +export default function buildComputedValue( + Component: ComponentType, { elementName, valueName: computedValueName }: BuilderProps ) { - return observer((props) => { + return observer((props: T) => { const computedValue = useComputedValue(computedValueName); const status = useStatus(elementName); diff --git a/Components/Calculation/builders/build-options.tsx b/Components/Calculation/builders/build-options.tsx index 88aeff4..8849fd6 100644 --- a/Components/Calculation/builders/build-options.tsx +++ b/Components/Calculation/builders/build-options.tsx @@ -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, { elementName, valueName }: BuilderProps) { - return observer((props) => { +export default function buildOptions( + Component: ComponentType, + { elementName, valueName }: BuilderProps +) { + return observer((props: T) => { const [value, setValue] = useStoreValue(valueName); const status = useStatus(elementName); const { isValid, help } = useValidation(elementName); diff --git a/Components/Calculation/builders/build-readonly.tsx b/Components/Calculation/builders/build-readonly.tsx index 89a1f31..a7cf79b 100644 --- a/Components/Calculation/builders/build-readonly.tsx +++ b/Components/Calculation/builders/build-readonly.tsx @@ -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, - { elementName, valueName }: BuilderProps -) { - return observer((props) => { +export default function buildReadonly(Component: ComponentType, { valueName }: BuilderProps) { + return observer((props: T) => { const [value] = useValue(valueName); return ; diff --git a/Components/Calculation/builders/build-value.tsx b/Components/Calculation/builders/build-value.tsx index 23aef47..89bac17 100644 --- a/Components/Calculation/builders/build-value.tsx +++ b/Components/Calculation/builders/build-value.tsx @@ -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, { elementName, valueName }: BuilderProps) { - return observer((props) => { +export default function buildValue( + Component: ComponentType, + { elementName, valueName }: BuilderProps +) { + return observer((props: T) => { const [value, setValue] = useStoreValue(valueName); const status = useStatus(elementName); const { isValid, help } = useValidation(elementName); diff --git a/Components/Calculation/config/elements-builders.ts b/Components/Calculation/config/elements-builders.ts index 9e60d06..a5edecc 100644 --- a/Components/Calculation/config/elements-builders.ts +++ b/Components/Calculation/config/elements-builders.ts @@ -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 = { +function wrapElementsBuilders>(arg: T) { + return arg; +} + +const builders = wrapElementsBuilders({ cbxRecalcWithRevision: buildValue, tbxLeaseObjectPrice: buildValue, tbxLeaseObjectPriceWthtVAT: buildValue, @@ -154,6 +157,6 @@ const builders: Record = { labelResultBonusDopProd: buildReadonly, labelResultBonusSafeFinance: buildReadonly, labelResultFirstPaymentRiskPolicy: buildReadonly, -}; +}); export default builders; diff --git a/Components/Calculation/config/elements-render/index.ts b/Components/Calculation/config/elements-render/index.ts new file mode 100644 index 0000000..07f3d61 --- /dev/null +++ b/Components/Calculation/config/elements-render/index.ts @@ -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; diff --git a/Components/Calculation/config/elements-render/layout.tsx b/Components/Calculation/config/elements-render/layout.tsx new file mode 100644 index 0000000..fb84ac7 --- /dev/null +++ b/Components/Calculation/config/elements-render/layout.tsx @@ -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 ( + + {title} + {addon} + + ); +} + +export function Container({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/Components/Calculation/config/elements-render.tsx b/Components/Calculation/config/elements-render/override.tsx similarity index 64% rename from Components/Calculation/config/elements-render.tsx rename to Components/Calculation/config/elements-render/override.tsx index 52fbf21..fd68419 100644 --- a/Components/Calculation/config/elements-render.tsx +++ b/Components/Calculation/config/elements-render/override.tsx @@ -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 ( - - {title} - {addon} - - ); -} - -function Container({ children }: { children: ReactNode }) { - return {children}; -} - -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: () => ( - - - - - ), - }; - - return acc; -}, {} as Record); - -const defaultLinkProps = { +const defaultLinkProps: ComponentProps = { text: 'Открыть в CRM', type: 'link', }; -const overrideRenderElements: Partial> = { +const overrideRender: Partial> = { selectLead: { render: () => { const title = titles.selectLead; @@ -90,7 +31,6 @@ const overrideRenderElements: Partial> = { }); const LinkComponent = buildReadonly(Link, { - elementName: 'linkLeadUrl', valueName: 'leadUrl', }); @@ -117,7 +57,6 @@ const overrideRenderElements: Partial> = { }); const LinkComponent = buildReadonly(Link, { - elementName: 'linkOpportunityUrl', valueName: 'opportunityUrl', }); @@ -144,7 +83,6 @@ const overrideRenderElements: Partial> = { }); const LinkComponent = buildReadonly(Link, { - elementName: 'linkQuoteUrl', valueName: 'quoteUrl', }); @@ -206,4 +144,4 @@ const overrideRenderElements: Partial> = { }, }; -export default Object.assign(renderElements, overrideRenderElements); +export default overrideRender; diff --git a/Components/Calculation/config/elements-render/render.jsx b/Components/Calculation/config/elements-render/render.jsx new file mode 100644 index 0000000..5f1e97a --- /dev/null +++ b/Components/Calculation/config/elements-render/render.jsx @@ -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: () => ( + + + + + ), + }; + + return acc; +}, {}); + +export default render; diff --git a/Components/Calculation/config/elements-render/types.ts b/Components/Calculation/config/elements-render/types.ts new file mode 100644 index 0000000..0e0fc7e --- /dev/null +++ b/Components/Calculation/config/elements-render/types.ts @@ -0,0 +1,3 @@ +import type { FC } from 'react'; + +export type RenderProps = { render: FC };