Commit Graph

3 Commits

Author SHA1 Message Date
Zimin A.N. d9df2fc359 feat(ui): batch UI polish — auth/lang to sidebar, search h-7, info overflow, graph zoom
User feedback batch — multiple iterations of UX refinement.

Layout shifts:
- TopBar right cluster: AuthBadge + LanguageSwitch переехали в Sidebar
  footer per user ("вход в сайдбар перенесем", "ru/en тоже в сайд баре").
  TopBar теперь: breadcrumb + search + Docs + VersionBadge + ThemeSwitch
  only. Освобождает место + concentrates user/lang controls в одном месте.
- Sidebar footer: новая структура — Lang toggle (Язык [RU/EN]) + Auth block
  (avatar+name+logout authed, Sign-in CTA anonymous) + collapse button.
  Refactored из inline JSX в named subcomponents (AuthedUserBlock,
  SignInCta, SidebarFooter).

Sizing / spacing:
- TopBar SearchInput: h-9 → h-7 to match LangSwitch/ThemeSwitch (+ Sign-in
  кнопка). User: "поиск по справочникам высоту выровняй". Override via
  `!h-7 text-cell` className на SearchInput.
- TopBar: h-14 → h-11 (slimmer). Sidebar logo block matches h-11.

Catalog search:
- Catalog page input в toolbar — restored для on-page filter ("Catalog
  search никак не работает" → проверил, работает; добавил TopBar context-
  aware behavior где TopBar input на /dictionaries route синхронизируется
  с URL ?q= live).
- TopBar search context-aware: catalog mode = live filter; else = submit
  → /search (records JSONB search).

InfoPanel:
- Description: `text-body text-ink-2 leading-relaxed` → +
  `break-words overflow-hidden`. Long slash-separated values
  (LZW/Deflate/JPEG2000/ZSTD/LERC) теперь wrap'ятся внутри panel вместо
  overflow за границы (user: "описание убежало за границы панели").
- Container: + `min-w-0 overflow-hidden` для proper flex shrinking.

Graph:
- Zoom controls overlay (+/-/1:1/N%) + mouse wheel zoom toward cursor +
  drag pan по empty space. Per user: "Граф связей еще не зумируется".

WorkflowBanner:
- Moved в InfoPanel banner slot (compact flex-col layout) — free
  horizontal space выше editor + concentrates status info в left rail.

Auth:
- AuthBadge: primary Button → compact h-7 outline button. Matches
  TopBar toolbar control style.
- RequireAuth: убран visible amber error banner "Авторизация недоступна:
  Failed to fetch" — silent fall-through к anonymous mode (user feedback).
- routes/index.tsx: beforeLoad skip redirect если есть `?code=` в URL
  (OIDC callback fix). HomeIndex компонент рендерит null + redirect на
  /dictionaries после auth complete.

LanguageSwitch:
- h-8 + items-stretch + inner items-center — matches ThemeSwitch height.
- Later moved entirely в Sidebar footer (h-7 button only) per user.
2026-05-11 21:50:21 +03:00
Zimin A.N. 7a3b31b957 feat(mobile): Sidebar drawer <1024px + Modal/Sheet fullscreen <880px
Per design_handoff_ordinis_mdm/README.md responsive table (line 464-465):
- ≤1024px: Sidebar becomes overlay drawer (hamburger в TopBar)
- ≤880px:  Drawers и modals fullscreen (100vw × 100dvh, no border-radius)

Implementation:

src/components/layout/Sidebar.tsx
  - Extracted SidebarContent (logo + nav + user block) для DRY
  - Desktop <Sidebar /> wraps SidebarContent в hidden lg:flex aside
  - New <MobileSidebar open onClose /> — Sheet с тем же содержимым,
    260px wide, slides from left
  - SidebarLink принимает onClick → drawer auto-close при navigate

src/components/layout/TopBar.tsx
  - Optional onMenuClick prop — рендерит hamburger button (Menu icon
    из lucide-react) с lg:hidden
  - VersionBadge скрыт <md (768px) — diagnostic info, не critical UX

src/routes/__root.tsx
  - useState mobileNavOpen, передаём в MobileSidebar + TopBar

src/ui/components/dialog.tsx
  - SIZE_CLASSES получили  prefix (arbitrary Tailwind v4
    breakpoint per handoff exact 880px). На mobile <880px modal становится
    fullscreen (inset-0 w-full h-full no rounded), ≥880px — centered с
    translate + max-w из SIZE_CLASSES.

src/ui/components/sheet.tsx
  - size variants: sm:max-w-* → min-[880px]:max-w-*. На mobile <880px
    sheet берёт w-full (fullscreen drawer per handoff).

src/components/record/RecordDrawer.tsx
  - max-width переключатель 520/880 теперь применяется только ≥880px.
    На mobile drawer всегда fullscreen.

src/ui/components/language-switch.tsx
  - Display fallback: opt.short → opt.label → uppercase id.
    Previously показывал id ('ru-RU', 'en-US') когда short не был задан —
    теперь использует label ('RU', 'EN') как fallback.

Browser-verified в preview viewport 375×812:
  - Hamburger ☰ visible, click открывает Sheet с nav items
  - Backdrop fade + slide-from-left animation
  - TopBar fits в 375px (RU/EN compact, Sign in visible)
  - LoadingBlock + Alert text-wrap correctly
2026-05-11 15:39:23 +03:00
Zimin A.N. 5007e0f4eb feat(ui): drop @nstart/ui dependency (Stage 3.9)
Все font cascade bugs из последних MR были вызваны @nstart/ui pollution
(Tektur inheritance от Card parent'ов, Onest font в Button, font-primary
class overrides). Решили обрезать раньше plan'а.

What changed:

New primitives (8 файлов в src/ui/components/):
  - panel.tsx           — container с border/surface
  - field.tsx           — FieldLabel/Hint/Error typography helpers
  - text-input.tsx      — Input + label/hint/error composite
  - table.tsx           — Table/TableHeader/Body/Row/HeaderCell/Cell/Empty
  - date-picker.tsx     — native <input type=date> wrapper с label/hint/error
  - multi-select.tsx    — Radix Popover + inline checkboxes
  - single-select.tsx   — native <select> с label/hint/error chrome
  - language-switch.tsx — segmented control в Tektur uppercase

Compatibility shims (existing components extended):
  - checkbox.tsx        — + label/description/error/onChange (nstart-compat
                          synthetic event), wrap в <label> когда есть chrome
  - modal.tsx           — + panelClassName / bodyClassName props
  - form-actions.tsx    — + align prop (start/end/between)
  - tabs-simple.tsx     — TabItem.count alias for .trailing (nstart-compat)
  - table TableHead     — alias TableHeaderCell с align prop

Barrel rewrite (src/ui/index.ts):
  - Удалён 'export * from @nstart/ui'
  - Explicit exports для всех 45+ нужных символов
  - SelectOption / MultiSelectOption / LanguageOption теперь {id, label}
    с optional 'value' alias — nstart-compat без массового codemod call-sites

styles.css cleanup:
  - Removed @import @nstart/ui/styles/{fonts,theme}.css
  - Removed @source nstart/dist directive (Tailwind v4 scan)
  - Removed --text-sm: 13px override (был костыль для @nstart/ui dist)
  - Legacy color tokens (--color-carbon/ultramarain/orbit/regolith/asteroid)
    sсодержали fallback mappings — оставлены, но callsites больше не используют

Codemod: 9 файлов конвертированы legacy colors → handoff tokens
  carbon → ink, ultramarain → accent, orbit → warn, regolith → line, asteroid → mute

main.tsx:
  - NStartUiProvider → TooltipProvider (Radix)
  - DatePickerProvider убран (наш DatePicker native, no provider needed)

routes/dictionaries.$name.tsx:
  - Removed useRef-based <input>.indeterminate hack
  - Radix Checkbox принимает checked='indeterminate' declaratively

package.json: -@nstart/ui (was 0.1.3)

Bundle impact:
  before: vendor-nstart-ui chunk = 1228 KB
  after:  no nstart chunk, всё в vendor-misc (+~70 KB Radix wrappers)
  net savings: ~1.15 MB minified, ~440 KB gzip

Tests: 116 pass (1 fixed: tab role from 'button' → 'tab', Radix semantically correct).
TS strict: clean.
Browser-verified (preview): 7 utilities computed correctly, nstart bundle absent.
2026-05-11 15:17:37 +03:00