fix(price-types): IsRequired применяется сразу, без перезагрузки страницы
Some checks are pending
Some checks are pending
Баг: переключение «Обязательная» в /catalog/price-types не приводило
к валидации в карточке товара — Save шёл и проходил, не требуя цену.
Корневая причина — два разных queryKey:
- useCatalogMutations в PriceTypesPage инвалидирует
['/api/catalog/price-types'] (для самой List-страницы),
- но usePriceTypes-хук, которым пользуется ProductEditPage и
ProductsPage, живёт под ключом ['lookup:price-types'].
В итоге свежий снапшот справочника не доходит до потребителей.
Фикс:
- useLookups: staleTime=0 + refetchOnMount: 'always' +
refetchOnWindowFocus=true. Любой переход на ProductEditPage
делает свежий GET и видит актуальный IsRequired/IsRetail.
- PriceTypesPage save/delete: дополнительно вызывают
qc.invalidateQueries({ queryKey: ['lookup:price-types'] }) —
потребители тут же перерендериваются, без необходимости F5.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bcc6976bd0
commit
defad7cbb4
|
|
@ -9,7 +9,14 @@ function useLookup<T>(key: string, url: string) {
|
|||
return useQuery({
|
||||
queryKey: [`lookup:${key}`],
|
||||
queryFn: async () => (await api.get<PagedResult<T>>(`${url}?pageSize=500`)).data.items,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
// staleTime=0 + refetchOnMount: 'always' гарантируют что любая страница
|
||||
// (например ProductEditPage), монтирующая usePriceTypes / useUnits / etc,
|
||||
// сразу подтянет свежий снапшот справочника после правки в его UI —
|
||||
// без необходимости явно прокидывать invalidate-pair (lookup-ключ ↔
|
||||
// URL-ключ useCatalogMutations).
|
||||
staleTime: 0,
|
||||
refetchOnMount: 'always',
|
||||
refetchOnWindowFocus: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { Button } from '@/components/Button'
|
|||
import { Modal } from '@/components/Modal'
|
||||
import { Field, TextInput, Checkbox } from '@/components/Field'
|
||||
import { useCatalogList, useCatalogMutations } from '@/lib/useCatalog'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import type { PriceType } from '@/lib/types'
|
||||
|
||||
const URL = '/api/catalog/price-types'
|
||||
|
|
@ -26,6 +27,7 @@ export function PriceTypesPage() {
|
|||
const { data, isLoading, page, setPage, search, setSearch, sortKey, sortOrder, setSort } = useCatalogList<PriceType>(URL)
|
||||
const { create, update, remove } = useCatalogMutations(URL, URL)
|
||||
const [form, setForm] = useState<Form | null>(null)
|
||||
const qc = useQueryClient()
|
||||
|
||||
const save = async () => {
|
||||
if (!form) return
|
||||
|
|
@ -33,6 +35,11 @@ export function PriceTypesPage() {
|
|||
void _omit
|
||||
if (id) await update.mutateAsync({ id, input: payload })
|
||||
else await create.mutateAsync(payload)
|
||||
// useCatalogMutations инвалидирует ['/api/catalog/price-types'] (List на этой
|
||||
// странице), но usePriceTypes-хук живёт под ключом 'lookup:price-types' —
|
||||
// явно тригерим перефетч чтобы карточка товара сразу увидела новый
|
||||
// IsRequired/IsRetail без перезагрузки страницы.
|
||||
await qc.invalidateQueries({ queryKey: ['lookup:price-types'] })
|
||||
setForm(null)
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +93,7 @@ export function PriceTypesPage() {
|
|||
<Button variant="danger" size="sm" onClick={async () => {
|
||||
if (confirm('Удалить тип цены?')) {
|
||||
await remove.mutateAsync(form.id!)
|
||||
await qc.invalidateQueries({ queryKey: ['lookup:price-types'] })
|
||||
setForm(null)
|
||||
}
|
||||
}}>
|
||||
|
|
|
|||
Loading…
Reference in a new issue