diff --git a/apps/web/process/configurator/reactions/values.ts b/apps/web/process/configurator/reactions/values.ts index df8f9b1..a8a249a 100644 --- a/apps/web/process/configurator/reactions/values.ts +++ b/apps/web/process/configurator/reactions/values.ts @@ -3,7 +3,7 @@ import type { Elements } from '@/Components/Calculation/config/map/values'; import * as CRMTypes from '@/graphql/crm.types'; import type { ProcessContext } from '@/process/types'; import { normalizeOptions } from '@/utils/entity'; -import { disposableReaction } from '@/utils/mobx'; +import { disposableDebouncedReaction, disposableReaction } from '@/utils/mobx'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import { comparer, reaction } from 'mobx'; @@ -15,7 +15,7 @@ export default function valuesReactions({ store, apolloClient }: ProcessContext) const { getTarifs, getRates, getPriceChange } = helper({ apolloClient }); - disposableReaction( + disposableDebouncedReaction( () => $process.has('LoadKP'), () => $calculation.$values.getValues([ @@ -39,6 +39,7 @@ export default function valuesReactions({ store, apolloClient }: ProcessContext) delay: 10, equals: comparer.shallow, fireImmediately: true, + wait: 100, } ); diff --git a/apps/web/utils/mobx.ts b/apps/web/utils/mobx.ts index c8a86d6..a63de0f 100644 --- a/apps/web/utils/mobx.ts +++ b/apps/web/utils/mobx.ts @@ -51,3 +51,41 @@ export function debouncedReaction( return reaction(expression, debouncedEffect, reactionOpts); } + +export function disposableDebouncedReaction( + disposeExpression: () => boolean, + expression: (r: IReactionPublic) => T, + effect: ( + arg: T, + prev: FireImmediately extends true ? T | undefined : T, + r: IReactionPublic + ) => void, + { wait, ...reactionOpts }: IReactionOptions & { wait: number } +) { + const debouncedEffect = debounce({ delay: wait }, effect); + + let disposer: IReactionDisposer | undefined; + + if (!disposeExpression()) { + disposer = reaction(expression, debouncedEffect, reactionOpts); + } + + function cleanDisposer() { + disposer = undefined; + } + + reaction(disposeExpression, (mustBeDisposed) => { + if (mustBeDisposed) { + if (disposer !== undefined) disposer(); + cleanDisposer(); + } else { + setTimeout(() => { + disposer = reaction( + expression, + debouncedEffect, + reactionOpts ? omit(reactionOpts, ['fireImmediately']) : undefined + ); + }, 100); + } + }); +}