优化桌面端界面布局
This commit is contained in:
@@ -3,32 +3,30 @@
|
||||
<aside class="desktop-sidebar">
|
||||
<header class="sidebar-head">
|
||||
<div class="sidebar-title-row">
|
||||
<div>
|
||||
<h1>{{ TEXT.common.appName }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<h1>{{ TEXT.common.appName }}</h1>
|
||||
|
||||
<el-dropdown v-if="study.currentStudy" trigger="click" class="study-switcher" @command="handleStudySwitch">
|
||||
<button class="study-switcher-trigger" type="button">
|
||||
<span class="study-name">{{ study.currentStudy.name }}</span>
|
||||
<el-icon><ArrowDown /></el-icon>
|
||||
<el-dropdown v-if="study.currentStudy" trigger="click" class="study-switcher" @command="handleStudySwitch">
|
||||
<button class="study-switcher-trigger" type="button">
|
||||
<span class="study-name">{{ study.currentStudy.name }}</span>
|
||||
<el-icon><ArrowDown /></el-icon>
|
||||
</button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="study-switcher-menu">
|
||||
<el-dropdown-item
|
||||
v-for="item in studies"
|
||||
:key="item.id"
|
||||
:command="item"
|
||||
:class="{ active: study.currentStudy?.id === item.id }"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<button v-else class="study-switcher-trigger empty" type="button" @click="router.push('/admin/projects')">
|
||||
选择项目
|
||||
</button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="study-switcher-menu">
|
||||
<el-dropdown-item
|
||||
v-for="item in studies"
|
||||
:key="item.id"
|
||||
:command="item"
|
||||
:class="{ active: study.currentStudy?.id === item.id }"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<button v-else class="study-switcher-trigger empty" type="button" @click="router.push('/admin/projects')">
|
||||
选择项目
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="sidebar-scroll">
|
||||
@@ -47,21 +45,6 @@
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section v-if="desktopRecentRoutes.length" class="nav-section">
|
||||
<div class="section-label">最近访问</div>
|
||||
<button
|
||||
v-for="item in desktopRecentRoutes"
|
||||
:key="`recent:${item.path}`"
|
||||
type="button"
|
||||
class="sidebar-link compact"
|
||||
:class="{ active: activeMenu === item.path }"
|
||||
@click="router.push(item.path)"
|
||||
>
|
||||
<el-icon><Clock /></el-icon>
|
||||
<span>{{ item.title }}</span>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section v-if="adminNavigationItems.length" class="nav-section">
|
||||
<div class="section-label">{{ DESKTOP_ADMIN_SECTION_LABEL }}</div>
|
||||
<template v-for="item in adminNavigationItems" :key="item.path">
|
||||
@@ -315,7 +298,6 @@
|
||||
>
|
||||
<button class="workspace-tab-action" type="button" @click="navigateWorkspaceTab(item.path)">
|
||||
<span>{{ item.title }}</span>
|
||||
<span class="tab-group">{{ item.group }}</span>
|
||||
</button>
|
||||
<button class="tab-close" type="button" title="关闭标签" @click.stop="closeWorkspaceTab(item.path)">
|
||||
×
|
||||
@@ -447,12 +429,11 @@ import {
|
||||
} from "../session/desktopActivityCenter";
|
||||
import {
|
||||
DESKTOP_SERVER_URL_CHANGED_EVENT,
|
||||
clearLegacyDesktopRouteHistoryPreference,
|
||||
getAppMetadata,
|
||||
getDesktopServerUrl,
|
||||
listenDesktopMenuCommand,
|
||||
readDesktopFavoriteRoutes,
|
||||
readDesktopRecentRoutes,
|
||||
recordDesktopRecentRoute,
|
||||
toggleDesktopFavoriteRoute,
|
||||
type DesktopRoutePreference,
|
||||
} from "../runtime";
|
||||
@@ -495,7 +476,6 @@ const desktopServerUrl = ref(getDesktopServerUrl());
|
||||
const desktopUpdateStatus = ref<DesktopUpdateStatusSnapshot>(getDesktopUpdateStatus());
|
||||
const desktopActivities = ref<DesktopActivityItem[]>(getDesktopActivities());
|
||||
const studies = ref<any[]>([]);
|
||||
const desktopRecentRoutes = ref<DesktopRoutePreference[]>(readDesktopRecentRoutes());
|
||||
const desktopFavoriteRoutes = ref<DesktopRoutePreference[]>(readDesktopFavoriteRoutes());
|
||||
const workspaceTabs = ref<DesktopRoutePreference[]>([]);
|
||||
const draggingWorkspaceTabPath = ref("");
|
||||
@@ -689,7 +669,6 @@ const headerReminderBadgeValue = computed(() => (headerReminderTotal.value > 99
|
||||
|
||||
const refreshDesktopRoutePreferences = () => {
|
||||
const allowedPaths = new Set(desktopNavigationItems.value.map((item) => item.path));
|
||||
desktopRecentRoutes.value = readDesktopRecentRoutes().filter((item) => allowedPaths.has(item.path));
|
||||
desktopFavoriteRoutes.value = readDesktopFavoriteRoutes().filter((item) => allowedPaths.has(item.path));
|
||||
};
|
||||
|
||||
@@ -769,7 +748,10 @@ const closeWorkspaceTab = (path: string) => {
|
||||
if (index >= 0) lastClosedWorkspaceTab.value = workspaceTabs.value[index];
|
||||
workspaceTabs.value = workspaceTabs.value.filter((tab) => tab.path !== path);
|
||||
if (activeMenu.value !== path) return;
|
||||
const next = workspaceTabs.value[index] || workspaceTabs.value[index - 1] || desktopRecentRoutes.value[0];
|
||||
const next =
|
||||
workspaceTabs.value[index] ||
|
||||
workspaceTabs.value[index - 1] ||
|
||||
desktopFavoriteRoutes.value.find((item) => item.path !== path);
|
||||
if (next) {
|
||||
router.push(next.path);
|
||||
} else {
|
||||
@@ -1054,7 +1036,6 @@ watch(
|
||||
study.setViewContext(null);
|
||||
const current = currentDesktopRoutePreference.value;
|
||||
if (current) {
|
||||
desktopRecentRoutes.value = recordDesktopRecentRoute(current);
|
||||
addWorkspaceTab(current);
|
||||
refreshDesktopRoutePreferences();
|
||||
}
|
||||
@@ -1076,9 +1057,9 @@ watch(
|
||||
|
||||
onMounted(async () => {
|
||||
window.addEventListener(DESKTOP_SERVER_URL_CHANGED_EVENT, updateDesktopServerUrl);
|
||||
clearLegacyDesktopRouteHistoryPreference();
|
||||
const current = currentDesktopRoutePreference.value;
|
||||
if (current) {
|
||||
desktopRecentRoutes.value = recordDesktopRecentRoute(current);
|
||||
addWorkspaceTab(current);
|
||||
}
|
||||
refreshDesktopRoutePreferences();
|
||||
@@ -1137,7 +1118,7 @@ useDesktopShortcuts(
|
||||
<style scoped>
|
||||
.desktop-workbench {
|
||||
display: grid;
|
||||
grid-template-columns: 272px minmax(0, 1fr);
|
||||
grid-template-columns: 248px minmax(0, 1fr);
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
min-height: 0;
|
||||
@@ -1173,23 +1154,23 @@ useDesktopShortcuts(
|
||||
|
||||
.sidebar-head {
|
||||
flex: 0 0 auto;
|
||||
padding: 54px 16px 14px;
|
||||
padding: 44px 10px 10px;
|
||||
border-bottom: 1px solid #dfe7f0;
|
||||
}
|
||||
|
||||
.sidebar-title-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.sidebar-head h1 {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
color: #101827;
|
||||
font-size: 18px;
|
||||
line-height: 1.3;
|
||||
font-size: 16px;
|
||||
line-height: 1.25;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -1210,6 +1191,13 @@ useDesktopShortcuts(
|
||||
color: #172233;
|
||||
}
|
||||
|
||||
.study-switcher {
|
||||
justify-self: start;
|
||||
width: 140px;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.study-switcher-trigger {
|
||||
appearance: none;
|
||||
display: grid;
|
||||
@@ -1217,11 +1205,11 @@ useDesktopShortcuts(
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
margin-top: 14px;
|
||||
padding: 0 10px;
|
||||
min-height: 32px;
|
||||
margin-top: 0;
|
||||
padding: 0 8px;
|
||||
border: 1px solid #d7e0ea;
|
||||
border-radius: 8px;
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
color: #26384f;
|
||||
cursor: pointer;
|
||||
@@ -1231,6 +1219,8 @@ useDesktopShortcuts(
|
||||
.study-switcher-trigger.empty {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
justify-self: start;
|
||||
width: 104px;
|
||||
color: #3f5d75;
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -1238,7 +1228,7 @@ useDesktopShortcuts(
|
||||
.study-name {
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
font-weight: 760;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -1255,7 +1245,7 @@ useDesktopShortcuts(
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
padding: 14px 10px 34px;
|
||||
padding: 10px 8px 24px;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
@@ -1278,11 +1268,11 @@ useDesktopShortcuts(
|
||||
}
|
||||
|
||||
.nav-section + .nav-section {
|
||||
margin-top: 18px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.section-label {
|
||||
padding: 0 8px 7px;
|
||||
padding: 0 6px 6px;
|
||||
color: #7b8da3;
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
@@ -1291,34 +1281,40 @@ useDesktopShortcuts(
|
||||
.sidebar-link {
|
||||
appearance: none;
|
||||
display: grid;
|
||||
grid-template-columns: 18px minmax(0, 1fr);
|
||||
grid-template-columns: 16px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
min-height: 32px;
|
||||
margin: 1px 0;
|
||||
padding: 0 9px;
|
||||
padding: 0 8px;
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: #3d5068;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
font-size: 14px;
|
||||
line-height: 1.3;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.sidebar-link.compact {
|
||||
grid-template-columns: 18px minmax(0, 1fr);
|
||||
grid-template-columns: 16px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.sidebar-link.child {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
min-height: 30px;
|
||||
padding-left: 36px;
|
||||
min-height: 28px;
|
||||
padding-left: 32px;
|
||||
color: #607289;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.sidebar-link :deep(.el-icon) {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.sidebar-link span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -1337,11 +1333,11 @@ useDesktopShortcuts(
|
||||
}
|
||||
|
||||
.sidebar-group {
|
||||
margin: 1px 0 5px;
|
||||
margin: 1px 0 4px;
|
||||
}
|
||||
|
||||
.group-title {
|
||||
grid-template-columns: 18px minmax(0, 1fr) 14px;
|
||||
grid-template-columns: 16px minmax(0, 1fr) 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -1858,10 +1854,7 @@ useDesktopShortcuts(
|
||||
|
||||
.workspace-tab-action {
|
||||
appearance: none;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
display: block;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
@@ -1872,18 +1865,13 @@ useDesktopShortcuts(
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.workspace-tab-action span:first-child {
|
||||
.workspace-tab-action span {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tab-group {
|
||||
color: #8394a9;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.tab-close {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
@@ -1946,11 +1934,12 @@ useDesktopShortcuts(
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
padding: 8px 10px;
|
||||
padding: 0;
|
||||
background: #eef2f6;
|
||||
}
|
||||
|
||||
.desktop-route-shell {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
@@ -2015,7 +2004,6 @@ useDesktopShortcuts(
|
||||
|
||||
:global([data-ctms-theme="dark"] .section-label),
|
||||
:global([data-ctms-theme="dark"] .panel-subtitle),
|
||||
:global([data-ctms-theme="dark"] .tab-group),
|
||||
:global([data-ctms-theme="dark"] .toolbar-subtitle) {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user