From e623ed07267d901b19e1bb1bcb30c2faf9dea3b7 Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Tue, 6 Jun 2023 13:35:15 +0300 Subject: [PATCH] utils/mobx: add queueReaction queue load-kp & subsidy reactions --- apps/web/package.json | 1 + apps/web/process/load-kp/reactions.ts | 134 +++++++++++++------------- apps/web/process/subsidy/reactions.ts | 18 +++- apps/web/utils/mobx.ts | 38 ++++++++ yarn.lock | 5 + 5 files changed, 127 insertions(+), 69 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index 62c31be..aba4dcc 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -20,6 +20,7 @@ "@trpc/next": "^10.13.0", "@trpc/react-query": "^10.13.0", "@trpc/server": "^10.13.0", + "async-await-queue": "^2.1.4", "axios": "^1.3.4", "dayjs": "^1.11.7", "less": "^4.1.3", diff --git a/apps/web/process/load-kp/reactions.ts b/apps/web/process/load-kp/reactions.ts index 17df36d..fb60e3a 100644 --- a/apps/web/process/load-kp/reactions.ts +++ b/apps/web/process/load-kp/reactions.ts @@ -1,7 +1,7 @@ /* eslint-disable sonarjs/cognitive-complexity */ import eltHelper from '../elt/lib/helper'; import type { ProcessContext } from '@/process/types'; -import { reaction } from 'mobx'; +import { queueReaction } from '@/utils/mobx'; import { omit } from 'radash'; import { message } from 'ui/elements'; @@ -12,9 +12,9 @@ export function common({ store, trpcClient, apolloClient }: ProcessContext) { const { init: initElt } = eltHelper({ apolloClient, store }); - reaction( + queueReaction( () => $calculation.$values.getValue('quote'), - () => { + async () => { const quote = $calculation.element('selectQuote').getOption(); if (!quote || $process.has('LoadKP') || $process.has('Calculate') || $process.has('CreateKP')) @@ -27,74 +27,76 @@ export function common({ store, trpcClient, apolloClient }: ProcessContext) { key, }); - trpcClient.getQuote - .query({ + try { + const { fingap, insurance, payments, values, elt } = await trpcClient.getQuote.query({ values: { quote: quote.value, ...$calculation.$values.getValues(['lead', 'opportunity', 'recalcWithRevision']), }, - }) - .then(({ values, payments, insurance, fingap, elt }) => { - $calculation.$values.setValues( - omit(values, [ - 'lead', - 'opportunity', - 'quote', - 'leadUrl', - 'opportunityUrl', - 'quoteUrl', - 'recalcWithRevision', - 'plPriceRub', - 'discountRub', - 'user', - ]) - ); - - $tables.payments.setValues(payments.values); - - if (insurance.values.osago) { - $tables.insurance.row('osago').setValues(insurance.values.osago); - } - if (insurance.values.kasko) { - $tables.insurance.row('kasko').setValues(insurance.values.kasko); - } - if (insurance.values.fingap) { - $tables.insurance.row('fingap').setValues(insurance.values.fingap); - } - - if (fingap) $tables.fingap.setSelectedKeys(fingap.keys); - - initElt().then((initialValues) => { - if (initialValues) { - $tables.elt.kasko.setRows(initialValues.kasko); - $tables.elt.osago.setRows(initialValues.osago); - } - - if (elt?.kasko) { - $tables.elt.kasko.setRow(elt.kasko); - $tables.elt.kasko.setSelectedKey(elt.kasko.key); - } - if (elt?.osago) { - $tables.elt.osago.setRow(elt.osago); - $tables.elt.osago.setSelectedKey(elt.osago.key); - } - }); - - message.success({ - content: `КП ${quote.label} загружено`, - key, - }); - }) - .catch(() => { - message.error({ - content: `Ошибка во время загрузки КП ${quote.label}`, - key, - }); - $calculation.element('selectQuote').resetValue(); - }) - .finally(() => { - $process.delete('LoadKP'); }); + + $calculation.$values.setValues( + omit(values, [ + 'lead', + 'opportunity', + 'quote', + 'leadUrl', + 'opportunityUrl', + 'quoteUrl', + 'recalcWithRevision', + 'plPriceRub', + 'discountRub', + 'user', + ]) + ); + + $tables.payments.setValues(payments.values); + + if (insurance.values.osago) { + $tables.insurance.row('osago').setValues(insurance.values.osago); + } + if (insurance.values.kasko) { + $tables.insurance.row('kasko').setValues(insurance.values.kasko); + } + if (insurance.values.fingap) { + $tables.insurance.row('fingap').setValues(insurance.values.fingap); + } + + if (fingap) $tables.fingap.setSelectedKeys(fingap.keys); + + initElt().then((initialValues) => { + if (initialValues) { + $tables.elt.kasko.setRows(initialValues.kasko); + $tables.elt.osago.setRows(initialValues.osago); + } + + if (elt?.kasko) { + $tables.elt.kasko.setRow(elt.kasko); + $tables.elt.kasko.setSelectedKey(elt.kasko.key); + } + if (elt?.osago) { + $tables.elt.osago.setRow(elt.osago); + $tables.elt.osago.setSelectedKey(elt.osago.key); + } + }); + + message.success({ + content: `КП ${quote.label} загружено`, + key, + }); + } catch { + message.error({ + content: `Ошибка во время загрузки КП ${quote.label}`, + key, + }); + $calculation.element('selectQuote').resetValue(); + } finally { + $process.delete('LoadKP'); + } + }, + { + name: 'load-kp', + priority: -1, } ); } diff --git a/apps/web/process/subsidy/reactions.ts b/apps/web/process/subsidy/reactions.ts index e5209ff..a605993 100644 --- a/apps/web/process/subsidy/reactions.ts +++ b/apps/web/process/subsidy/reactions.ts @@ -1,6 +1,7 @@ import * as CRMTypes from '@/graphql/crm.types'; import type { ProcessContext } from '@/process/types'; -import { reaction } from 'mobx'; +import { queueReaction } from '@/utils/mobx'; +import { comparer } from 'mobx'; /** * При изменении "Программа от производителя" selectImportProgram , Стоимости ПЛ tbxLeaseObjectPrice, Валюты selectSupplierCurrency, Скидка от поставщика, в валюте поставщика (tbxSupplierDiscountRub) @@ -22,7 +23,7 @@ import { reaction } from 'mobx'; export function common({ store, apolloClient }: ProcessContext) { const { $calculation } = store; - reaction( + queueReaction( () => $calculation.$values.getValues(['importProgram', 'plPriceRub', 'supplierDiscountRub']), async ({ importProgram: importProgramId, plPriceRub, supplierDiscountRub }) => { if (importProgramId) { @@ -48,10 +49,14 @@ export function common({ store, apolloClient }: ProcessContext) { } else { $calculation.element('tbxImportProgramSum').setValue(0); } + }, + { + name: 'tbxImportProgramSum', + priority: 1, } ); - reaction( + queueReaction( () => $calculation.$values.getValues([ 'subsidy', @@ -59,6 +64,7 @@ export function common({ store, apolloClient }: ProcessContext) { 'discountRub', 'addEquipmentPrice', 'importProgramSum', + 'quote', ]), async ({ subsidy: subsidyId, @@ -95,6 +101,12 @@ export function common({ store, apolloClient }: ProcessContext) { if (sum > maxSum) sum = maxSum; $calculation.element('tbxSubsidySum').setValue(sum); + }, + { + delay: 5, + equals: comparer.shallow, + name: 'tbxSubsidySum', + priority: 1, } ); } diff --git a/apps/web/utils/mobx.ts b/apps/web/utils/mobx.ts index c8a86d6..7e5ff11 100644 --- a/apps/web/utils/mobx.ts +++ b/apps/web/utils/mobx.ts @@ -1,3 +1,4 @@ +import { Queue } from 'async-await-queue'; import type { IReactionDisposer, IReactionOptions, IReactionPublic } from 'mobx'; import { reaction } from 'mobx'; import { debounce, omit } from 'radash'; @@ -51,3 +52,40 @@ export function debouncedReaction( return reaction(expression, debouncedEffect, reactionOpts); } + +const queue = new Queue(1, 10); + +export function queueReaction( + expression: (r: IReactionPublic) => T, + effect: ( + arg: T, + prev: FireImmediately extends true ? T | undefined : T, + r: IReactionPublic + ) => Promise, + { + priority, + name, + ...reactionOpts + }: IReactionOptions & { name: string; priority: number } +): IReactionDisposer { + const me = Symbol(name); + + async function queueEffect( + arg: T, + prev: FireImmediately extends true ? T | undefined : T, + r: IReactionPublic + ) { + await queue.wait(me, priority); + + try { + await effect(arg, prev, r); + } catch (error) { + // eslint-disable-next-line no-console + console.error(error); + } finally { + queue.end(me); + } + } + + return reaction(expression, queueEffect, reactionOpts); +} diff --git a/yarn.lock b/yarn.lock index fd2d651..553ed2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2669,6 +2669,11 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +async-await-queue@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/async-await-queue/-/async-await-queue-2.1.4.tgz#0c44a405cd31369b561f6ac663b74b4b4ffb99ad" + integrity sha512-3DpDtxkKO0O/FPlWbk/CrbexjuSxWm1CH1bXlVNVyMBIkKHhT5D85gzHmGJokG3ibNGWQ7pHBmStxUW/z/0LYQ== + async-validator@^4.1.0: version "4.2.5" resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339"