From 3edd6b2a691fa53f64dce7ff4850056b384efd89 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Thu, 26 Feb 2026 04:39:17 +0800 Subject: [PATCH] feat: implement layout store management and add API documentation modal --- src/agents/app.ts | 7 ++++- src/components/ui/dialog.tsx | 2 ++ src/pages/[root]/v1/[appId]/page2.tsx | 14 ---------- src/pages/studio/index.tsx | 25 ++++++++++++++---- src/pages/studio/store.ts | 6 ++++- src/pages/view/components/DocsModal.tsx | 34 +++++++++++++++++++++++++ src/pages/view/list.tsx | 29 ++++++++++++++------- src/routes/__root.tsx | 11 +++++++- 8 files changed, 97 insertions(+), 31 deletions(-) delete mode 100644 src/pages/[root]/v1/[appId]/page2.tsx create mode 100644 src/pages/view/components/DocsModal.tsx diff --git a/src/agents/app.ts b/src/agents/app.ts index 65d85cd..2e82c01 100644 --- a/src/agents/app.ts +++ b/src/agents/app.ts @@ -1,3 +1,8 @@ import { QueryRouterServer } from '@kevisual/router/browser' import { use } from '@kevisual/context' -export const app = use('app', new QueryRouterServer()) \ No newline at end of file +export const app = use('app', new QueryRouterServer()) + +import { useLayoutStore } from '@/pages/auth/store' + +const layoutStore = useLayoutStore.getState() +layoutStore.setShowBaseHeader(false) \ No newline at end of file diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index f49a149..c509160 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { Dialog as DialogPrimitive } from "@base-ui/react/dialog" diff --git a/src/pages/[root]/v1/[appId]/page2.tsx b/src/pages/[root]/v1/[appId]/page2.tsx deleted file mode 100644 index bdb9a0f..0000000 --- a/src/pages/[root]/v1/[appId]/page2.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { AppProvider } from '../../../studio/index.tsx'; - -interface PageProps { - params: Promise<{ - root: string - appId: string - }> -} - -export default async function Page({ params }: PageProps) { - const { root, appId } = await params; - console.log('root', root, 'appId', appId); - return ; -} diff --git a/src/pages/studio/index.tsx b/src/pages/studio/index.tsx index 8ea512f..abc6ba9 100644 --- a/src/pages/studio/index.tsx +++ b/src/pages/studio/index.tsx @@ -1,6 +1,6 @@ import { filterRouteInfo, useStudioStore } from './store.ts'; import { use, useEffect, useState } from 'react'; -import { MonitorPlay, Play, PanelLeft, PanelLeftClose, PanelRight, PanelRightClose, Filter, FilterX, Search, X, MoreHorizontal, Info, Code, RotateCcw } from 'lucide-react'; +import { MonitorPlay, Play, PanelLeft, PanelLeftClose, PanelRight, PanelRightClose, PanelTop, PanelTopClose, Filter, FilterX, Search, X, MoreHorizontal, Info, Code, RotateCcw, Book } from 'lucide-react'; import { Panel, Group } from 'react-resizable-panels' import { ViewList } from '../view/list.tsx'; import { useShallow } from 'zustand/shallow'; @@ -12,6 +12,7 @@ import { ExportDialog } from './components/ExportDialog'; import { useQueryViewStore } from '../query-view/store/index.ts'; import { toast } from 'sonner'; import { DetailsDialog } from '../query-view/components/DetailsDialog.tsx'; +import { useLayoutStore } from '../auth/store.ts'; export const AppProvider = () => { const { showLeftPanel, showRightPanel } = useStudioStore(useShallow((state) => ({ showLeftPanel: state.showLeftPanel, @@ -49,12 +50,26 @@ export const WrapperHeader = (props: { children: React.ReactNode }) => { showRightPanel: state.showRightPanel, setShowRightPanel: state.setShowRightPanel, }))); + const layoutStore = useLayoutStore(useShallow((state) => ({ + showBaseHeader: state.showBaseHeader, + setShowBaseHeader: state.setShowBaseHeader, + }))); return
-
{ - store.setShowLeftPanel(!store.showLeftPanel); - }}> - {showLeftPanel ? : } +
+ +
{ + store.setShowLeftPanel(!store.showLeftPanel); + }}> + {showLeftPanel ? : } +
+
{ + layoutStore.setShowBaseHeader(!layoutStore.showBaseHeader) + } + }> + {layoutStore.showBaseHeader ? : } +
+ + + + + ); +}; \ No newline at end of file diff --git a/src/pages/view/list.tsx b/src/pages/view/list.tsx index 0dda576..c611ced 100644 --- a/src/pages/view/list.tsx +++ b/src/pages/view/list.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; import { useStudioStore } from '../studio/store.ts'; -import { Search, RotateCw, Plus, MoreHorizontal, Layout, Edit2, Trash2, MousePointer2 } from "lucide-react"; +import { Search, RotateCw, Plus, MoreHorizontal, Layout, Edit2, Trash2, MousePointer2, Book } from "lucide-react"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { @@ -14,7 +14,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover import { ViewEditor } from "@/pages/view/components/ViewEditor.tsx"; import { toast } from "sonner"; import { useShallow } from "zustand/shallow"; - +import { DocsModal } from './components/DocsModal.tsx' const ViewItem = ({ view, onEdit, onDelete, onDeleteViewItem }: { view: any; onEdit: (view: any) => void; onDelete: (id: string) => void; onDeleteViewItem: (id: string, viewId: string) => void }) => { const [expanded, setExpanded] = useState(false); const studioStore = useStudioStore(useShallow((state) => ({ @@ -158,22 +158,29 @@ const ViewItem = ({ view, onEdit, onDelete, onDeleteViewItem }: { view: any; onE
} export const ViewList = () => { - const { routeViewList, updateRouteView, deleteRouteView, deleteRouteViewItem, getViewList } = useStudioStore(); + const store = useStudioStore(useShallow((state) => ({ + routeViewList: state.routeViewList, + updateRouteView: state.updateRouteView, + deleteRouteView: state.deleteRouteView, + deleteRouteViewItem: state.deleteRouteViewItem, + getViewList: state.getViewList, + setShowApiDocs: state.setShowApiDocs, + }))); const [searchTerm, setSearchTerm] = useState(""); const [editorOpen, setEditorOpen] = useState(false); const [editingView, setEditingView] = useState(null); - const filteredViews = routeViewList.filter(view => + const filteredViews = store.routeViewList.filter(view => (view.title || '未命名视图').toLowerCase().includes(searchTerm.toLowerCase()) || (view.description || '').toLowerCase().includes(searchTerm.toLowerCase()) ); useEffect(() => { - getViewList(); + store.getViewList(); }, []) const handleRefresh = async () => { const toastId = toast.loading('正在刷新视图列表...'); - await getViewList(); + await store.getViewList(); // toast.update(toastId, { render: '视图列表已刷新', type: 'success', id: false, autoClose: 1000 }); toast.success('视图列表已刷新', { duration: 1000 }); toast.dismiss(toastId); @@ -190,17 +197,20 @@ export const ViewList = () => { const handleDelete = (id: string) => { if (confirm('确定要删除这个视图吗?')) { - deleteRouteView(id); + store.deleteRouteView(id); } }; const handleSaveView = (viewData: any) => { - updateRouteView(viewData); + store.updateRouteView(viewData); }; return (
+
{ view={view} onEdit={handleEdit} onDelete={handleDelete} - onDeleteViewItem={deleteRouteViewItem} + onDeleteViewItem={store.deleteRouteViewItem} /> )) )} @@ -242,6 +252,7 @@ export const ViewList = () => { data={editingView} onSave={handleSaveView} /> +
); } \ No newline at end of file diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 2a6d2ea..28d78f7 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -4,18 +4,27 @@ import { TanStackRouterDevtools } from '@tanstack/react-router-devtools' import { Toaster } from '@/components/ui/sonner' import { AuthProvider } from '@/pages/auth' import { TooltipProvider } from '@/components/ui/tooltip' +import { useLayoutStore } from '@/pages/auth/store'; +import { useShallow } from 'zustand/shallow'; +import clsx from 'clsx'; export const Route = createRootRoute({ component: RootComponent, }) function RootComponent() { + const store = useLayoutStore(useShallow(state => ({ + showBaseHeader: state.showBaseHeader, + }))); return (
-
+