mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-21 18:19:03 +08:00
将导航栏展开收起按钮移至顶栏
This commit is contained in:
+23
-1
@@ -53,6 +53,7 @@ function MainContent(): React.JSX.Element {
|
|||||||
const [authLoading, setAuthLoading] = useState(false)
|
const [authLoading, setAuthLoading] = useState(false)
|
||||||
const [isPortraitMode, setIsPortraitMode] = useState(false)
|
const [isPortraitMode, setIsPortraitMode] = useState(false)
|
||||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
|
||||||
|
const [floatingSidebarExpanded, setFloatingSidebarExpanded] = useState(false)
|
||||||
|
|
||||||
const activeMenu = useMemo(() => {
|
const activeMenu = useMemo(() => {
|
||||||
const p = location.pathname
|
const p = location.pathname
|
||||||
@@ -143,10 +144,12 @@ function MainContent(): React.JSX.Element {
|
|||||||
await api.windowSetResizable(false)
|
await api.windowSetResizable(false)
|
||||||
await api.windowResize(940, 1600)
|
await api.windowResize(940, 1600)
|
||||||
setSidebarCollapsed(true)
|
setSidebarCollapsed(true)
|
||||||
|
setFloatingSidebarExpanded(false)
|
||||||
} else {
|
} else {
|
||||||
await api.windowSetResizable(true)
|
await api.windowSetResizable(true)
|
||||||
await api.windowResize(2560, 1440)
|
await api.windowResize(2560, 1440)
|
||||||
setSidebarCollapsed(false)
|
setSidebarCollapsed(false)
|
||||||
|
setFloatingSidebarExpanded(false)
|
||||||
}
|
}
|
||||||
setIsPortraitMode(nextPortraitMode)
|
setIsPortraitMode(nextPortraitMode)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -155,6 +158,20 @@ function MainContent(): React.JSX.Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isPortraitMode || !sidebarCollapsed) {
|
||||||
|
setFloatingSidebarExpanded(false)
|
||||||
|
}
|
||||||
|
}, [isPortraitMode, sidebarCollapsed])
|
||||||
|
|
||||||
|
const toggleSidebar = () => {
|
||||||
|
if (isPortraitMode && sidebarCollapsed) {
|
||||||
|
setFloatingSidebarExpanded((prev) => !prev)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setSidebarCollapsed((prev) => !prev)
|
||||||
|
}
|
||||||
|
|
||||||
const isDark = currentTheme?.mode === "dark"
|
const isDark = currentTheme?.mode === "dark"
|
||||||
const brandColor = currentTheme?.config?.tdesign?.brandColor || "#0052D9"
|
const brandColor = currentTheme?.config?.tdesign?.brandColor || "#0052D9"
|
||||||
|
|
||||||
@@ -175,7 +192,8 @@ function MainContent(): React.JSX.Element {
|
|||||||
onMenuChange={onMenuChange}
|
onMenuChange={onMenuChange}
|
||||||
collapsed={sidebarCollapsed}
|
collapsed={sidebarCollapsed}
|
||||||
floatingExpand={isPortraitMode}
|
floatingExpand={isPortraitMode}
|
||||||
onCollapsedChange={setSidebarCollapsed}
|
floatingExpanded={floatingSidebarExpanded}
|
||||||
|
onFloatingExpandedChange={setFloatingSidebarExpanded}
|
||||||
/>
|
/>
|
||||||
<ContentArea
|
<ContentArea
|
||||||
permission={permission}
|
permission={permission}
|
||||||
@@ -183,6 +201,10 @@ function MainContent(): React.JSX.Element {
|
|||||||
onAuthClick={() => setAuthVisible(true)}
|
onAuthClick={() => setAuthVisible(true)}
|
||||||
onLogout={logout}
|
onLogout={logout}
|
||||||
isPortraitMode={isPortraitMode}
|
isPortraitMode={isPortraitMode}
|
||||||
|
sidebarCollapsed={sidebarCollapsed}
|
||||||
|
floatingExpand={isPortraitMode}
|
||||||
|
floatingExpanded={floatingSidebarExpanded}
|
||||||
|
onToggleSidebar={toggleSidebar}
|
||||||
onToggleOrientation={toggleOrientationMode}
|
onToggleOrientation={toggleOrientationMode}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React, { Suspense, lazy, useEffect } from "react"
|
import React, { Suspense, lazy, useEffect } from "react"
|
||||||
import { Layout, Space, Button, Tag, Spin } from "antd"
|
import { Layout, Space, Button, Tag, Spin } from "antd"
|
||||||
|
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons"
|
||||||
import { Routes, Route, Navigate } from "react-router-dom"
|
import { Routes, Route, Navigate } from "react-router-dom"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
import { WindowControls } from "./WindowControls"
|
import { WindowControls } from "./WindowControls"
|
||||||
@@ -46,6 +47,10 @@ interface ContentAreaProps {
|
|||||||
onAuthClick: () => void
|
onAuthClick: () => void
|
||||||
onLogout: () => void
|
onLogout: () => void
|
||||||
isPortraitMode: boolean
|
isPortraitMode: boolean
|
||||||
|
sidebarCollapsed: boolean
|
||||||
|
floatingExpand: boolean
|
||||||
|
floatingExpanded: boolean
|
||||||
|
onToggleSidebar: () => void
|
||||||
onToggleOrientation: () => void
|
onToggleOrientation: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +60,10 @@ export function ContentArea({
|
|||||||
onAuthClick,
|
onAuthClick,
|
||||||
onLogout,
|
onLogout,
|
||||||
isPortraitMode,
|
isPortraitMode,
|
||||||
|
sidebarCollapsed,
|
||||||
|
floatingExpand,
|
||||||
|
floatingExpanded,
|
||||||
|
onToggleSidebar,
|
||||||
onToggleOrientation,
|
onToggleOrientation,
|
||||||
}: ContentAreaProps): React.JSX.Element {
|
}: ContentAreaProps): React.JSX.Element {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@@ -115,6 +124,35 @@ export function ContentArea({
|
|||||||
} as React.CSSProperties
|
} as React.CSSProperties
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
paddingLeft: "8px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100%",
|
||||||
|
WebkitAppRegion: "no-drag",
|
||||||
|
flexShrink: 0,
|
||||||
|
} as React.CSSProperties
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
onClick={onToggleSidebar}
|
||||||
|
icon={
|
||||||
|
floatingExpand && sidebarCollapsed
|
||||||
|
? floatingExpanded
|
||||||
|
? <MenuFoldOutlined />
|
||||||
|
: <MenuUnfoldOutlined />
|
||||||
|
: sidebarCollapsed
|
||||||
|
? <MenuUnfoldOutlined />
|
||||||
|
: <MenuFoldOutlined />
|
||||||
|
}
|
||||||
|
title={sidebarCollapsed ? "展开导航栏" : "收起导航栏"}
|
||||||
|
style={{ width: "32px", height: "32px" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
style={
|
style={
|
||||||
|
|||||||
+11
-45
@@ -9,8 +9,6 @@ import {
|
|||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
CloudOutlined,
|
CloudOutlined,
|
||||||
UploadOutlined,
|
UploadOutlined,
|
||||||
MenuFoldOutlined,
|
|
||||||
MenuUnfoldOutlined,
|
|
||||||
} from "@ant-design/icons"
|
} from "@ant-design/icons"
|
||||||
import { useState, useEffect } from "react"
|
import { useState, useEffect } from "react"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
@@ -24,7 +22,8 @@ interface SidebarProps {
|
|||||||
onMenuChange: (value: string) => void
|
onMenuChange: (value: string) => void
|
||||||
collapsed: boolean
|
collapsed: boolean
|
||||||
floatingExpand: boolean
|
floatingExpand: boolean
|
||||||
onCollapsedChange: (collapsed: boolean) => void
|
floatingExpanded: boolean
|
||||||
|
onFloatingExpandedChange: (expanded: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DbStatus {
|
interface DbStatus {
|
||||||
@@ -39,10 +38,10 @@ export function Sidebar({
|
|||||||
onMenuChange,
|
onMenuChange,
|
||||||
collapsed,
|
collapsed,
|
||||||
floatingExpand,
|
floatingExpand,
|
||||||
onCollapsedChange,
|
floatingExpanded,
|
||||||
|
onFloatingExpandedChange,
|
||||||
}: SidebarProps): React.JSX.Element {
|
}: SidebarProps): React.JSX.Element {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [floatingExpanded, setFloatingExpanded] = useState(false)
|
|
||||||
const [dbStatus, setDbStatus] = useState<DbStatus>({ type: "sqlite", connected: true })
|
const [dbStatus, setDbStatus] = useState<DbStatus>({ type: "sqlite", connected: true })
|
||||||
const [syncLoading, setSyncLoading] = useState(false)
|
const [syncLoading, setSyncLoading] = useState(false)
|
||||||
const [messageApi, contextHolder] = message.useMessage()
|
const [messageApi, contextHolder] = message.useMessage()
|
||||||
@@ -107,9 +106,9 @@ export function Sidebar({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!floatingExpand || !collapsed) {
|
if (!floatingExpand || !collapsed) {
|
||||||
setFloatingExpanded(false)
|
onFloatingExpandedChange(false)
|
||||||
}
|
}
|
||||||
}, [floatingExpand, collapsed])
|
}, [floatingExpand, collapsed, onFloatingExpandedChange])
|
||||||
|
|
||||||
const handleForceSync = async () => {
|
const handleForceSync = async () => {
|
||||||
if (!(window as any).api) return
|
if (!(window as any).api) return
|
||||||
@@ -193,53 +192,20 @@ export function Sidebar({
|
|||||||
|
|
||||||
const showFloatingPanel = floatingExpand && collapsed && floatingExpanded
|
const showFloatingPanel = floatingExpand && collapsed && floatingExpanded
|
||||||
|
|
||||||
const renderSidebarBody = (
|
const renderSidebarBody = (isCollapsedView: boolean, hideMenu = false) => (
|
||||||
isCollapsedView: boolean,
|
|
||||||
isFloatingPanel = false,
|
|
||||||
hideMenu = false
|
|
||||||
) => (
|
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
style={
|
style={
|
||||||
{
|
{
|
||||||
padding: isCollapsedView ? "24px 8px 12px" : "32px 24px 16px",
|
padding: isCollapsedView ? "20px 8px 12px" : "24px 24px 16px",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
WebkitAppRegion: "drag",
|
WebkitAppRegion: "drag",
|
||||||
userSelect: "none",
|
userSelect: "none",
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
position: "relative",
|
|
||||||
} as React.CSSProperties
|
} as React.CSSProperties
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Button
|
|
||||||
type="text"
|
|
||||||
size="small"
|
|
||||||
onClick={() => {
|
|
||||||
if (floatingExpand && collapsed) {
|
|
||||||
setFloatingExpanded((prev) => !prev)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
onCollapsedChange(!collapsed)
|
|
||||||
}}
|
|
||||||
icon={
|
|
||||||
floatingExpand && collapsed
|
|
||||||
? isFloatingPanel
|
|
||||||
? <MenuFoldOutlined />
|
|
||||||
: <MenuUnfoldOutlined />
|
|
||||||
: isCollapsedView
|
|
||||||
? <MenuUnfoldOutlined />
|
|
||||||
: <MenuFoldOutlined />
|
|
||||||
}
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
position: "absolute",
|
|
||||||
top: "8px",
|
|
||||||
right: "8px",
|
|
||||||
WebkitAppRegion: "no-drag",
|
|
||||||
} as React.CSSProperties
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<img
|
<img
|
||||||
src={appLogo}
|
src={appLogo}
|
||||||
style={{
|
style={{
|
||||||
@@ -283,7 +249,7 @@ export function Sidebar({
|
|||||||
onClick={({ key }) => {
|
onClick={({ key }) => {
|
||||||
onMenuChange(key)
|
onMenuChange(key)
|
||||||
if (floatingExpand && collapsed) {
|
if (floatingExpand && collapsed) {
|
||||||
setFloatingExpanded(false)
|
onFloatingExpandedChange(false)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
@@ -376,7 +342,7 @@ export function Sidebar({
|
|||||||
theme="light"
|
theme="light"
|
||||||
>
|
>
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
{renderSidebarBody(collapsed, false, showFloatingPanel)}
|
{renderSidebarBody(collapsed, showFloatingPanel)}
|
||||||
|
|
||||||
{showFloatingPanel && (
|
{showFloatingPanel && (
|
||||||
<div
|
<div
|
||||||
@@ -394,7 +360,7 @@ export function Sidebar({
|
|||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{renderSidebarBody(false, true)}
|
{renderSidebarBody(false)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Sider>
|
</Sider>
|
||||||
|
|||||||
Reference in New Issue
Block a user