From ddbe7368a2fae112f7c0453e2c0e1dd73e3f3891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=97=D0=B8=D0=BC=D0=B8=D0=BD?= Date: Sun, 10 May 2026 17:59:01 +0000 Subject: [PATCH] docs(admin-ui): rich design handoff Dictionary Catalog (3 views + nstart/ui patch) --- .../README.md | 503 +++++++--- .../design/design-canvas.jsx | 936 ++++++++++++++++++ .../design/dictionary-prototype.html | 118 +++ .../design/dictionary-views.html | 486 +++++++++ .../design/proto/data.jsx | 49 + .../design/proto/ui.jsx | 72 ++ .../design/proto/view-graph.jsx | 180 ++++ .../design/proto/view-hub.jsx | 154 +++ .../design/proto/view-list.jsx | 154 +++ .../patch.diff | 495 --------- .../patches/README.md | 133 +++ .../proposed.tsx | 448 --------- .../prototype.html | 274 ----- .../review.md | 296 ++---- .../screenshots/A-graph-view.png | Bin 0 -> 21150 bytes .../screenshots/B-hub-view.png | Bin 0 -> 23095 bytes .../screenshots/D-list-view.png | Bin 0 -> 28504 bytes 17 files changed, 2743 insertions(+), 1555 deletions(-) create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/design-canvas.jsx create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/dictionary-prototype.html create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/dictionary-views.html create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/proto/data.jsx create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/proto/ui.jsx create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/proto/view-graph.jsx create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/proto/view-hub.jsx create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/design/proto/view-list.jsx delete mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/patch.diff create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/patches/README.md delete mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/proposed.tsx delete mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/prototype.html create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/screenshots/A-graph-view.png create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/screenshots/B-hub-view.png create mode 100644 ordinis-admin-ui/design_handoff_dictionary_catalog/screenshots/D-list-view.png diff --git a/ordinis-admin-ui/design_handoff_dictionary_catalog/README.md b/ordinis-admin-ui/design_handoff_dictionary_catalog/README.md index 103ca4a..a854378 100644 --- a/ordinis-admin-ui/design_handoff_dictionary_catalog/README.md +++ b/ordinis-admin-ui/design_handoff_dictionary_catalog/README.md @@ -1,177 +1,394 @@ -# Dictionary Catalog v2 — Design Handoff +# Handoff: Dictionary Catalog Redesign + nstart-ui Popover Fix -Pages: `/dictionaries/` (catalog) + per-card нав до `/dictionaries/$name`. +## Overview -Текущая страница (single-screen, scope-grouped grid карточек) хорошо работала -на 10 справочниках, но при росте до 40+ (ЦУОД bundle expansion) UX degrades: -forced grouping ломает sort-by-attention, scope-as-section не позволяет -multi-scope запрос, density фиксированная (cards-only). Этот hand-off -поднимает катаког в шаблон **filter-first list**: URL-driven filters, -density toggle, sort, persistent state shareable через ссылку. +Two interconnected pieces of work for the **Ordinis admin UI** (`ordinis-admin-ui`, React 19 + TanStack Router + `@nstart/ui` 0.1.3): -## Scope +1. **`@nstart/ui` patch** — `Select` / `MultiSelect` / `DatePicker` popovers render inline and get clipped by modal `overflow:auto` (visible bug in the "Создать справочник" modal). Fix via `pnpm patch` to render into a portal on `document.body`. Same patch fixes `Checkbox.indeterminate` ref-forwarding. -- ✅ `/dictionaries/` page redesign (catalog only). -- ❌ `/dictionaries/$name` (detail) — отдельный hand-off, не trog'аем. -- ❌ Backend / API — не меняем, всё локально через `useDictionaries()`. -- ❌ i18n переводы — keys добавлены, локалаизация в parallel PR. +2. **Dictionary catalog redesign** — three new ways to browse the 40+ dictionaries with their FK relationships visible: + - **D · List view with inline FK chips** (smallest change; replaces current grid) + - **A · Graph view** (force-directed overview of all dicts + edges) + - **B · Hub view** (one dict in focus, neighbors on either side; new tab inside `dictionaries.$name.tsx`) -## Файлы handoff +## About the Design Files -| Файл | Назначение | -|---|---| -| `README.md` | Этот документ — components / tokens / routes / AC | -| `prototype.html` | Static visual mock (Tailwind CDN) для Figma replacement | -| `proposed.tsx` | Финальная React-компонента — заменяет `routes/dictionaries.index.tsx` | -| `patch.diff` | Unified diff от current до proposed | -| `review.md` | Senior frontend review (taste calls, edge cases) | +The HTML/JSX in `design/` is a **design reference**, not production code to copy directly. It's a working prototype showing intended look, layout, interactions, and data shape — but written as a single self-contained HTML file with inline Babel. -## Components используемые +**Your task:** recreate these views inside the existing `ordinis-admin-ui` React/TypeScript codebase, using its established patterns: +- TanStack Router routes +- TanStack Query for data +- `@nstart/ui` components (`Button`, `Modal`, `Tabs`, `Badge`, `Alert`, etc.) for chrome +- TailwindCSS v4 (project already uses it via `@tailwindcss/vite`) +- React Hook Form + AJV for forms +- Phosphor Icons (`@phosphor-icons/react`) -Из `@nstart/ui` (без новых): -- `PageHeader` — заголовок + actions slot (кнопка Create) -- `SearchInput` — debounced query -- `Button` (`variant="primary"`, `variant="ghost"`, `size="sm"`) -- `Badge` (`variant="neutral|info|warning"`) -- `EmptyState` — пустые состояния (no data / no match) -- `LoadingBlock` — initial fetch skeleton -- `Alert` (`variant="error"`) +**Do not** ship the prototype HTML to production. **Do not** import the prototype `.jsx` files — they use `window.*` globals and inline Babel which won't work in the Vite build. -**Новые элементы (не component'ы — inline UI):** -- `ScopeChip` — toggle pill с цветным dot, multi-select. -- `SortDropdown` — `` element. + +### How + +Use `pnpm patch` to fork only the affected files in `node_modules/@nstart/ui/dist/` and persist as a project-level patch. Full step-by-step in `patches/README.md`. + +```bash +pnpm patch @nstart/ui # → opens temp dir, edit dist/index.js +pnpm patch-commit # → writes patches/@nstart__ui@0.1.3.patch ``` -State persisted в URL — shareable links для команды: -- `/dictionaries/?q=spacecraft` — поиск по словам -- `/dictionaries/?scope=PUBLIC,INTERNAL` — multi-scope filter -- `/dictionaries/?sort=recordCount&density=dense` — power-user view -- `/dictionaries/?q=test&scope=PUBLIC&sort=name&density=card` — комбинация +Three logical changes inside `dist/index.js` (or `.mjs`): -Default state (no params): show all, sort by name, density=card. +1. **Wrap Select / MultiSelect / DatePicker popover in `createPortal(node, document.body)`** with `position: fixed`, computed `top`/`left`/`width` from `triggerRef.getBoundingClientRect()`, `z-index: 9999`. +2. **Listen to `resize` and capture-phase `scroll`** so the portal stays glued to the trigger inside scrolling modals. +3. **Update outside-click detection** — after the popover moves out of trigger's DOM subtree, the existing `event.target` check fails. Replace with `triggerRef.current.contains(t) || popoverRef.current.contains(t)`. +4. **Auto-flip when popover overflows viewport bottom** — flip above the trigger. -Navigation: -- `` — typed router -- На карточке: cтрока с `keyboard nav` (Enter / Space → navigate) +For `Checkbox`: +- Forward ref to the inner ``, not the `