store: add useErrors hook

Calculation/render: override btnCalculate, btnCreateKP, btnCreateKPMini
This commit is contained in:
vchikalkin 2023-05-31 11:45:59 +03:00
parent 2d0117bc4c
commit 5c8560e266
8 changed files with 122 additions and 73 deletions

View File

@ -32,9 +32,9 @@ export function buildAction<T>(
<Component <Component
onClick={throttledAction} onClick={throttledAction}
status={status} status={status}
{...props}
disabled={status === 'Disabled'} disabled={status === 'Disabled'}
loading={status === 'Loading'} loading={status === 'Loading'}
{...props}
/> />
); );
}); });

View File

@ -6,7 +6,7 @@ import types from '../elements-types';
import map from '../map'; import map from '../map';
import type { RenderProps } from './types'; import type { RenderProps } from './types';
import { Container, Head } from '@/Components/Layout/Element'; import { Container, Head } from '@/Components/Layout/Element';
import { useStore } from '@/stores/hooks'; import { useErrors, useStore } from '@/stores/hooks';
import { useIsFetching } from '@tanstack/react-query'; import { useIsFetching } from '@tanstack/react-query';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react'; import type { ComponentProps } from 'react';
@ -25,6 +25,108 @@ const formatter = Intl.NumberFormat('ru', {
}).format; }).format;
const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = { const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
btnCalculate: {
render: () => {
const elementName = 'btnCalculate';
const title = titles.btnCalculate;
const valueName = map.btnCalculate;
const Component = components.btnCalculate;
const props = elementsProps.btnCalculate;
const { builder } = types.btnCalculate();
const Element = builder(Component, {
elementName,
valueName,
});
const RenderedComponent = observer(() => {
const { $process } = useStore();
const { hasErrors } = useErrors();
return (
<Container>
<Head htmlFor={elementName} title={title} />
<Element
{...props}
loading={$process.has('Calculate') || $process.has('CreateKP')}
disabled={$process.has('LoadKP') || (!$process.has('Unlimited') && hasErrors)}
/>
</Container>
);
});
return <RenderedComponent />;
},
},
btnCreateKP: {
render: () => {
const elementName = 'btnCreateKP';
const title = titles.btnCreateKP;
const valueName = map.btnCreateKP;
const Component = components.btnCreateKP;
const props = elementsProps.btnCreateKP;
const { builder } = types.btnCreateKP();
const Element = builder(Component, {
elementName,
valueName,
});
const RenderedComponent = observer(() => {
const { $process } = useStore();
const { hasErrors } = useErrors();
return (
<Container>
<Head htmlFor={elementName} title={title} />
<Element
{...props}
loading={$process.has('Calculate') || $process.has('CreateKP')}
disabled={$process.has('LoadKP') || (!$process.has('Unlimited') && hasErrors)}
/>
</Container>
);
});
return <RenderedComponent />;
},
},
btnCreateKPMini: {
render: () => {
const elementName = 'btnCreateKPMini';
const title = titles.btnCreateKPMini;
const valueName = map.btnCreateKPMini;
const Component = components.btnCreateKPMini;
const props = elementsProps.btnCreateKPMini;
const { builder } = types.btnCreateKPMini();
const Element = builder(Component, {
elementName,
valueName,
});
const RenderedComponent = observer(() => {
const { $process } = useStore();
const { hasErrors } = useErrors();
return (
<Container>
<Head htmlFor={elementName} title={title} />
<Element
{...props}
loading={$process.has('Calculate') || $process.has('CreateKP')}
disabled={$process.has('LoadKP') || (!$process.has('Unlimited') && hasErrors)}
/>
</Container>
);
});
return <RenderedComponent />;
},
},
selectHighSeasonStart: { selectHighSeasonStart: {
render: () => { render: () => {
const elementName = 'selectHighSeasonStart'; const elementName = 'selectHighSeasonStart';

View File

@ -2,7 +2,7 @@ import PaymentsTable from './PaymentsTable';
import Results from './Results'; import Results from './Results';
import Validation from './Validation'; import Validation from './Validation';
import Background from '@/Components/Layout/Background'; import Background from '@/Components/Layout/Background';
import { useStore } from '@/stores/hooks'; import { useErrors, useStore } from '@/stores/hooks';
import { min } from '@/styles/mq'; import { min } from '@/styles/mq';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
@ -15,12 +15,7 @@ const items = outputTabs.map(({ Component, id, title }) => {
if (id === 'validation') { if (id === 'validation') {
Label = observer(() => { Label = observer(() => {
const { $calculation, $tables } = useStore(); const { hasErrors } = useErrors();
const hasErrors =
$calculation.hasErrors ||
$tables.fingap.hasErrors ||
$tables.insurance.hasErrors ||
$tables.payments.hasErrors;
return ( return (
<Badge offset={[5, 0]} dot={hasErrors}> <Badge offset={[5, 0]} dot={hasErrors}>
@ -48,16 +43,11 @@ const Wrapper = styled(Background)`
`; `;
const Output = observer(() => { const Output = observer(() => {
const { $calculation, $tables, $results } = useStore(); const { $results } = useStore();
const [activeKey, setActiveKey] = useState(undefined); const [activeKey, setActiveKey] = useState(undefined);
const { hasErrors } = useErrors();
useEffect(() => { useEffect(() => {
const hasErrors =
$calculation.hasErrors ||
$tables.fingap.hasErrors ||
$tables.insurance.hasErrors ||
$tables.payments.hasErrors;
if ($results.payments.length > 0) { if ($results.payments.length > 0) {
setActiveKey('payments-table'); setActiveKey('payments-table');
} }
@ -65,13 +55,7 @@ const Output = observer(() => {
if (hasErrors) { if (hasErrors) {
setActiveKey('validation'); setActiveKey('validation');
} }
}, [ }, [$results.payments.length, hasErrors]);
$calculation.hasErrors,
$results.payments.length,
$tables.fingap.hasErrors,
$tables.insurance.hasErrors,
$tables.payments.hasErrors,
]);
return ( return (
<Wrapper> <Wrapper>

View File

@ -11,9 +11,6 @@ export async function action({ store, trpcClient }: ProcessContext) {
$process.add('Calculate'); $process.add('Calculate');
$calculation.$status.setStatus('btnCalculate', 'Loading');
$calculation.$status.setStatus('btnCreateKP', 'Loading');
$calculation.$status.setStatus('btnCreateKPMini', 'Loading');
$results.clear(); $results.clear();
const values = $calculation.$values.getValues(); const values = $calculation.$values.getValues();
@ -59,10 +56,6 @@ export async function action({ store, trpcClient }: ProcessContext) {
}); });
}) })
.finally(() => { .finally(() => {
$calculation.$status.setStatus('btnCalculate', 'Default');
$calculation.$status.setStatus('btnCreateKP', 'Default');
$calculation.$status.setStatus('btnCreateKPMini', 'Default');
$process.delete('Calculate'); $process.delete('Calculate');
}); });
} }

View File

@ -19,35 +19,6 @@ function hasInvalidValueOrOptions(value: unknown, options: Array<BaseOption<unkn
export default function reactions({ store }: ProcessContext) { export default function reactions({ store }: ProcessContext) {
const { $calculation, $tables, $process } = store; const { $calculation, $tables, $process } = store;
disposableReaction(
() => $process.has('Unlimited'),
() => {
const hasElementsErrors = Object.values($calculation.$validation).some(
(validation) => validation.hasErrors
);
const hasPaymentsErrors = $tables.payments.validation.hasErrors;
const hasInsuranceErrors = $tables.insurance.validation.hasErrors;
const hasFingapErrors = $tables.fingap.validation.hasErrors;
return hasElementsErrors || hasPaymentsErrors || hasInsuranceErrors || hasFingapErrors;
},
(hasErrors) => {
if (hasErrors) {
$calculation.$status.setStatus('btnCalculate', 'Disabled');
$calculation.$status.setStatus('btnCreateKP', 'Disabled');
$calculation.$status.setStatus('btnCreateKPMini', 'Disabled');
} else {
$calculation.$status.setStatus('btnCalculate', 'Default');
$calculation.$status.setStatus('btnCreateKP', 'Default');
$calculation.$status.setStatus('btnCreateKPMini', 'Default');
}
},
{
fireImmediately: true,
}
);
/** /**
* Проверяем, что выбранное значение элемента есть в списке * Проверяем, что выбранное значение элемента есть в списке
*/ */

View File

@ -12,9 +12,6 @@ export function action({ store, trpcClient, apolloClient }: ProcessContext) {
$process.add('CreateKP'); $process.add('CreateKP');
$calculation.$status.setStatus('btnCalculate', 'Loading');
$calculation.$status.setStatus('btnCreateKP', 'Loading');
$calculation.$status.setStatus('btnCreateKPMini', 'Loading');
$results.clear(); $results.clear();
const values = $calculation.$values.getValues(); const values = $calculation.$values.getValues();
@ -71,10 +68,6 @@ export function action({ store, trpcClient, apolloClient }: ProcessContext) {
}); });
}) })
.finally(() => { .finally(() => {
$calculation.$status.setStatus('btnCalculate', 'Default');
$calculation.$status.setStatus('btnCreateKP', 'Default');
$calculation.$status.setStatus('btnCreateKPMini', 'Default');
$process.delete('CreateKP'); $process.delete('CreateKP');
}); });
} }

View File

@ -96,11 +96,4 @@ export function common({ store, trpcClient, apolloClient }: ProcessContext) {
}); });
} }
); );
reaction(
() => $process.has('LoadKP'),
(isLoadKP) => {
$calculation.$status.setStatus('selectQuote', isLoadKP ? 'Disabled' : 'Default');
}
);
} }

View File

@ -9,3 +9,16 @@ export function useStore() {
return context; return context;
} }
export function useErrors() {
const { $calculation, $tables } = useStore();
const hasElementsErrors = $calculation.hasErrors;
const hasPaymentsErrors = $tables.payments.validation.hasErrors;
const hasInsuranceErrors = $tables.insurance.validation.hasErrors;
const hasFingapErrors = $tables.fingap.validation.hasErrors;
return {
hasErrors: hasElementsErrors || hasPaymentsErrors || hasInsuranceErrors || hasFingapErrors,
};
}