From 7d86b7ed73afd362b84d6906e4b99e617fba7f43 Mon Sep 17 00:00:00 2001 From: nns <278048682+nurdotnet@users.noreply.github.com> Date: Sat, 25 Apr 2026 12:39:25 +0500 Subject: [PATCH] =?UTF-8?q?fix(money-input):=20=D0=BA=D0=BE=D1=80=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D0=BD=D0=BE=D0=B5=20=D0=BE=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20allowFractionalPrices=20?= =?UTF-8?q?=D0=B1=D0=B5=D0=B7=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Главная причина бага: useOrgSettings имел staleTime=5 минут. Когда пользователь переключал галку в /settings/organization, инвалидация ключа `/api/organization/settings` помечала кэш stale, но MoneyInput в открытой форме товара продолжал получать старое значение из кэша до момента, пока сабскрайбер не делал перефетч. На свежем монтировании (переход с /settings обратно на /catalog/products/...) перефетча тоже не происходило, т.к. данные считались всё ещё валидными. Фикс: - useOrgSettings: staleTime=0 + refetchOnMount: 'always' + refetchOnWindowFocus=true. Каждое монтирование компонента — свежие настройки одним лёгким GET'ом. Цена нулевая, цикл «изменил настройку — открыл форму — увидел эффект» теперь работает без перезагрузки. - OrganizationSettingsPage: useEffect синхронизирует form со settings.data без условия `!form` — при свежем рефетче форма тоже подтягивает актуальное. Все вызовы MoneyInput в формах уже не передают allowFractional — компонент сам читает useOrgSettings, что вместе с фиксом выше даёт корректное поведение. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/food-market.web/src/lib/useOrgSettings.ts | 8 +++++++- .../src/pages/OrganizationSettingsPage.tsx | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/food-market.web/src/lib/useOrgSettings.ts b/src/food-market.web/src/lib/useOrgSettings.ts index eb2fe13..85a7d24 100644 --- a/src/food-market.web/src/lib/useOrgSettings.ts +++ b/src/food-market.web/src/lib/useOrgSettings.ts @@ -21,6 +21,12 @@ export function useOrgSettings() { return useQuery({ queryKey: ['/api/organization/settings'], queryFn: async () => (await api.get('/api/organization/settings')).data, - staleTime: 5 * 60 * 1000, + // Настройки меняются редко, но переключатели вроде AllowFractionalPrices + // должны применяться к открытым в других вкладках формам сразу. Поэтому + // staleTime=0 + refetchOnMount: 'always' — каждый монтирующийся компонент + // получает свежие настройки. Стоимость минимальная: один лёгкий GET. + staleTime: 0, + refetchOnMount: 'always', + refetchOnWindowFocus: true, }) } diff --git a/src/food-market.web/src/pages/OrganizationSettingsPage.tsx b/src/food-market.web/src/pages/OrganizationSettingsPage.tsx index 5038f70..6495173 100644 --- a/src/food-market.web/src/pages/OrganizationSettingsPage.tsx +++ b/src/food-market.web/src/pages/OrganizationSettingsPage.tsx @@ -14,7 +14,10 @@ export function OrganizationSettingsPage() { const countries = useCountries() const [form, setForm] = useState(null) - useEffect(() => { if (settings.data && !form) setForm(settings.data) }, [settings.data, form]) + // Синхронизируем форму с актуальным снимком настроек: первый раз — после + // загрузки; и каждый раз когда сервер вернул свежую версию (например после + // refetchOnMount или после save в другой вкладке). + useEffect(() => { if (settings.data) setForm(settings.data) }, [settings.data]) // При смене страны подтягиваем её валюту и ставку НДС (оба read-only, из справочника стран). const onCountryChange = (countryCode: string) => {