112 lines
3.5 KiB
TypeScript
112 lines
3.5 KiB
TypeScript
/* eslint-disable function-paren-newline */
|
||
/* eslint-disable implicit-arrow-linebreak */
|
||
/* eslint-disable no-confusing-arrow */
|
||
/* eslint-disable object-curly-newline */
|
||
/* eslint-disable import/no-cycle */
|
||
import type { Elements } from 'Components/Calculation/config/map';
|
||
import type { BaseOption } from 'Elements/types';
|
||
import { mergeWith } from 'lodash';
|
||
import { makeAutoObservable } from 'mobx';
|
||
import RootStore from 'stores/root';
|
||
import type { CalculationOptions, Filter, OptionsFilters } from './types';
|
||
|
||
const EXCLUDE_RESET_ELEMENTS: Elements[] = ['selectTechnicalCard', 'selectTownRegistration'];
|
||
|
||
const AUTO_SET_VALUE_ELEMENTS: Elements[] = [
|
||
'selectProduct',
|
||
'selectLeaseObjectType',
|
||
'selectBrand',
|
||
'selectModel',
|
||
'selectConfiguration',
|
||
'selectTracker',
|
||
'selectTelematic',
|
||
'selectTechnicalCard',
|
||
'selectFuelCard',
|
||
'selectRegistration',
|
||
'selectTownRegistration',
|
||
];
|
||
|
||
export default class OptionsStore {
|
||
root: RootStore;
|
||
options: Partial<CalculationOptions> = {};
|
||
filters: Partial<OptionsFilters> = {};
|
||
|
||
constructor(rootStore: RootStore) {
|
||
makeAutoObservable(this);
|
||
this.root = rootStore;
|
||
}
|
||
|
||
hydrate = (initialOptions: Partial<CalculationOptions>) => {
|
||
this.options = initialOptions;
|
||
};
|
||
|
||
/** **************** OPTIONS **************** */
|
||
getOption(elementName: Elements) {
|
||
const value = this.root.$calculation.$values.getValueByElement(elementName);
|
||
return this.options[elementName]?.find((x) => x.value === value);
|
||
}
|
||
|
||
getOptions(
|
||
elementName: Elements,
|
||
settings?: {
|
||
filtered: true;
|
||
}
|
||
) {
|
||
const options = this.options[elementName];
|
||
|
||
if (!settings?.filtered) return options;
|
||
|
||
const filter = this.filters[elementName];
|
||
return filter ? options && filter(options) : options;
|
||
}
|
||
|
||
setOptions = (elementName: Elements, options: BaseOption[]) => {
|
||
this.options[elementName] = options;
|
||
};
|
||
|
||
mergeOptions = (options: Partial<CalculationOptions>) => {
|
||
mergeWith(this.options, options, (objValue, srcValue) =>
|
||
objValue === undefined ? srcValue : objValue
|
||
);
|
||
};
|
||
|
||
clearOptions = (elementName: Elements) => {
|
||
this.options[elementName] = [];
|
||
|
||
this.root.$calculation.$values.clearValueOfElement(elementName);
|
||
};
|
||
|
||
/** **************** FILTERS **************** */
|
||
getFilter(elementName: Elements) {
|
||
return this.filters[elementName];
|
||
}
|
||
|
||
setFilter = (elementName: Elements, filter: Filter) => {
|
||
this.filters[elementName] = filter;
|
||
|
||
/**
|
||
* Проверяем, что значение есть в отфильтрованном списке,
|
||
* иначе сбрасываем значение
|
||
* (кроме исключений {@link EXCLUDE_RESET_ELEMENTS})
|
||
*/
|
||
const filteredOptons = this.getOptions(elementName);
|
||
|
||
if (!EXCLUDE_RESET_ELEMENTS.includes(elementName)) {
|
||
const elementValue = this.root.$calculation.$values.getValueByElement(elementName);
|
||
|
||
if (!filteredOptons?.length || !filteredOptons.some((x) => x.value === elementValue)) {
|
||
this.root.$calculation.$values.clearValueOfElement(elementName);
|
||
}
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* Если после фильтрации остается одна запись, то указываем ее
|
||
* (для элементов из списка {@link AUTO_SET_VALUE_ELEMENTS})
|
||
*/
|
||
if (filteredOptons?.length === 1 && AUTO_SET_VALUE_ELEMENTS.includes(elementName)) {
|
||
this.root.$calculation.$values.setValueOfElement(elementName, filteredOptons[0].value);
|
||
}
|
||
};
|
||
}
|