move options elements validation to process/calculate

This commit is contained in:
vchikalkin 2023-02-02 20:00:08 +03:00
parent 6172833fdb
commit 2a4203914b
3 changed files with 56 additions and 62 deletions

View File

@ -1,8 +1,20 @@
import types from 'Components/Calculation/config/elements-types';
import type * as Values from 'Components/Calculation/config/map/values';
import { reaction } from 'mobx';
import type { ReactionsContext } from 'process/types';
import type { BaseOption } from 'ui/elements/types';
function hasInvalidValue(value: unknown, options: BaseOption<unknown>[]) {
if (value === null) {
return false;
}
return (value && !options?.length) || !options.some((x) => x.value === value);
}
export default function validationReactions({ store }: ReactionsContext) {
const { $calculation, $tables } = store;
reaction(
() => {
const hasElementsErrors = Object.values($calculation.$validation).some(
@ -27,4 +39,48 @@ export default function validationReactions({ store }: ReactionsContext) {
fireImmediately: true,
}
);
/**
* Проверяем, что выбранное значение элемента есть в списке
*/
(Object.keys(types) as Values.Elements[]).forEach((elementName) => {
const type = types[elementName];
if (type().typeName !== 'Options') {
return;
}
const element = $calculation.element(elementName);
reaction(
() => {
const options = element.getOptions();
const value = element.getValue();
return {
value,
options,
};
},
({ value, options }) => {
element.validate({
invalid: hasInvalidValue(value, options),
message: 'Выбранное значение отсутствует в списке',
silent: true,
});
},
{
delay: 100,
}
);
reaction(
() => element.getOptions(),
(options) => {
const value = element.getValue();
if (hasInvalidValue(value, options)) {
element.resetValue();
}
}
);
});
}

View File

@ -1,59 +0,0 @@
import types from 'Components/Calculation/config/elements-types';
import type * as Values from 'Components/Calculation/config/map/values';
import { reaction } from 'mobx';
import type { BaseOption } from 'ui/elements/types';
import type CalculationStore from '.';
export function hasInvalidValue(value: unknown, options: BaseOption<unknown>[]) {
if (value === null) {
return false;
}
return (value && !options?.length) || !options.some((x) => x.value === value);
}
export function createReactions($calculation: CalculationStore) {
/**
* Проверяем, что выбранное значение элемента есть в списке
*/
(Object.keys(types) as Values.Elements[]).forEach((elementName) => {
const type = types[elementName];
if (type().typeName !== 'Options') {
return;
}
const element = $calculation.element(elementName);
reaction(
() => {
const options = element.getOptions();
const value = element.getValue();
return {
value,
options,
};
},
({ value, options }) => {
element.validate({
invalid: hasInvalidValue(value, options),
message: 'Выбранное значение отсутствует в списке',
silent: true,
});
},
{
delay: 100,
}
);
reaction(
() => element.getOptions(),
(options) => {
const value = element.getValue();
if (hasInvalidValue(value, options)) {
element.resetValue();
}
}
);
});
}

View File

@ -7,7 +7,6 @@ import type RootStore from 'stores/root';
import Validation from 'stores/validation';
import type { BaseOption } from 'ui/elements/types';
import type { RemoveError, ValidationParams } from '../validation/types';
import { createReactions } from './helpers';
import OptionsStore from './options';
import StatusStore from './statuses';
import ValuesStore from './values';
@ -23,8 +22,6 @@ export default class CalculationStore {
this.$status = new StatusStore(rootStore);
this.$options = new OptionsStore(rootStore);
this.$validation = observable.object({});
createReactions(this);
}
private createElementValidation = <E extends Values.Elements>(elementName: E) => {