fix(TaskDetail): фиксы per-field редактирования по тестам прода

- server: rich-text/company/task разрешены в PATCH field-values (была 400, поля не сохранялись)
- user-поле: дропдаун открывается сразу при редактировании, текущее значение всегда в списке
- select.tsx: viewport max-h-60 вместо высоты триггера (список показывал 1 пункт)
- плотность строк: min-h 28/36px, leading-5, read-only системные строки — py-1 как раньше
- вход в редактирование: double-click/double-tap (одиночный клик — только карандаш)
- textarea/table/task/company: компактная ширина редакторов, h-7
- сброс pendingAutofillRef при отмене; нативный select не отменяется по blur
This commit is contained in:
2026-08-03 22:20:30 +03:00
parent 8a8c798eb7
commit d562735eca
4 changed files with 118 additions and 44 deletions

View File

@@ -457,7 +457,7 @@ export function registerTaskFieldRoutes(router: ReturnType<typeof import("expres
return res.status(400).json({ success: false, error: immutableErrorsSingle.join('\n') });
}
const INLINE_EDITABLE_FIELD_TYPES = new Set(['text', 'number', 'textarea', 'date', 'datetime', 'select', 'radio-group', 'checkbox', 'toggle', 'user', 'file', 'geo', 'contract-number', 'table', 'checklist', 'contact', 'document_template']);
const INLINE_EDITABLE_FIELD_TYPES = new Set(['text', 'number', 'textarea', 'rich-text', 'date', 'datetime', 'select', 'radio-group', 'checkbox', 'toggle', 'user', 'file', 'geo', 'contract-number', 'table', 'checklist', 'contact', 'company', 'task', 'document_template']);
if (!INLINE_EDITABLE_FIELD_TYPES.has(field.type)) {
return res.status(400).json({ success: false, error: `Поле типа «${field.type}» не поддерживает inline-редактирование` });
}
@@ -630,7 +630,7 @@ export function registerTaskFieldRoutes(router: ReturnType<typeof import("expres
}
const fieldIds = entries.map(([k]) => parseInt(k, 10));
const INLINE_EDITABLE_FIELD_TYPES = new Set(['text', 'number', 'textarea', 'date', 'datetime', 'select', 'radio-group', 'checkbox', 'toggle', 'user', 'file', 'geo', 'checklist', 'contact', 'document_template']);
const INLINE_EDITABLE_FIELD_TYPES = new Set(['text', 'number', 'textarea', 'rich-text', 'date', 'datetime', 'select', 'radio-group', 'checkbox', 'toggle', 'user', 'file', 'geo', 'contract-number', 'table', 'checklist', 'contact', 'company', 'task', 'document_template']);
const formFields = await storage.getFormFields(existingTask.formId, req.organizationId!);
const fieldMap = new Map(formFields.map(f => [f.id, f]));
const existingValues = await storage.getTaskFieldValues(taskId, req.organizationId!);