Commit Graph

285 Commits

Author SHA1 Message Date
96e088c890 fix(gps): фильтр несогласованности скоростей против LBS-телепортов; fix: плейхед не закрывает balloon точек трека 2026-08-28 10:33:45 +03:00
ac4f89d42e feat(gps): фильтры heartbeat-эхо/valid=false/spike; доступ к GPS и Финансам — матрица на /users (пользователи+роли) 2026-08-26 17:13:49 +03:00
2fb7ad6606 fix(pwa): добавлен interactive-widget=resizes-content в viewport
Без этого на Android при открытии клавиатуры viewport не уменьшался,
и поле ввода сообщения в чате/задаче перекрывалось клавиатурой
или «убегало» вверх вместе с контентом.
2026-08-26 15:10:09 +03:00
5e8103a6da fix(push): bump SW to v12, улучшен openOrFocusChat и notificationclick
- openOrFocusChat: includeUncontrolled=true, логирование, try/catch, fallback на clients.openWindow.
- notificationclick: логирование data, fallback построения URL из вложенного data.data.
- markNotificationRead: поддержка type/messageId/conversationId на верхнем уровне и во вложенном data.
- Bump CACHE_NAME до v12 для принудительного обновления SW.
2026-08-26 14:54:37 +03:00
8a649541fb feat(button): связь parent/child и копирование полей для кнопки создания задачи
- В настройках кнопки «Создать задачу по форме» добавлен выбор связи: новая задача — родительская или дочерняя (task_relations).
- Добавлено копирование значений полей из текущей задачи в новую через визуальный маппинг в отдельном диалоге (ButtonCopyFieldsDialog).
- Маппинг хранится в form_fields.options.copyFields, связь — в options.relationType.
- CreateTaskDialog/CreateTaskFormContent поддерживают initialValues (объектные значения) и parentTaskId.
2026-08-26 11:24:56 +03:00
8f5789ec28 feat(gps): фокус геозоны на карте, город по умолчанию для всех карт, доступ к GPS по пользователям/ролям (админ) 2026-08-26 10:20:38 +03:00
3e8849019a feat(gps): скорость в км/ч (конверсия узлов Traccar + backfill), деление маршрута на поездки, проигрывание от любой точки, скорости x100-x1000 2026-08-26 09:24:29 +03:00
a4b508f70e fix(gps): гистерезис подтверждения jump-кандидата — latch-up на LBS, реальные переезды принимаются после 3 точек 2026-08-25 18:06:43 +03:00
3d24a15fb3 fix(gps): отсев устаревших копий и LBS-телепортов (stale/jump фильтры), настройка maxJumpSpeedKmh, фильтрация трека при выдаче 2026-08-25 17:49:38 +03:00
b635d1e16e feat(gps): last_seen по времени приёма, фильтр джиттера (настройки), линейка, трек по скорости; fix: карта не перекрывает диалоги (isolation) 2026-08-25 17:01:44 +03:00
670cecfe05 feat(gps): список объектов по клику на кластер, стрелки направления на точках трека; fix: хитбокс маркеров (попапы точек трека) 2026-08-25 16:15:02 +03:00
39c70033e3 feat(gps): кластеризация маркеров объектов (ymaps.Clusterer + leaflet.markercluster), точки трека со скоростью в попапах 2026-08-25 15:26:35 +03:00
bde9c2a641 feat(gps): левая панель-дерево объектов вместо select'ов; fix(csp): разрешён api-maps.yandex.ru для JS API 2.1 2026-08-25 14:59:09 +03:00
c7aac447bc feat(gps): Яндекс-подложка переведена на JS API 2.1 (v3 без бесплатного тарифа), общий marker-html для обеих подложек 2026-08-25 14:29:47 +03:00
4018ee0f1b feat(gps): SinoTrack ST-901L в справочнике — порт 5013 (H02), проверено на реальном устройстве 2026-08-25 13:51:25 +03:00
f6e3e1964c Кнопка На себя у поля Ответственный в TaskDetail и меню дополнительных действий в TaskChat 2026-08-25 10:13:36 +03:00
a7cf1b2c97 fix(gps): убран '--' из XML-комментария в traccar.xml.example (SAXParseException) 2026-08-24 22:25:26 +03:00
7fe636b56c feat(gps): вкладка «Инструкции» со справочником настройки трекеров + открыты порты протоколов (Teltonika, GPS103, H02, Suntech) 2026-08-24 22:15:34 +03:00
a6a42fdb15 feat(gps): бесплатная подложка OSM с авто-fallback и ручным переключателем провайдера карты 2026-08-24 21:05:22 +03:00
541248b103 chore: traccar.xml вынесен в .gitignore (шаблон traccar.xml.example), forward.type=json 2026-08-24 19:42:26 +03:00
104b3ca422 feat: модуль GPS-мониторинга (карта Яндекс.Карт, Traccar, геозоны, маршруты, группы) 2026-08-24 19:30:11 +03:00
c0e2ddd9c8 Исправлено дублирование сообщений в task-чате: защита от двойного Enter/клика по кнопке отправки 2026-08-24 16:53:25 +03:00
8b713e66c0 Исправлено дублирование сообщений в task-чате: защита от двойного Enter/клика по кнопке отправки 2026-08-24 16:50:05 +03:00
422eafd41f Дополнительное ускорение появления просмотренных задач во вкладке Последние: refetchOnMount always и refetch при переключении на recent 2026-08-24 16:35:01 +03:00
709d4cbfa3 Ускорено появление просмотренных задач во вкладке Последние: фоновый refetch всех home-запросов и refetchOnWindowFocus для recent 2026-08-24 16:22:56 +03:00
a4eaf65915 Отслеживание просмотров задач: task_views, POST /api/tasks/:id/view и обновление /api/home/recent 2026-08-24 15:40:30 +03:00
74abd8fad5 Исправлен клик по push-уведомлению: открытие задачи/чата из тела, Ответить и Прочитано; controlled-clients + fallback openWindow 2026-08-21 16:03:47 +03:00
5eb98c399a Кнопка create_task открывает CreateTaskDialog вместо несуществующего маршрута 2026-08-21 14:00:39 +03:00
e93e39383f Исправлено сохранение настроек кнопки (buttonActionType, buttonUrl, buttonFormId) в bulkSaveFormFields 2026-08-21 11:42:43 +03:00
e24df563df Добавлен выбор режима условия для table-полей в переходах: по значению или пользователь из колонки 2026-08-20 15:11:27 +03:00
281f8da995 fix: rate limiting по пользователям из JWT + cleanup WebPush подписок и cooldown sync-push 2026-08-20 14:17:13 +03:00
5ff2aaa023 fix: RAG embedding_queue ON CONFLICT + пересоздание finance views
- enqueueEmbedding: onConflictDoNothing без предиката не находил
  частичный уникальный индекс embedding_queue_pending_entity_idx
  (WHERE processed_at IS NULL) — каждая постановка в очередь индексации
  падала. Добавлен where: isNull(processedAt).
- finance ensureViews: CREATE OR REPLACE VIEW не умеет менять тип столбца
  (stavkands text↔varchar во внешней БД omegaprom) — заменено на
  DROP VIEW IF EXISTS + CREATE VIEW (зависимых объектов нет).
2026-08-06 15:10:38 +03:00
47869971e6 feat: объединение страниц профиля — /profile рендерит карточку пользователя
- /profile теперь обёртка MyProfilePage над UserProfilePage (один экран для своего и чужого профиля)
- self-вкладки из ProfileSettings перенесены: Уведомления, Offline, Интерфейс, Безопасность (components/profile/*)
- ProfileSettings.tsx удалён
- админ видит вкладки Уведомления и Offline на чужой карточке с данными целевого пользователя
  (userId-параметр в GET/POST /api/subscriptions, PATCH/DELETE по владельцу, GET /api/sync/config?userId=; проверка canManageUser)
- Роль/Активен/Статус disabled для не-админа (сервер их и раньше игнорировал)
- пункт меню «Настройки профиля» переименован в «Мой профиль»
2026-08-05 11:48:07 +03:00
667bddeac9 feat: замещение пользователей (substitution) — заместители по умолчанию и по формам, контур ознакомления, inbox reasons
- таблица user_delegations (миграция 0067) + колонки delegated_from_user_id/pending_review в task_assignees
- delegation.service: резолвер с цепочкой и защитой от циклов, bulk-до-назначение чанками, чистка истёкших замещений
- центральный хук в addTaskAssignee: заместитель добавляется при любом назначении (ручном, автопереходе, user-поле, MCP)
- контур ознакомления: после перехода отсутствующий остаётся в исполнителях с pending_review, снимается кнопкой «Ознакомлен»
- inbox reasons delegation/delegation_review + фильтр «Замещение» на главной
- блок «Замещение» в профиле пользователя, бейдж «за <имя>» и баннер ознакомления в карточке задачи
2026-08-05 10:44:55 +03:00
17a8dc42f2 fix(ui): второй пакет ревью better-interface — каркас, чат, реестр, настройки
HIGH:
- chat: действия над сообщением доступны на мобильном (меню ⋯)
- iOS-зум: базовые input/textarea text-base, auth-экраны 16px
- контент не перекрыт нижней навигацией на iPhone (safe-area)
- контрасты: billing-оверлей, бот-кнопка, заголовки задач (text-primary)
- клавиатура: входящие на Главной, aria-label нижней навигации, триггер чата button
- confirm() → AlertDialog (сайдбар, чат, настройки)
- счётчики непрочитанных 7-8px → 10px

MEDIUM:
- офлайн-баннеры и бейджи на токенах warning/success/info/destructive
- transition-all → точечные свойства в примитивах ui
- шрифты: Inter без дублей (24 семейства → 2), letter-spacing с body убран
- prefers-reduced-motion kill-switch
- autocomplete + aria на auth/профиле, ошибки пароля у поля
- SPA: document.title + фокус на main при навигации, тост с action без таймера
- FormEditor: превью на Dialog, табы скроллятся на мобильном, без инлайн-стилей
- empty states с запросом и «Сбросить фильтры», UX-тексты
2026-08-04 19:20:59 +03:00
7d975b0b00 fix(ui): пакет фиксов по ревью better-interface (HIGH+MEDIUM)
HIGH:
- mobile: поля задачи доступны для форм без вкладок (fallback-аккордеон)
- удаление вложений доступно на тач-устройствах (кнопка всегда видна)
- бейдж статуса: контрастный текст по яркости (statusColor.ts), также в реестре и канбане
- кнопки согласования: контрастные дефолты #15803d/#b91c1c + текст по яркости
- клавиатура: focus-visible у карандаша, focus-ring у поиска, InlineField с клавиатуры

MEDIUM:
- iOS: инпуты text-base на мобильном (убран зум при фокусе)
- системные поля унифицированы с кастомными (inline label+value)
- тач-таргеты ≥32px, кнопка удаления задачи отделена ms-auto
- токены --warning/--success/--info во всех скинах, хардкод-цвета → семантика
- заголовок задачи крупнее + title с полным текстом; мелкий текст ≥11px
- UX-тексты: «Не удалось …» вместо «Ошибка», имена вместо ID
- button.tsx: без transition-all, глобальный active:scale-[0.96]
- ARIA: aria-label инпутам, role=alert ошибкам, Escape в dropdown
2026-08-04 09:36:13 +03:00
d562735eca 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
2026-08-03 22:20:30 +03:00
8a8c798eb7 feat(TaskDetail): per-field inline-редактирование вместо глобального режима
- Клик по полю редактирует только его; автосохранение по blur/Enter/выбору, Esc — отмена
- Одиночный PATCH /api/tasks/:id/field-values/:fieldId + optimistic-кэш + офлайн-очередь
- Строка поля: фиксированные метрики read=edit (min-h 32/40px), редактор в потоке — ноль layout shift
- Удалены глобальный edit-режим, draft-машинерия, batch-сохранение и StickyActionBar
- Удалён мёртвый код components/task-detail/ (NotionFieldRow, useInlineEdit, useDirtyFields)
- Новый редактор checklist; составные редакторы сохраняют по закрытию
- Полировка: hover-подсветка, карандаш по hover, fade-in, семантические токены, тач-таргеты 40px
2026-08-03 17:17:59 +03:00
9a387c5db0 fix: бесконечный ретрай upload 400, скобки в именах файлов, тост batch-create
- useOfflineSync: tryUploadFile/trySendAttachmentMessage бросали ошибку без
  кода статуса — постоянная 400 не распознавалась regex \b400\b и вложение
  ретраилось бесконечно (спам POST /api/upload каждые ~30 сек).
- validateFilename: разрешены скобки () в именах (типично для фото с
  телефонов; сохраняемое имя всё равно генерируется), в текст 400 добавлено
  само имя файла для диагностики.
- BatchCreateDialog: тост ошибки показывает текст сервера (из BadRequestError
  или JSON в message 5xx) вместо общего «Ошибка создания задач».
2026-08-03 15:25:11 +03:00
1d5321ed0c feat: чанкинг batch-create >100 задач + журнал ошибок API
B: BatchCreateDialog режет список на чанки ≤100 (лимит сервера), каждый
чанк со своим idempotency-key (requestId-N) — повтор после ошибки не
создаёт дублей; 10-минутный лок армируется только при полном успехе,
а не до запроса (раньше блокировал даже после 400).

D: таблица error_logs (миграция 0066), захват ответов >=400 в request
middleware (без 401/health/events, дедуп 60с), admin API GET/DELETE
/api/error-logs и вкладка «Журнал ошибок» в Настройках.
2026-08-03 14:55:29 +03:00
1bb6a53226 feat: закрытые задачи в глобальном поиске зачёркнуты + бейдж статуса
searchTasksByKeyword теперь возвращает isCompleted и через leftJoin
formStatuses — statusName/statusColor/statusIsFinal. В HomeGlobalSearch
закрытые задачи (isCompleted || statusIsFinal) зачёркнуты и приглушены,
у каждой задачи цветной бейдж текущего статуса.
2026-08-03 13:29:36 +03:00
4ace1369ca fix: согласующие перехода — только авторизация, без автоназначения
assigneeUserId/assigneeConditions перехода раньше и давали право нажать
кнопку, и молча переназначали задачу на согласующего; кликнувший также
всегда добавлялся в task_assignees (список «Ответственный»).
Теперь ответственный при переходе всегда сохраняется, кликнувший в
ответственные не добавляется (доступ трекается через recordTransitionAccess).
В FormEditor добавлена подсказка о семантике блока «Согласующие».
2026-08-03 11:18:14 +03:00
a701b06394 fix: явный flex-row для горизонтального расположения бейджей 2026-07-24 16:35:18 +03:00
fd8d27e3d2 fix: поле 200px, бейджи в отдельном flex-контейнере рядом 2026-07-24 16:25:45 +03:00
e5f8dbce42 fix: ограничена максимальная ширина поля справочника для размещения бейджей рядом 2026-07-24 16:13:40 +03:00
d72cdc8af1 fix: адаптивная ширина поля справочника, бейджи рядом 2026-07-24 15:53:04 +03:00
a969af9086 fix: w-auto контейнер для компактного отображения поля и бейджей 2026-07-24 15:37:48 +03:00
0c5e95a201 fix: inline-flex контейнер для компактного отображения поля и бейджей 2026-07-24 15:20:34 +03:00
b08b906222 fix: фиксированная ширина поля справочника 200px, бейджи рядом 2026-07-24 15:04:33 +03:00
1a89ab50ef fix: поле справочника не растягивается на всю ширину, бейджи рядом 2026-07-24 14:45:45 +03:00