From c152a670aeac21a424c44e998c0507c32b8b0b14 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: Fri, 24 Jul 2026 12:03:16 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20=D1=87=D0=B8=D1=81=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D1=8F=20=D1=81=D0=BE=D1=80=D1=82=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20date/datetime/number=20=D0=BF=D0=BE=D0=BB=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B2=20=D1=80=D0=B5=D0=B5=D1=81=D1=82=D1=80=D0=B5=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D1=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Сортировка кастомных полей шла лексикографически по отображаемой строке: даты «ДД.ММ.ГГГГ» сортировались по дню («01.12.2025» < «02.01.2024»), числа как строки («10» < «9»). Теперь для field_ типов date/datetime/number сравнение идёт по сырому значению (timestamp/число), пустые — всегда в конец. --- server/routes/task-crud-list.routes.ts | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/server/routes/task-crud-list.routes.ts b/server/routes/task-crud-list.routes.ts index 6836767..5416ead 100644 --- a/server/routes/task-crud-list.routes.ts +++ b/server/routes/task-crud-list.routes.ts @@ -267,6 +267,30 @@ export function registerTaskCrudListRoutes(router: ReturnType }; + let numericFieldId: number | null = null; + let numericFieldIsDate = false; + if (sortColumn.startsWith('field_')) { + const fieldId = parseInt(sortColumn.replace('field_', '')); + const field = formFields.find((f) => f.id === fieldId); + if (field && ['date', 'datetime', 'number'].includes(field.type)) { + numericFieldId = fieldId; + numericFieldIsDate = field.type === 'date' || field.type === 'datetime'; + } + } + const toSortNumber = (t: TaskWithFV): number | null => { + const v = t.fieldValues?.[numericFieldId!]; + if (v === undefined || v === null || v === '') return null; + if (numericFieldIsDate) { + const ts = new Date(String(v)).getTime(); + return isNaN(ts) ? null : ts; + } + const n = Number(String(v).replace(/\s/g, '')); + return isNaN(n) ? null : n; + }; + tasks = [...tasks].sort((a, b) => { if (DATE_COLS.has(sortColumn)) { const _a = (a as Record)[sortColumn]; @@ -275,6 +299,15 @@ export function registerTaskCrudListRoutes(router: ReturnType