From 9e6ddd1bcee459a5eedd688b6ba2f032966c5a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=97=D0=B8=D0=BC=D0=B8=D0=BD?= Date: Thu, 14 May 2026 20:42:45 +0000 Subject: [PATCH] fix(ui): replace raw AxiosError dumps with QueryErrorState across routes --- .../lineage/CascadeConfirmDialog.tsx | 12 ++++---- .../src/routes/dictionaries.$name.tsx | 30 +++++++++---------- ordinis-admin-ui/src/routes/my-drafts.tsx | 17 ++++++----- ordinis-admin-ui/src/routes/reviews.tsx | 4 +-- .../src/routes/webhooks.index.tsx | 10 +++---- 5 files changed, 34 insertions(+), 39 deletions(-) diff --git a/ordinis-admin-ui/src/components/lineage/CascadeConfirmDialog.tsx b/ordinis-admin-ui/src/components/lineage/CascadeConfirmDialog.tsx index a74110b..a7114fa 100644 --- a/ordinis-admin-ui/src/components/lineage/CascadeConfirmDialog.tsx +++ b/ordinis-admin-ui/src/components/lineage/CascadeConfirmDialog.tsx @@ -1,6 +1,6 @@ import { useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { Alert, Badge, Button, LoadingBlock, Modal, TextInput } from '@/ui' +import { Alert, Badge, Button, LoadingBlock, Modal, QueryErrorState, TextInput } from '@/ui' import { WarningIcon, XCircleIcon } from '@phosphor-icons/react' import { useCascadePreview } from '@/api/queries' import { useCascadeCloseRecord } from '@/api/mutations' @@ -116,9 +116,7 @@ export const CascadeConfirmDialog = ({ {preview.isLoading && } {preview.error && ( - - {String(preview.error)} - + preview.refetch()} /> )} {plan && ( @@ -261,9 +259,9 @@ export const CascadeConfirmDialog = ({ )} {cascadeMut.error && ( - - {String(cascadeMut.error)} - + /* Mutation error — no retry button (user triggers via Confirm + again). QueryErrorState classifies 4xx/5xx code/message. */ + )} )} diff --git a/ordinis-admin-ui/src/routes/dictionaries.$name.tsx b/ordinis-admin-ui/src/routes/dictionaries.$name.tsx index bcc637f..fce8674 100644 --- a/ordinis-admin-ui/src/routes/dictionaries.$name.tsx +++ b/ordinis-admin-ui/src/routes/dictionaries.$name.tsx @@ -967,9 +967,10 @@ function DictionaryDetail() { {recordsResult.isLoading && } {recordsResult.error && ( - - {String(recordsResult.error)} - + recordsResult.refetch()} + /> )} {recordsResult.data && recordsResult.data.length === 0 && ( @@ -1279,9 +1280,10 @@ function DictionaryDetail() { )} {detailQuery.data && edit.kind === 'edit' && rawRecordQuery.error && ( - - {String(rawRecordQuery.error)} - + rawRecordQuery.refetch()} + /> )} {detailQuery.data && edit.kind === 'edit' && rawRecordQuery.data && ( @@ -2086,7 +2088,8 @@ function highlightJson(json: string): string { */ function EventsTabContent({ dictName }: { dictName: string }) { const { t } = useTranslation() - const { data, isLoading, error } = useAudit({ dictionaryName: dictName, size: 50 }) + const auditQ = useAudit({ dictionaryName: dictName, size: 50 }) + const { data, isLoading, error } = auditQ // Filter chips per prototype: все / edit / publish / review / webhook / export. // Backend audit actions: CREATE / UPDATE / CLOSE / EXPORT etc. — map to display // groups for chip filter. @@ -2094,11 +2097,7 @@ function EventsTabContent({ dictName }: { dictName: string }) { if (isLoading) return if (error) - return ( - - {String(error)} - - ) + return auditQ.refetch()} /> const rows = data?.content ?? [] if (rows.length === 0) return ( @@ -2298,7 +2297,8 @@ function EventsTabContent({ dictName }: { dictName: string }) { function HistoryTabContent({ detail }: { detail?: import('@/api/client').DictionaryDetail }) { const { t } = useTranslation() const [diffEntryId, setDiffEntryId] = useState(undefined) - const { data, isLoading, error } = useChangelog(detail?.name) + const changelogQ = useChangelog(detail?.name) + const { data, isLoading, error } = changelogQ if (!detail) return null @@ -2306,9 +2306,7 @@ function HistoryTabContent({ detail }: { detail?: import('@/api/client').Diction
{isLoading && } {error && ( - - {String(error)} - + changelogQ.refetch()} /> )} {data && data.entries.length === 0 && ( )} + {/* QueryErrorState classifies status code (502 → "Сервис временно + недоступен", timeout → "Запрос превысил время ожидания", etc.) и + показывает retry button. Раньше тут был {String(error)} + который дампил raw AxiosError юзеру — анти-паттерн UX. */} {drafts.error && ( - - {String(drafts.error)} - + drafts.refetch()} /> )} {schemaDrafts.error && ( - - {String(schemaDrafts.error)} - + schemaDrafts.refetch()} + /> )} {bothEmpty && } diff --git a/ordinis-admin-ui/src/routes/reviews.tsx b/ordinis-admin-ui/src/routes/reviews.tsx index cb6f55b..5d9b25d 100644 --- a/ordinis-admin-ui/src/routes/reviews.tsx +++ b/ordinis-admin-ui/src/routes/reviews.tsx @@ -715,9 +715,7 @@ function ReviewDrawer({ draftId, onClose }: DrawerProps) {
{draftQ.isLoading && } {draftQ.error && ( - - {String(draftQ.error)} - + draftQ.refetch()} /> )} {draft && ( diff --git a/ordinis-admin-ui/src/routes/webhooks.index.tsx b/ordinis-admin-ui/src/routes/webhooks.index.tsx index 225b91d..e28f188 100644 --- a/ordinis-admin-ui/src/routes/webhooks.index.tsx +++ b/ordinis-admin-ui/src/routes/webhooks.index.tsx @@ -12,6 +12,7 @@ import { MultiSelect, PageHeader, Panel, + QueryErrorState, Table, TableBody, TableCell, @@ -79,7 +80,8 @@ const EVENT_TYPE_OPTIONS: SelectOption[] = [ function WebhooksPage() { const { t } = useTranslation() - const { data, isLoading, error } = useWebhookSubscriptions() + const subsQ = useWebhookSubscriptions() + const { data, isLoading, error } = subsQ const [createOpen, setCreateOpen] = useState(false) const [revealedSecret, setRevealedSecret] = useState<{ name: string @@ -94,11 +96,7 @@ function WebhooksPage() { if (isLoading) return if (error) { - return ( - - {String(error)} - - ) + return subsQ.refetch()} /> } return (