From 8268ba3c267ed472167d8628d64ef85ce6718221 Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Tue, 28 Mar 2023 12:35:51 +0300 Subject: [PATCH] prepare frontend for /unlimited page --- .../Calculation/builders/build-action.tsx | 3 +- .../Calculation/builders/build-options.tsx | 4 +- .../Calculation/builders/build-value.tsx | 4 +- apps/web/Components/Output/Validation.jsx | 36 ++++++++---- .../process/calculate/reactions/validation.ts | 55 ++++++++++--------- apps/web/stores/calculation/index.ts | 15 +++-- apps/web/stores/calculation/statuses/index.ts | 2 + .../stores/calculation/validation/hooks.js | 6 +- apps/web/stores/process/index.ts | 2 +- apps/web/stores/tables/fingap/index.ts | 11 ++-- apps/web/stores/tables/insurance/index.ts | 17 ++++-- apps/web/stores/tables/payments/index.ts | 13 +++-- apps/web/stores/validation/index.ts | 8 ++- packages/ui/elements/Checkbox.tsx | 4 +- packages/ui/elements/Input.tsx | 11 +++- packages/ui/elements/InputNumber.tsx | 10 +++- packages/ui/elements/Radio.tsx | 4 +- packages/ui/elements/Segmented.tsx | 12 +++- packages/ui/elements/Select.tsx | 4 +- packages/ui/elements/Switch.tsx | 11 +++- packages/ui/elements/types.ts | 4 +- 21 files changed, 156 insertions(+), 80 deletions(-) diff --git a/apps/web/Components/Calculation/builders/build-action.tsx b/apps/web/Components/Calculation/builders/build-action.tsx index a59ae10..c2074d0 100644 --- a/apps/web/Components/Calculation/builders/build-action.tsx +++ b/apps/web/Components/Calculation/builders/build-action.tsx @@ -21,8 +21,7 @@ export default function buildAction( return ( - import(`process/${processName}/action`).then((module) => module.action(context)) - } + import(`process/${processName}/action`).then((module) => module.action(context))} status={status} {...props} /> diff --git a/apps/web/Components/Calculation/builders/build-options.tsx b/apps/web/Components/Calculation/builders/build-options.tsx index e08f34b..63bbec8 100644 --- a/apps/web/Components/Calculation/builders/build-options.tsx +++ b/apps/web/Components/Calculation/builders/build-options.tsx @@ -19,13 +19,13 @@ export default function buildOptions( return observer((props: T) => { const [value, setValue] = useStoreValue(valueName); const status = useStatus(elementName); - const { isValid, help } = useValidation(elementName); + const { validateStatus, help } = useValidation(elementName); const options = useOptions(elementName); return ( ( return observer((props: T) => { const [value, setValue] = useStoreValue(valueName); const status = useStatus(elementName); - const { isValid, help } = useValidation(elementName); + const { validateStatus, help } = useValidation(elementName); return ( { const elementErrors = validation.getErrors(); const elementTitle = validation.params.err_title; return elementErrors.map(({ key, message }) => ( - + )); }); } -function getPaymentsTableErrors($tables) { +function getPaymentsTableErrors({ $tables, $process }) { const { payments } = $tables; const errors = payments.validation.getErrors(); const title = payments.validation.params.err_title; return errors.map(({ key, message }) => ( - + )); } -function getInsuranceTableErrors($tables) { +function getInsuranceTableErrors({ $tables, $process }) { const { insurance } = $tables; const errors = insurance.validation.getErrors(); const title = insurance.validation.params.err_title; return errors.map(({ key, message }) => ( - + )); } const Errors = observer(() => { - const { $calculation, $tables } = useStore(); + const store = useStore(); + const { $calculation, $tables } = store; const hasElementsErrors = Object.values($calculation.$validation).some( (validation) => validation.hasErrors @@ -69,9 +85,9 @@ const Errors = observer(() => { return ; } - const elementsErrors = getElementsErrors($calculation); - const paymentsErrors = getPaymentsTableErrors($tables); - const insuranceErrors = getInsuranceTableErrors($tables); + const elementsErrors = getElementsErrors(store); + const paymentsErrors = getPaymentsTableErrors(store); + const insuranceErrors = getInsuranceTableErrors(store); const errors = [...elementsErrors, ...paymentsErrors, ...insuranceErrors]; diff --git a/apps/web/process/calculate/reactions/validation.ts b/apps/web/process/calculate/reactions/validation.ts index 3a8430b..36c042e 100644 --- a/apps/web/process/calculate/reactions/validation.ts +++ b/apps/web/process/calculate/reactions/validation.ts @@ -5,6 +5,7 @@ import type { ProcessContext } from '@/process/types'; import ValidationHelper from '@/stores/validation/helper'; import { reaction } from 'mobx'; import { uid } from 'radash'; +import { makeDisposable } from 'tools'; import type { BaseOption } from 'ui/elements/types'; function hasInvalidValueOrOptions(value: unknown, options: Array>) { @@ -16,34 +17,38 @@ function hasInvalidValueOrOptions(value: unknown, options: Array { - const hasElementsErrors = Object.values($calculation.$validation).some( - (validation) => validation.hasErrors - ); + makeDisposable( + () => + reaction( + () => { + 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; + 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, - } + 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, + } + ), + () => $process.has('Unlimited') ); /** diff --git a/apps/web/stores/calculation/index.ts b/apps/web/stores/calculation/index.ts index ab662c5..c49be96 100644 --- a/apps/web/stores/calculation/index.ts +++ b/apps/web/stores/calculation/index.ts @@ -1,3 +1,4 @@ +import Validation from '../validation'; import type { ValidationParams } from '../validation/types'; import OptionsStore from './options'; import StatusStore from './statuses'; @@ -6,17 +7,18 @@ import titles from '@/Components/Calculation/config/elements-titles'; import type * as Values from '@/Components/Calculation/config/map/values'; import { getValueName } from '@/Components/Calculation/config/map/values'; import type RootStore from '@/stores/root'; -import Validation from '@/stores/validation'; import { observable } from 'mobx'; import type { BaseOption } from 'ui/elements/types'; export default class CalculationStore { + private root: RootStore; public $values: ValuesStore; public $status: StatusStore; public $options: OptionsStore; public $validation: Partial>; constructor(rootStore: RootStore) { + this.root = rootStore; this.$values = new ValuesStore(rootStore); this.$status = new StatusStore(rootStore); this.$options = new OptionsStore(rootStore); @@ -24,10 +26,13 @@ export default class CalculationStore { } private createElementValidation = (elementName: E) => { - this.$validation[elementName] = new Validation({ - err_key: elementName, - err_title: titles[elementName], - }); + this.$validation[elementName] = new Validation( + { + err_key: elementName, + err_title: titles[elementName], + }, + this.root + ); }; public element = (elementName: E) => ({ diff --git a/apps/web/stores/calculation/statuses/index.ts b/apps/web/stores/calculation/statuses/index.ts index faf77f8..b03400e 100644 --- a/apps/web/stores/calculation/statuses/index.ts +++ b/apps/web/stores/calculation/statuses/index.ts @@ -21,6 +21,8 @@ export default class StatusStore { }; public getStatus(elementName: ElementsActions | ElementsValues) { + if (this.root.$process.has('Unlimited')) return 'Default'; + return this.overrided[elementName] || this.statuses[elementName]; } diff --git a/apps/web/stores/calculation/validation/hooks.js b/apps/web/stores/calculation/validation/hooks.js index 7a8a06e..8065ed2 100644 --- a/apps/web/stores/calculation/validation/hooks.js +++ b/apps/web/stores/calculation/validation/hooks.js @@ -1,16 +1,16 @@ import { useStore } from '@/stores/hooks'; export function useValidation(elementName) { - const { $calculation } = useStore(); + const { $calculation, $process } = useStore(); const hasErrors = $calculation.$validation?.[elementName]?.hasErrors; if (hasErrors) { return { help: 'Некорректные данные', - isValid: false, + validateStatus: $process.has('Unlimited') ? 'warning' : 'error', }; } return { - isValid: true, + validateStatus: '', }; } diff --git a/apps/web/stores/process/index.ts b/apps/web/stores/process/index.ts index e18ef85..3a97210 100644 --- a/apps/web/stores/process/index.ts +++ b/apps/web/stores/process/index.ts @@ -1,7 +1,7 @@ import type { ObservableSet } from 'mobx'; import { observable } from 'mobx'; -export type Process = 'ELT' | 'LoadKP'; +export type Process = 'ELT' | 'LoadKP' | 'Unlimited'; export type ProcessStore = ObservableSet; export default function createProcessStore() { diff --git a/apps/web/stores/tables/fingap/index.ts b/apps/web/stores/tables/fingap/index.ts index 4aeebbf..90b0541 100644 --- a/apps/web/stores/tables/fingap/index.ts +++ b/apps/web/stores/tables/fingap/index.ts @@ -15,10 +15,13 @@ export default class FinGAPTable { this.selectedKeys = new Set(); this.risks = observable([]); - this.validation = new Validation({ - err_key: 'ERR_FINGAP_TABLE', - err_title: 'Таблица рисков Safe Finance', - }); + this.validation = new Validation( + { + err_key: 'ERR_FINGAP_TABLE', + err_title: 'Таблица рисков Safe Finance', + }, + rootStore + ); makeAutoObservable(this); this.root = rootStore; diff --git a/apps/web/stores/tables/insurance/index.ts b/apps/web/stores/tables/insurance/index.ts index 8d70370..bee94d9 100644 --- a/apps/web/stores/tables/insurance/index.ts +++ b/apps/web/stores/tables/insurance/index.ts @@ -21,10 +21,13 @@ export default class InsuranceTable { insuranceTableConfig.defaultStatuses; constructor(rootStore: RootStore) { - this.validation = new Validation({ - err_key: 'ERR_INSURANCE_TABLE', - err_title: 'Таблица страхования', - }); + this.validation = new Validation( + { + err_key: 'ERR_INSURANCE_TABLE', + err_title: 'Таблица страхования', + }, + rootStore + ); makeAutoObservable(this); this.root = rootStore; @@ -95,7 +98,11 @@ export default class InsuranceTable { getOptions: (valueName: V) => this.options[key][valueName], - getStatus: (valueName: Insurance.Values) => this.statuses[key][valueName], + getStatus: (valueName: Insurance.Values) => { + if (this.root.$process.has('Unlimited')) return 'Default'; + + return this.statuses[key][valueName]; + }, getValue: (valueName: V) => { const rowIndex = this.values.findIndex((x) => x.key === key); diff --git a/apps/web/stores/tables/payments/index.ts b/apps/web/stores/tables/payments/index.ts index bddc221..9e87865 100644 --- a/apps/web/stores/tables/payments/index.ts +++ b/apps/web/stores/tables/payments/index.ts @@ -14,10 +14,13 @@ export default class PaymentsTable { private overridedStatus: IObservableValue; constructor(rootStore: RootStore) { - this.validation = new Validation({ - err_key: 'ERR_PAYMENTS_TABLE', - err_title: 'Таблица платежей', - }); + this.validation = new Validation( + { + err_key: 'ERR_PAYMENTS_TABLE', + err_title: 'Таблица платежей', + }, + rootStore + ); this.values = observable([]); this.statuses = observable([]); @@ -50,6 +53,8 @@ export default class PaymentsTable { }; public getStatus(index: number) { + if (this.root.$process.has('Unlimited')) return 'Default'; + return this.overridedStatus.get() ?? this.statuses[index]; } diff --git a/apps/web/stores/validation/index.ts b/apps/web/stores/validation/index.ts index 5b9ca5a..0154033 100644 --- a/apps/web/stores/validation/index.ts +++ b/apps/web/stores/validation/index.ts @@ -1,14 +1,17 @@ +import type RootStore from '../root'; import type { RemoveError, ValidationConfig, ValidationError, ValidationParams } from './types'; import { makeAutoObservable } from 'mobx'; import notification from 'ui/elements/notification'; export default class Validation { + private root: RootStore; private params: ValidationConfig; private errors: Set; - constructor(config: ValidationConfig) { + constructor(config: ValidationConfig, rootStore: RootStore) { this.params = config; this.errors = new Set(); + this.root = rootStore; makeAutoObservable(this); } @@ -33,10 +36,11 @@ export default class Validation { this.errors.add({ key, message }); if (!silent) { - notification.error({ + notification.open({ description: message, key: this.params.err_key, message: this.params.err_title, + type: this.root.$process.has('Unlimited') ? 'warning' : 'error', }); } diff --git a/packages/ui/elements/Checkbox.tsx b/packages/ui/elements/Checkbox.tsx index 97a9622..e83ce2a 100644 --- a/packages/ui/elements/Checkbox.tsx +++ b/packages/ui/elements/Checkbox.tsx @@ -16,7 +16,7 @@ function Checkbox({ value, setValue, status, - isValid, + validateStatus, help, text, ...props @@ -26,7 +26,7 @@ function Checkbox({ } return ( - + ) { +function Input({ + value, + setValue, + status, + validateStatus, + help, + ...props +}: BaseElementProps) { function handleChange(event: ChangeEvent) { setValue(event.target.value); } return ( - + ); diff --git a/packages/ui/elements/InputNumber.tsx b/packages/ui/elements/InputNumber.tsx index 8164678..583f8da 100644 --- a/packages/ui/elements/InputNumber.tsx +++ b/packages/ui/elements/InputNumber.tsx @@ -7,7 +7,13 @@ const { Item: FormItem } = Form; type InputNumberProps = AntInputNumberProps; -function InputNumber({ setValue, status, isValid, help, ...props }: BaseElementProps) { +function InputNumber({ + setValue, + status, + validateStatus, + help, + ...props +}: BaseElementProps) { function handleChange(value: number | null) { if (value) { setValue(value); @@ -17,7 +23,7 @@ function InputNumber({ setValue, status, isValid, help, ...props }: BaseElementP } return ( - + + & { options: BaseOption[]; }; -function Segmented({ value, setValue, options, status, isValid, help, ...props }: ElementProps) { +function Segmented({ + value, + setValue, + options, + status, + validateStatus, + help, + ...props +}: ElementProps) { return ( - + & ElementProps) { @@ -31,7 +31,7 @@ function Select({ ); return ( - + ) { +function Switch({ + value, + setValue, + status, + validateStatus, + help, + ...props +}: BaseElementProps) { return ( - + ); diff --git a/packages/ui/elements/types.ts b/packages/ui/elements/types.ts index dc065d8..ab86129 100644 --- a/packages/ui/elements/types.ts +++ b/packages/ui/elements/types.ts @@ -1,10 +1,12 @@ +import type { ValidateStatus } from 'antd/es/form/FormItem'; + export type Status = 'Default' | 'Disabled' | 'Hidden' | 'Loading'; export type BaseElementProps = { help?: string; - isValid?: boolean; setValue: (value: Value) => void; status?: Status; + validateStatus?: ValidateStatus; value: Value; };