From 5a2220d77966efff26ddac12b2d408cdf5696f5f Mon Sep 17 00:00:00 2001 From: "Zimin A.N." Date: Mon, 11 May 2026 19:01:57 +0300 Subject: [PATCH] feat(editor): ExportModal + TimeTravelModal + InfoPanel merge + fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UI redesign matching prototype (Ordinis (3) dump): - ExportModal: format (CSV/JSON/Excel/SQL) + scope (all/filtered/selected) + column toggles + encoding/delimiter + preview filename per redesign line 1059-1092. CSV uses backend mutation, JSON client-side from filtered rows, Excel/SQL disabled (backend pending). - TimeTravelModal: full-page compare СЕЙЧАС vs ТОЧКА ВО ВРЕМЕНИ + quick presets (сейчас/неделя/месяц/год/при создании) + step toggle версия/день + slider + tabs (Что изменилось / Записи на момент / Структура и поля) + "Открыть как readonly" CTA. Replaces inline TimeTravelPicker. - InfoPanel ← используют merge: rich rows с field path + active records count + onClose policy chip (BLOCK/WARN/CASCADE). Inline DictionaryDependentsPanel above records table removed (one source of truth). - Sidebar logo: match redesign/ui-kit.html .brand SVG (outer ring + inner faded ring + orbit dot offset right cx=22.5). ORDINIS Tektur tracking 0.22em + MDM smaller mute 0.32em. - Bg neutralized: #fbf8ee Earth cream → #faf9f5 warm neutral default (per user preference, Earth cream still described in comment как opt-in). - WorkflowBanner: Case 1 Live (approvalRequired=false) returns null — permanent "Опубликовано" banner = noise, status already visible в InfoPanel scope/version/updatedAt. Banner показывается только когда есть actionable state. Critical bug fixes: - fix(CascadeConfirmDialog): infinite render loop "Maximum update depth exceeded". useEffect had cascadeMut (TanStack Query mutation wrapper) в deps — wrapper identity changes every render → effect fires → reset() → store update → render → loop. Extract stable `reset` reference перед useEffect. Симптомы у user: создание/редактирование записи не работали. - fix(semantic-release): add missing peer dep conventional-changelog-conventionalcommits (9.3.1). semantic-release 22+ больше не bundles preset. Без неё release job падал с "Cannot find module 'conventional-changelog-conventionalcommits'". --- ordinis-admin-ui/package.json | 1 + ordinis-admin-ui/pnpm-lock.yaml | 11 + .../src/components/editor/EditorInfoPanel.tsx | 67 ++- .../src/components/editor/ExportModal.tsx | 436 ++++++++++++++ .../src/components/editor/WorkflowBanner.tsx | 30 +- .../src/components/layout/Sidebar.tsx | 21 +- .../lineage/CascadeConfirmDialog.tsx | 9 +- .../components/timetravel/TimeTravelModal.tsx | 539 ++++++++++++++++++ .../src/routes/dictionaries.$name.tsx | 62 +- ordinis-admin-ui/src/styles.css | 16 +- 10 files changed, 1109 insertions(+), 83 deletions(-) create mode 100644 ordinis-admin-ui/src/components/editor/ExportModal.tsx create mode 100644 ordinis-admin-ui/src/components/timetravel/TimeTravelModal.tsx diff --git a/ordinis-admin-ui/package.json b/ordinis-admin-ui/package.json index 98f9de4..f4c2bba 100644 --- a/ordinis-admin-ui/package.json +++ b/ordinis-admin-ui/package.json @@ -63,6 +63,7 @@ "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "@vitejs/plugin-react": "^4.3.4", + "conventional-changelog-conventionalcommits": "^9.3.1", "jsdom": "^29.1.1", "semantic-release": "^24.2.1", "tailwindcss": "^4.0.0-beta.7", diff --git a/ordinis-admin-ui/pnpm-lock.yaml b/ordinis-admin-ui/pnpm-lock.yaml index 7683a0f..a77534c 100644 --- a/ordinis-admin-ui/pnpm-lock.yaml +++ b/ordinis-admin-ui/pnpm-lock.yaml @@ -159,6 +159,9 @@ importers: '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.7.0(vite@6.4.2(jiti@2.6.1)(lightningcss@1.32.0)) + conventional-changelog-conventionalcommits: + specifier: ^9.3.1 + version: 9.3.1 jsdom: specifier: ^29.1.1 version: 29.1.1 @@ -1905,6 +1908,10 @@ packages: resolution: {integrity: sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==} engines: {node: '>=18'} + conventional-changelog-conventionalcommits@9.3.1: + resolution: {integrity: sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==} + engines: {node: '>=18'} + conventional-changelog-writer@8.4.0: resolution: {integrity: sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g==} engines: {node: '>=18'} @@ -5324,6 +5331,10 @@ snapshots: dependencies: compare-func: 2.0.0 + conventional-changelog-conventionalcommits@9.3.1: + dependencies: + compare-func: 2.0.0 + conventional-changelog-writer@8.4.0: dependencies: '@simple-libs/stream-utils': 1.2.0 diff --git a/ordinis-admin-ui/src/components/editor/EditorInfoPanel.tsx b/ordinis-admin-ui/src/components/editor/EditorInfoPanel.tsx index 56e2417..0b00fea 100644 --- a/ordinis-admin-ui/src/components/editor/EditorInfoPanel.tsx +++ b/ordinis-admin-ui/src/components/editor/EditorInfoPanel.tsx @@ -1,10 +1,10 @@ import { useMemo } from 'react' import { Link } from '@tanstack/react-router' import { useTranslation } from 'react-i18next' -import { ClockCounterClockwiseIcon, MapTrifoldIcon, DownloadSimpleIcon } from '@phosphor-icons/react' +import { ClockCounterClockwiseIcon, MapTrifoldIcon, DownloadSimpleIcon, ArrowRightIcon } from '@phosphor-icons/react' import { Badge } from '@/ui' import { useDictionaryDependents } from '@/api/queries' -import type { DictionaryDetail } from '@/api/client' +import type { DictionaryDetail, OnCloseAction, SchemaDependent } from '@/api/client' import { cn } from '@/lib/utils' /** @@ -42,11 +42,7 @@ export function EditorInfoPanel({ detail, recordCount, actions }: EditorInfoPane const { data: refByRaw } = useDictionaryDependents(detail.name) const outgoingNames = useMemo(() => extractOutgoingFk(detail.schemaJson), [detail.schemaJson]) - const incomingNames = useMemo(() => { - const seen = new Set() - for (const dep of refByRaw ?? []) seen.add(dep.sourceDict) - return Array.from(seen).sort() - }, [refByRaw]) + const incomingDeps: SchemaDependent[] = useMemo(() => refByRaw ?? [], [refByRaw]) return (