From 52bec07413ab10389811aba81ca1992689b9de50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=BB=D1=8C=D1=8F=D1=81=20=D0=A1=D1=83=D0=BB=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Jul 2026 11:53:05 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=BD=D0=BE=D0=B6=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B1=D0=BE=D1=80=D0=B0=20=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BE=D1=87=D0=BD=D0=B8=D0=BA=D0=B0=20+=20=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B8=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B8=D0=BF=D0=B0=20=D0=B2=20=D0=A1=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BE=D1=87=D0=BD=D0=B8=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/TaskDetail.tsx | 27 +++++++++++++++++++-------- shared/field-types.ts | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/client/src/pages/TaskDetail.tsx b/client/src/pages/TaskDetail.tsx index fbe3ea8..69d13de 100644 --- a/client/src/pages/TaskDetail.tsx +++ b/client/src/pages/TaskDetail.tsx @@ -256,13 +256,16 @@ function LinkedTaskDisplay({ linkedFormId, taskId, relationType }: { linkedFormI // Компонент для отображения значения из справочника type DirectoryData = { table: { rows: Array<{ id: number; values: string[] }>; columns: Array<{ name: string }> } }; -function TableValueDisplay({ tableId, displayColumn, rowId }: { tableId: number; displayColumn?: string; rowId: string | number }) { +function TableValueDisplay({ tableId, displayColumn, rowId }: { tableId: number; displayColumn?: string; rowId: string | number | Array }) { const { isOnline } = useOfflineSyncContext(); const [offlineData, setOfflineData] = useState(null); + const isArray = Array.isArray(rowId); + const rowIds = isArray ? rowId.map(String) : [String(rowId)]; + const { data: tableData, isLoading } = useQuery({ queryKey: ['/api/directories', tableId], - enabled: !!tableId && !!rowId && isOnline, + enabled: !!tableId && rowIds.length > 0 && isOnline, staleTime: 5 * 60 * 1000, }); @@ -275,12 +278,12 @@ function TableValueDisplay({ tableId, displayColumn, rowId }: { tableId: number; // Load from IDB when offline and live data is unavailable useEffect(() => { - if (!isOnline && !tableData && tableId && rowId) { + if (!isOnline && !tableData && tableId && rowIds.length > 0) { getDirectory(tableId).then(cached => { if (cached) setOfflineData(cached.data as DirectoryData); }).catch(() => {}); } - }, [isOnline, tableData, tableId, rowId]); + }, [isOnline, tableData, tableId, rowIds]); const effectiveData = tableData ?? offlineData; @@ -289,18 +292,26 @@ function TableValueDisplay({ tableId, displayColumn, rowId }: { tableId: number; const table = effectiveData?.table; if (!table) return Таблица не найдена; - const row = table.rows?.find(r => r.id.toString() === rowId?.toString()); - if (!row) return Запись не найдена; - let displayColumnIndex = table.columns?.findIndex(c => c.name === displayColumn); if (displayColumnIndex === undefined || displayColumnIndex < 0) { displayColumnIndex = 0; } + const rows = table.rows || []; + const labels = rowIds + .map((id) => { + const row = rows.find((r) => r.id.toString() === id); + if (!row) return null; + return row.values[displayColumnIndex] || row.values[0] || `#${id}`; + }) + .filter(Boolean); + + if (labels.length === 0) return Запись не найдена; + return ( - {row.values[displayColumnIndex] || row.values[0]} + {labels.join(', ')} ); } diff --git a/shared/field-types.ts b/shared/field-types.ts index bad6db5..acda656 100644 --- a/shared/field-types.ts +++ b/shared/field-types.ts @@ -27,7 +27,7 @@ export const FIELD_TYPE_DEFINITIONS: FieldTypeDef[] = [ { id: "textarea", label: "Многострочный текст", iconName: "AlignLeft", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] }, { id: "rich-text", label: "Богатый текстовый редактор", iconName: "FileText", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] }, { id: "history-number", label: "Числовое поле с историей", iconName: "History", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] }, - { id: "table", label: "Выбор из таблицы", iconName: "Table", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] }, + { id: "table", label: "Справочник", iconName: "Table", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] }, { id: "task", label: "Связь с задачей", iconName: "Link2", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] }, { id: "company", label: "Организация (DaData)", iconName: "Building2", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] }, { id: "geo", label: "Адрес с координатами", iconName: "MapPin", supportsOptions: false, allowedIn: ["form", "global", "table", "user"] },