validation: show tables errors

payments: generate table on changing leasingPeriod
This commit is contained in:
Chika 2022-07-09 15:10:21 +03:00
parent 8075047103
commit 441f9aadbd
7 changed files with 105 additions and 30 deletions

View File

@ -9,31 +9,56 @@ const Bold = styled.span`
font-weight: bold;
`;
const Errors = observer(() => {
const { $calculation } = useStore();
if (!$calculation.$validation.hasErrors()) {
return <Alert type="success" showIcon message="Ошибок нет 🙂" />;
}
function Message(title, text) {
return (
<>
<Bold>{title}</Bold>
{': '}
{text}
</>
);
}
function getElementsErrors($calculation) {
const { elementsErrors } = $calculation.$validation;
const errors = Object.keys(elementsErrors).map((elementName) => {
const elementErrors = elementsErrors[elementName];
const elementTitle = titles[elementName];
return elementErrors.map((error) => {
const message = (
<>
<Bold>{elementTitle}</Bold>
{': '}
{error.text}
</>
);
return <Alert key={error.name} type="error" showIcon message={message} />;
});
return elementErrors.map((error) => (
<Alert key={error.name} type="error" showIcon message={Message(elementTitle, error.text)} />
));
});
return errors;
}
function getPaymentsTableErrors($tables) {
const { payments } = $tables;
const messages = payments.validation.getMessages();
const title = payments.validation.params.err_title;
return messages.map((text) => <Alert type="error" showIcon message={Message(title, text)} />);
}
function getInsuranceTableErrors($tables) {
const { insurance } = $tables;
const messages = insurance.validation.getMessages();
return messages.map((message) => <Alert type="error" showIcon message={message} />);
}
const Errors = observer(() => {
const { $calculation, $tables } = useStore();
const elementsErrors = getElementsErrors($calculation);
const paymentsErrors = getPaymentsTableErrors($tables);
const insuranceErrors = getInsuranceTableErrors($tables);
const errors = [...elementsErrors, ...paymentsErrors, ...insuranceErrors];
if (errors.length === 0) return <Alert type="success" showIcon message="Ошибок нет 🙂" />;
return <Flex flexDirection="column">{errors}</Flex>;
});

View File

@ -6,6 +6,7 @@ import type { BaseOption } from 'Elements/types';
import type { GetServerSideProps } from 'next';
import Head from 'next/head';
import leadOpportunityUrlsReactions from 'process/lead-opportunity/reactions/urls';
import paymentsReactions from 'process/payments/reactions';
import { fetchUser } from 'services/user';
import { getDomainName } from 'services/user/tools';
import { useStore } from 'stores/hooks';
@ -46,6 +47,7 @@ function Home({ graphQLData }: PageProps) {
* add reactions to store
*/
leadOpportunityUrlsReactions(store, apolloClient);
paymentsReactions(store, apolloClient);
/**
* set graphql data to store

View File

@ -0,0 +1,27 @@
import type { ApolloClient } from '@apollo/client';
import { reaction } from 'mobx';
import type RootStore from 'stores/root';
export default function paymentsReactions(store: RootStore, apolloClient: ApolloClient<object>) {
const { $calculation } = store;
reaction(
() => $calculation.$values.getValue('leasingPeriod'),
(leasingPeriod) => {
if (leasingPeriod) {
const { $tables } = store;
$tables.payments.setValues(
Array.from(
{
length: leasingPeriod,
},
() => 0
)
);
}
},
{
fireImmediately: true,
}
);
}

View File

@ -15,7 +15,7 @@ export default class ValidationStore {
this.root = rootStore;
}
hasErrors() {
get hasErrors() {
return (Object.keys(this.elementsErrors) as Elements[]).some(
(elementName) => this.elementsErrors[elementName]?.length
);
@ -42,7 +42,7 @@ export default class ValidationStore {
notification.error({
key: error.name,
message: `Ошибка в поле ${titles[elementName]}`,
message: `${titles[elementName]}`,
description: error.text,
});

View File

@ -23,7 +23,7 @@ export default class InsuranceTable {
this.root = rootStore;
this.validation = new Validation({
err_key: 'ERR_INSURANCE_TABLE',
err_title: 'Ошибка в таблице страхования',
err_title: 'Таблица страхования',
});
makeAutoObservable(this);
}

View File

@ -1,6 +1,7 @@
import type { Status } from 'Elements/types';
import type { IObservableArray } from 'mobx';
import { makeAutoObservable, observable, reaction } from 'mobx';
import { makeAutoObservable, observable, reaction, toJS } from 'mobx';
import type RootStore from 'stores/root';
import Validation from '../validation';
@ -19,7 +20,7 @@ export default class PaymentsTable {
this.root = rootStore;
this.validation = new Validation({
err_key: 'ERR_PAYMENTS_TABLE',
err_title: 'Ошибка в таблице платежей',
err_title: 'Таблица платежей',
});
this.values = observable<number>([]);
this.statuses = observable<Status>([]);
@ -34,6 +35,23 @@ export default class PaymentsTable {
this.statuses.length = length;
}
);
/**
* Проверяем платежи на 0
*/
const errorText = 'Значения не должны быть равны 0';
let removeError: () => void;
reaction(
() => toJS(this.values),
(values) => {
if (values.includes(0)) {
removeError = this.validation.addError(errorText);
} else {
removeError();
}
}
);
}
getValue(index: number) {

View File

@ -1,5 +1,5 @@
import notification from 'Elements/notification';
import { makeAutoObservable, observable } from 'mobx';
import { makeAutoObservable } from 'mobx';
type Params = {
err_key: string;
@ -8,24 +8,27 @@ type Params = {
export default class Validation {
params: Params;
messages = observable<string>([]);
messages: Set<string>;
constructor(params: Params) {
makeAutoObservable(this);
this.params = params;
this.messages = new Set();
makeAutoObservable(this);
}
get hasErrors() {
return this.messages.size > 0;
}
getMessages() {
return this.messages;
return [...this.messages];
}
addError = (message: string) => {
this.messages.push(message);
const messageIndex = this.messages.length;
this.messages.add(message);
const removeError = () => {
this.messages.splice(messageIndex - 1, 1);
this.messages.delete(message);
};
notification.error({