优化桌面端界面布局
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;
|
||||
}
|
||||
|
||||
@@ -88,12 +88,18 @@ const openManager = () => {
|
||||
|
||||
<style scoped>
|
||||
.panel {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
flex-direction: column;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
overflow: hidden;
|
||||
padding: 24px 14px;
|
||||
background: transparent;
|
||||
background:
|
||||
radial-gradient(circle at 18% 0%, rgba(47, 123, 232, 0.12) 0%, transparent 38%),
|
||||
linear-gradient(180deg, #eef7ff 0%, #f8fbff 52%, #edf3fb 100%);
|
||||
}
|
||||
|
||||
.header {
|
||||
@@ -101,37 +107,69 @@ const openManager = () => {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 0 8px 16px;
|
||||
border-bottom: 1px solid #edf2f8;
|
||||
color: #8b98aa;
|
||||
padding: 12px 12px;
|
||||
border: 1px solid rgba(110, 153, 205, 0.18);
|
||||
border-radius: 12px;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(255, 255, 255, 0.92) 0%, rgba(232, 244, 255, 0.86) 100%);
|
||||
box-shadow:
|
||||
0 10px 24px rgba(42, 86, 143, 0.07),
|
||||
0 1px 0 rgba(255, 255, 255, 0.9) inset;
|
||||
color: #385b7f;
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.header > span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.header > span::before {
|
||||
content: "";
|
||||
width: 6px;
|
||||
height: 20px;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(180deg, #2f7be8 0%, #23b7d9 100%);
|
||||
box-shadow: 0 0 14px rgba(47, 123, 232, 0.26);
|
||||
}
|
||||
|
||||
.menu {
|
||||
flex: 1 1 auto;
|
||||
max-height: calc(100vh - 240px);
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
border-right: 0;
|
||||
padding: 14px 0 0;
|
||||
padding: 14px 2px 0;
|
||||
background: transparent;
|
||||
}
|
||||
.menu :deep(.el-menu-item) {
|
||||
position: relative;
|
||||
height: 44px;
|
||||
margin: 4px 0;
|
||||
padding: 0 10px !important;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 10px;
|
||||
color: #5f6f7a;
|
||||
color: #506475;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: 44px;
|
||||
transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
|
||||
}
|
||||
.menu :deep(.el-menu-item:hover) {
|
||||
background: rgba(31, 95, 184, 0.06);
|
||||
border-color: rgba(47, 123, 232, 0.1);
|
||||
background: rgba(255, 255, 255, 0.66);
|
||||
color: #1f5fb8;
|
||||
}
|
||||
.menu :deep(.el-menu-item.is-active) {
|
||||
background: #e7f4ff;
|
||||
color: #1f5fb8;
|
||||
border-color: rgba(47, 123, 232, 0.18);
|
||||
background:
|
||||
linear-gradient(135deg, rgba(220, 239, 255, 0.96) 0%, rgba(240, 248, 255, 0.96) 100%);
|
||||
box-shadow:
|
||||
0 10px 22px rgba(47, 123, 232, 0.12),
|
||||
3px 0 0 #2f7be8 inset;
|
||||
color: #1559ad;
|
||||
}
|
||||
.cat-icon {
|
||||
display: inline-flex;
|
||||
@@ -142,10 +180,11 @@ const openManager = () => {
|
||||
height: 24px;
|
||||
margin-right: 10px;
|
||||
border-radius: 7px;
|
||||
background: rgba(95, 111, 122, 0.08);
|
||||
color: #697982;
|
||||
background: linear-gradient(135deg, rgba(221, 234, 249, 0.9) 0%, rgba(242, 248, 255, 0.9) 100%);
|
||||
color: #517194;
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.82) inset;
|
||||
}
|
||||
.cat-icon :deep(svg) {
|
||||
font-size: 13px;
|
||||
@@ -153,20 +192,21 @@ const openManager = () => {
|
||||
height: 1em;
|
||||
}
|
||||
.menu :deep(.el-menu-item.is-active) .cat-icon {
|
||||
background: #d7ebff;
|
||||
color: #1f5fb8;
|
||||
background: linear-gradient(135deg, #2f7be8 0%, #24b7d8 100%);
|
||||
color: #ffffff;
|
||||
box-shadow: 0 8px 18px rgba(47, 123, 232, 0.25);
|
||||
}
|
||||
.category-create-btn {
|
||||
height: 34px;
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
background: #415a77;
|
||||
background: linear-gradient(135deg, #2f527a 0%, #203a5c 100%);
|
||||
font-weight: 800;
|
||||
box-shadow: 0 8px 18px rgba(65, 90, 119, 0.16);
|
||||
box-shadow: 0 8px 18px rgba(37, 67, 105, 0.2);
|
||||
}
|
||||
.category-create-btn:hover,
|
||||
.category-create-btn:focus {
|
||||
background: #344960;
|
||||
background: linear-gradient(135deg, #254866 0%, #172f4e 100%);
|
||||
}
|
||||
.name {
|
||||
flex: 1;
|
||||
@@ -183,8 +223,8 @@ const openManager = () => {
|
||||
height: 18px;
|
||||
padding: 0 6px;
|
||||
border-radius: 999px;
|
||||
background: rgba(95, 111, 122, 0.08);
|
||||
color: #697982;
|
||||
background: rgba(88, 111, 137, 0.1);
|
||||
color: #5d7590;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
line-height: 18px;
|
||||
@@ -192,7 +232,7 @@ const openManager = () => {
|
||||
}
|
||||
|
||||
.menu :deep(.el-menu-item.is-active) .cat-count {
|
||||
background: #d7ebff;
|
||||
color: #1f5fb8;
|
||||
background: linear-gradient(135deg, #cfe7ff 0%, #dcf7ff 100%);
|
||||
color: #1559ad;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<template>
|
||||
<div class="faq-list-card">
|
||||
<div class="faq-list-card" :class="{ 'faq-list-card--desktop': isDesktop }">
|
||||
<el-table
|
||||
:data="items"
|
||||
v-loading="loading"
|
||||
style="width: 100%"
|
||||
class="faq-table"
|
||||
:class="{ 'faq-table--with-actions': canDelete, 'faq-table--without-actions': !canDelete }"
|
||||
:row-class-name="rowClassName"
|
||||
:height="isDesktop ? '100%' : undefined"
|
||||
@row-click="onRowClick"
|
||||
table-layout="fixed"
|
||||
>
|
||||
<el-table-column prop="question" :label="TEXT.common.fields.question" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<div class="question-cell">
|
||||
<span class="question-icon">{{ questionInitial(scope.row.question) }}</span>
|
||||
<span class="question-icon"><el-icon><QuestionFilled /></el-icon></span>
|
||||
<el-link type="primary" :underline="false" class="question-link">
|
||||
{{ scope.row.question }}
|
||||
</el-link>
|
||||
@@ -52,12 +54,14 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { QuestionFilled } from "@element-plus/icons-vue";
|
||||
import { computed } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { deleteFaqItem } from "../api/faqs";
|
||||
import type { FaqItem, FaqCategory } from "../api/faqs";
|
||||
import { displayDateTime, displayEnum } from "../utils/display";
|
||||
import { TEXT } from "../locales";
|
||||
import { isTauriRuntime } from "../runtime";
|
||||
|
||||
const props = defineProps<{
|
||||
items: FaqItem[];
|
||||
@@ -69,6 +73,7 @@ const props = defineProps<{
|
||||
const emit = defineEmits(["refresh"]);
|
||||
|
||||
const router = useRouter();
|
||||
const isDesktop = isTauriRuntime();
|
||||
|
||||
const categoryMap = computed(() =>
|
||||
props.categories.reduce<Record<string, string>>((acc, cur) => {
|
||||
@@ -81,10 +86,6 @@ const categoryLabel = (categoryId: string) => {
|
||||
return categoryMap.value[categoryId] || categoryId || "--";
|
||||
};
|
||||
|
||||
const questionInitial = (question?: string) => {
|
||||
return String(question || "?").trim().slice(0, 1) || "?";
|
||||
};
|
||||
|
||||
const splitDateTime = (value?: string | number | Date | null) => {
|
||||
const displayValue = displayDateTime(value);
|
||||
const [date, time] = displayValue.split(" ");
|
||||
@@ -145,9 +146,10 @@ const remove = async (row: FaqItem) => {
|
||||
}
|
||||
|
||||
.faq-table :deep(.el-table__header-wrapper th.el-table__cell) {
|
||||
border-bottom: 0;
|
||||
background: transparent;
|
||||
color: #8a98aa;
|
||||
height: 46px;
|
||||
border-bottom: 1px solid #dce8f7;
|
||||
background: linear-gradient(180deg, #f7fbff 0%, #eef5fc 100%);
|
||||
color: #5d7088;
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
}
|
||||
@@ -166,21 +168,23 @@ const remove = async (row: FaqItem) => {
|
||||
}
|
||||
|
||||
.faq-table :deep(.faq-row td.el-table__cell) {
|
||||
padding: 12px 0;
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid #e8eef6;
|
||||
background: #ffffff;
|
||||
transition: background 0.18s ease;
|
||||
}
|
||||
|
||||
.faq-table :deep(.faq-row:hover td.el-table__cell) {
|
||||
background: #f8f9fb;
|
||||
background: #f7fbff;
|
||||
}
|
||||
|
||||
.faq-table :deep(col:nth-child(1)) { width: 43%; }
|
||||
.faq-table :deep(col:nth-child(2)) { width: 14%; }
|
||||
.faq-table :deep(col:nth-child(3)) { width: 14%; }
|
||||
.faq-table :deep(col:nth-child(4)) { width: 14%; }
|
||||
.faq-table :deep(col:nth-child(5)) { width: 15%; }
|
||||
.faq-table--with-actions :deep(col) {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.faq-table--without-actions :deep(col) {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -205,10 +209,19 @@ const remove = async (row: FaqItem) => {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 10px;
|
||||
background: #f3f7fb;
|
||||
color: #5e6f7b;
|
||||
font-size: 15px;
|
||||
background:
|
||||
radial-gradient(circle at 26% 22%, rgba(255, 255, 255, 0.42) 0%, transparent 28%),
|
||||
linear-gradient(135deg, #2f7be8 0%, #23b7d9 100%);
|
||||
color: #ffffff;
|
||||
font-size: 17px;
|
||||
font-weight: 800;
|
||||
box-shadow:
|
||||
0 10px 20px rgba(47, 123, 232, 0.2),
|
||||
0 1px 0 rgba(255, 255, 255, 0.45) inset;
|
||||
}
|
||||
|
||||
.question-icon :deep(.el-icon) {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.question-link {
|
||||
@@ -257,4 +270,128 @@ const remove = async (row: FaqItem) => {
|
||||
.question-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
flex: 1 1 auto;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-table__inner-wrapper) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-table__header-wrapper th.el-table__cell) {
|
||||
height: 42px;
|
||||
padding: 0 14px;
|
||||
border-bottom: 1px solid rgba(121, 152, 188, 0.28) !important;
|
||||
background: linear-gradient(180deg, #f4f9ff 0%, #eaf3fc 100%) !important;
|
||||
color: #49647f;
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-table__body) {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 6px;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-table__body-wrapper) {
|
||||
background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-table__body-wrapper::-webkit-scrollbar),
|
||||
.faq-list-card--desktop .faq-table :deep(.el-scrollbar__wrap::-webkit-scrollbar) {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-scrollbar__wrap) {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-scrollbar__bar.is-vertical) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.el-table__empty-block) {
|
||||
min-height: 100%;
|
||||
background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.faq-row td.el-table__cell) {
|
||||
padding: 10px 14px;
|
||||
border-top: 1px solid rgba(226, 235, 246, 0.92);
|
||||
border-bottom: 1px solid rgba(226, 235, 246, 0.92);
|
||||
background: #ffffff;
|
||||
transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.faq-row td.el-table__cell:first-child) {
|
||||
border-left: 1px solid rgba(226, 235, 246, 0.92);
|
||||
border-radius: 9px 0 0 9px;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.faq-row td.el-table__cell:last-child) {
|
||||
border-right: 1px solid rgba(226, 235, 246, 0.92);
|
||||
border-radius: 0 9px 9px 0;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .faq-table :deep(.faq-row:hover td.el-table__cell) {
|
||||
border-color: rgba(111, 159, 220, 0.34);
|
||||
background: #f5faff;
|
||||
box-shadow: 0 8px 18px rgba(45, 86, 143, 0.06);
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .question-cell {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .question-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
box-shadow:
|
||||
0 8px 16px rgba(47, 123, 232, 0.18),
|
||||
0 1px 0 rgba(255, 255, 255, 0.45) inset;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .question-link {
|
||||
color: #0f172a;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .category-pill {
|
||||
height: 24px;
|
||||
padding: 0 9px;
|
||||
border-radius: 7px;
|
||||
background: linear-gradient(135deg, #e7f3ff 0%, #eefaff 100%);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.faq-list-card--desktop .time-text {
|
||||
gap: 0;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
:global([data-ctms-theme="dark"] .faq-list-card--desktop .faq-table .faq-row td.el-table__cell) {
|
||||
border-color: #26364a;
|
||||
background: #172033;
|
||||
}
|
||||
|
||||
:global([data-ctms-theme="dark"] .faq-list-card--desktop .faq-table .faq-row:hover td.el-table__cell) {
|
||||
background: #1d2b42;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const readLayoutSource = () => readFileSync(resolve(__dirname, "./Layout.vue"), "utf8");
|
||||
const readAppSource = () => readFileSync(resolve(__dirname, "../App.vue"), "utf8");
|
||||
const readDesktopLayoutSource = () => readFileSync(resolve(__dirname, "./DesktopLayout.vue"), "utf8");
|
||||
const readWebLayoutSource = () => readFileSync(resolve(__dirname, "./WebLayout.vue"), "utf8");
|
||||
const readNavigationSource = () => readFileSync(resolve(__dirname, "./layout/navigation.ts"), "utf8");
|
||||
@@ -17,23 +18,40 @@ const readFileTaskFeedbackSource = () => readFileSync(resolve(__dirname, "../uti
|
||||
const readAttachmentListSource = () => readFileSync(resolve(__dirname, "./attachments/AttachmentList.vue"), "utf8");
|
||||
const readDocumentDetailSource = () => readFileSync(resolve(__dirname, "../views/documents/DocumentDetail.vue"), "utf8");
|
||||
const readMainStyleSource = () => readFileSync(resolve(__dirname, "../styles/main.css"), "utf8");
|
||||
const readFaqSource = () => readFileSync(resolve(__dirname, "../views/Faq.vue"), "utf8");
|
||||
const readFaqListSource = () => readFileSync(resolve(__dirname, "./FaqList.vue"), "utf8");
|
||||
const readProjectOverviewSource = () => readFileSync(resolve(__dirname, "../views/ia/ProjectOverview.vue"), "utf8");
|
||||
|
||||
describe("desktop layout shell", () => {
|
||||
it("routes desktop and web shells through the runtime flag", () => {
|
||||
const source = readLayoutSource();
|
||||
const app = readAppSource();
|
||||
|
||||
expect(source).toContain("const isDesktop = isTauriRuntime()");
|
||||
expect(source).toContain("<DesktopLayout v-if=\"isDesktop\" />");
|
||||
expect(source).toContain("<WebLayout v-else />");
|
||||
expect(app).toContain("const isDesktopRuntime = isTauriRuntime();");
|
||||
expect(app).toContain('document.body.classList.add("is-desktop-runtime")');
|
||||
expect(app).toContain('document.body.classList.remove("is-desktop-runtime")');
|
||||
});
|
||||
|
||||
it("uses route-only desktop preference storage", () => {
|
||||
const source = readDesktopLayoutSource();
|
||||
const webSource = readWebLayoutSource();
|
||||
|
||||
expect(source).toContain("readDesktopRecentRoutes");
|
||||
expect(source).toContain("readDesktopFavoriteRoutes");
|
||||
expect(source).toContain("recordDesktopRecentRoute");
|
||||
expect(source).toContain("currentDesktopRoutePreference");
|
||||
expect(source).toContain("toggleDesktopFavoriteRoute");
|
||||
expect(source).not.toContain("readDesktopRecentRoutes");
|
||||
expect(source).not.toContain("recordDesktopRecentRoute");
|
||||
expect(source).not.toContain("desktopRecentRoutes");
|
||||
expect(source).not.toContain("最近访问");
|
||||
expect(webSource).toContain("readDesktopFavoriteRoutes");
|
||||
expect(webSource).toContain("toggleDesktopFavoriteRoute");
|
||||
expect(webSource).not.toContain("readDesktopRecentRoutes");
|
||||
expect(webSource).not.toContain("recordDesktopRecentRoute");
|
||||
expect(webSource).not.toContain("desktopRecentRoutes");
|
||||
expect(webSource).not.toContain("最近访问");
|
||||
});
|
||||
|
||||
it("shares active route mapping between web and desktop shells", () => {
|
||||
@@ -86,12 +104,35 @@ describe("desktop layout shell", () => {
|
||||
expect(tauriConfig).toContain('"titleBarStyle": "Overlay"');
|
||||
expect(tauriConfig).toContain('"hiddenTitle": true');
|
||||
expect(tauriConfig).toContain('"trafficLightPosition": { "x": 16, "y": 18 }');
|
||||
expect(layout).toContain("padding: 54px 16px 14px;");
|
||||
expect(layout).toContain("padding: 44px 10px 10px;");
|
||||
expect(layout).toContain("-webkit-app-region: drag;");
|
||||
expect(layout).toContain("-webkit-app-region: no-drag;");
|
||||
expect(layout).not.toContain(["@tauri-apps", "api", "window"].join("/"));
|
||||
});
|
||||
|
||||
it("keeps the desktop sidebar dense enough for navigation-heavy screens", () => {
|
||||
const layout = readDesktopLayoutSource();
|
||||
const sidebarHeadStart = layout.indexOf('<header class="sidebar-head">');
|
||||
const sidebarHeadEnd = layout.indexOf("</header>", sidebarHeadStart);
|
||||
const sidebarHeadTemplate = layout.slice(sidebarHeadStart, sidebarHeadEnd);
|
||||
|
||||
expect(layout).toContain("grid-template-columns: 248px minmax(0, 1fr);");
|
||||
expect(layout).toContain("padding: 44px 10px 10px;");
|
||||
expect(layout).toContain("grid-template-columns: auto minmax(0, 1fr);");
|
||||
expect(layout).toContain("width: 140px;");
|
||||
expect(layout).toContain("margin-top: 0;");
|
||||
expect(layout).toContain("padding: 10px 8px 24px;");
|
||||
expect(layout).toContain("margin-top: 12px;");
|
||||
expect(layout).toContain("font-size: 14px;");
|
||||
expect(sidebarHeadTemplate).toContain('<div class="sidebar-title-row">');
|
||||
expect(sidebarHeadTemplate.indexOf("<h1>{{ TEXT.common.appName }}</h1>")).toBeLessThan(
|
||||
sidebarHeadTemplate.indexOf('<el-dropdown v-if="study.currentStudy"'),
|
||||
);
|
||||
expect(layout).not.toContain("grid-template-columns: 272px minmax(0, 1fr);");
|
||||
expect(layout).not.toContain("padding: 54px 16px 14px;");
|
||||
expect(layout).not.toContain("padding: 44px 12px 12px;");
|
||||
});
|
||||
|
||||
it("renders desktop preferences as a split settings panel", () => {
|
||||
const preferences = readDesktopPreferencesSource();
|
||||
const desktopLayout = readDesktopLayoutSource();
|
||||
@@ -187,6 +228,8 @@ describe("desktop layout shell", () => {
|
||||
expect(tabsTemplate).not.toContain('@click="router.push(item.path)"');
|
||||
expect(source).not.toContain(".slice(-7)");
|
||||
expect(tabsTemplate).toContain('@contextmenu.prevent.stop="openWorkspaceTabMenu(item, $event)"');
|
||||
expect(tabsTemplate).not.toContain('class="tab-group"');
|
||||
expect(tabsTemplate).not.toContain("{{ item.group }}");
|
||||
expect(source).toContain("const lastClosedWorkspaceTab = ref<DesktopRoutePreference | null>(null);");
|
||||
expect(source).toContain("const workspaceTabMenu = ref<");
|
||||
expect(source).toContain("const closeOtherWorkspaceTabs = (path: string) => {");
|
||||
@@ -306,18 +349,89 @@ describe("desktop layout shell", () => {
|
||||
const styles = readMainStyleSource();
|
||||
|
||||
expect(styles).toContain("/* Desktop workbench density */");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell.page");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell.ctms-page-shell");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .page-body");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .page-inner");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .overview");
|
||||
expect(styles).toContain("padding: 0 !important;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .table-card");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .hero-banner");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .faq-hero");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .page-bg-dots");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .module-placeholder-surface");
|
||||
expect(styles).toContain("box-shadow: none !important;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-table th.el-table__cell");
|
||||
expect(styles).toContain("height: 34px;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-table td.el-table__cell");
|
||||
expect(styles).toContain("padding: 7px 10px;");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-pagination");
|
||||
expect(styles).toContain(".desktop-workbench .desktop-route-shell .el-drawer__body");
|
||||
expect(styles).toContain(":root[data-ctms-theme=\"dark\"] .desktop-workbench .desktop-route-shell .hero-stat");
|
||||
});
|
||||
|
||||
it("renders Element Plus modals with desktop-native surfaces in the desktop runtime", () => {
|
||||
const styles = readMainStyleSource();
|
||||
|
||||
expect(styles).toContain("/* Desktop runtime modal surfaces */");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-overlay");
|
||||
expect(styles).toContain("left: 0 !important;");
|
||||
expect(styles).toContain("backdrop-filter: blur(12px) saturate(135%);");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-overlay-dialog");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-overlay-message-box");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-dialog,");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-message-box");
|
||||
expect(styles).toContain("border-radius: 12px;");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-dialog__header");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-message-box__header");
|
||||
expect(styles).toContain("body.is-desktop-runtime .desktop-preferences-dialog");
|
||||
expect(styles).toContain("body.is-desktop-runtime .desktop-preferences-dialog .el-dialog__body");
|
||||
expect(styles).toContain("body.is-desktop-runtime .desktop-preferences-dialog .el-dialog__body {\n padding: 0;");
|
||||
expect(styles).toContain("body.is-desktop-runtime .el-message-box__btns");
|
||||
expect(styles).toContain("body.is-desktop-runtime .dialog-fade-enter-from .el-dialog");
|
||||
expect(styles).toContain("body.is-desktop-runtime .msgbox-fade-enter-from .el-message-box");
|
||||
expect(styles).toContain(':root[data-ctms-theme="dark"] body.is-desktop-runtime .desktop-preferences-dialog');
|
||||
expect(styles).toContain(':root[data-ctms-theme="dark"] body.is-desktop-runtime .el-dialog');
|
||||
});
|
||||
|
||||
it("keeps first-pass desktop content pages workbench-oriented", () => {
|
||||
const faq = readFaqSource();
|
||||
const faqList = readFaqListSource();
|
||||
const projectOverview = readProjectOverviewSource();
|
||||
|
||||
expect(faq).toContain("const isDesktop = isTauriRuntime();");
|
||||
expect(faq).toContain(":class=\"{ 'medical-consult-page--desktop': isDesktop }\"");
|
||||
expect(faq).toContain('v-if="!isDesktop" class="page-bg-dots"');
|
||||
expect(faq).toContain('<h1 v-if="!isDesktop"');
|
||||
expect(faq).toContain('v-else class="desktop-toolbar-meta"');
|
||||
expect(faq).toContain('v-if="isDesktop" action="faq.create"');
|
||||
expect(faq).toContain('<div v-if="!isDesktop" class="list-toolbar">');
|
||||
expect(faq).toContain(".medical-consult-page--desktop .faq-workspace");
|
||||
expect(faq).toContain("grid-template-columns: 236px minmax(0, 1fr);");
|
||||
expect(faqList).toContain(":class=\"{ 'faq-list-card--desktop': isDesktop }\"");
|
||||
expect(faqList).toContain("const isDesktop = isTauriRuntime();");
|
||||
expect(faqList).toContain(".faq-list-card--desktop .faq-table");
|
||||
expect(projectOverview).toContain(":class=\"{ 'project-overview--desktop': isDesktop }\"");
|
||||
expect(projectOverview).not.toContain("overview-summary-strip");
|
||||
expect(projectOverview).not.toContain("const activeCenterCount");
|
||||
expect(projectOverview).toContain("desktop-attention-section");
|
||||
expect(projectOverview).toContain("desktop-attention-head");
|
||||
expect(projectOverview).toContain("更新 {{ overviewUpdatedAtLabel }}");
|
||||
expect(projectOverview).toContain("overview-workbench");
|
||||
expect(projectOverview).toContain("enrollment-snapshot");
|
||||
expect(projectOverview).toContain("desktop-attention-board");
|
||||
expect(projectOverview).toContain("const stageStatusSummary");
|
||||
expect(projectOverview).toContain("const activeStageItems");
|
||||
expect(projectOverview).toContain("const attentionItems");
|
||||
expect(projectOverview).toContain("grid-template-columns: minmax(620px, 1fr) minmax(300px, 360px);");
|
||||
expect(projectOverview).toContain("max-height: min(360px, calc(100vh - 300px));");
|
||||
expect(projectOverview).toContain("@media (max-width: 1240px)");
|
||||
expect(projectOverview).toContain(".project-overview--desktop .overview-card");
|
||||
expect(projectOverview).toContain(".project-overview--desktop .overview-card--enrollment");
|
||||
expect(projectOverview).toContain(".project-overview--desktop :deep(.center-row)");
|
||||
expect(projectOverview).toContain(".project-overview--desktop :deep(.stage-node)");
|
||||
});
|
||||
|
||||
it("keeps desktop entry surfaces stable at the minimum window size", () => {
|
||||
const login = readLoginSource();
|
||||
const serverSettings = readDesktopServerSettingsSource();
|
||||
|
||||
@@ -22,16 +22,6 @@
|
||||
</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
|
||||
<el-menu-item-group v-if="isDesktop && desktopRecentRoutes.length" class="menu-group desktop-menu-group">
|
||||
<template #title>
|
||||
<span class="menu-divider">最近访问</span>
|
||||
</template>
|
||||
<el-menu-item v-for="item in desktopRecentRoutes" :key="`recent:${item.path}`" :index="item.path">
|
||||
<el-icon><Clock /></el-icon>
|
||||
<span>{{ item.title }}</span>
|
||||
</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
|
||||
<el-menu-item-group v-if="auth.user" class="menu-group">
|
||||
<template #title>
|
||||
<span class="menu-divider">{{ TEXT.menu.admin }}</span>
|
||||
@@ -434,13 +424,12 @@ import { forceLogout, LOGOUT_REASON_MANUAL } from "../session/sessionManager";
|
||||
import { checkDesktopUpdateAndPrompt } from "../session/desktopUpdateManager";
|
||||
import {
|
||||
DESKTOP_SERVER_URL_CHANGED_EVENT,
|
||||
clearLegacyDesktopRouteHistoryPreference,
|
||||
getAppMetadata,
|
||||
getDesktopServerUrl,
|
||||
isTauriRuntime,
|
||||
listenDesktopMenuCommand,
|
||||
readDesktopFavoriteRoutes,
|
||||
readDesktopRecentRoutes,
|
||||
recordDesktopRecentRoute,
|
||||
toggleDesktopFavoriteRoute,
|
||||
type DesktopRoutePreference,
|
||||
} from "../runtime";
|
||||
@@ -472,7 +461,6 @@ const profileDialogDirty = ref(false);
|
||||
const commandPaletteVisible = ref(false);
|
||||
const desktopPreferencesVisible = ref(false);
|
||||
const desktopServerUrl = ref(getDesktopServerUrl());
|
||||
const desktopRecentRoutes = ref<DesktopRoutePreference[]>(readDesktopRecentRoutes());
|
||||
const desktopFavoriteRoutes = ref<DesktopRoutePreference[]>(readDesktopFavoriteRoutes());
|
||||
const headerOverviewStats = ref<{
|
||||
centerActual: number;
|
||||
@@ -720,9 +708,6 @@ const desktopNavigationItems = computed<DesktopNavigationItem[]>(() => {
|
||||
|
||||
const refreshDesktopRoutePreferences = () => {
|
||||
if (!isDesktop) return;
|
||||
desktopRecentRoutes.value = readDesktopRecentRoutes().filter((item) =>
|
||||
desktopNavigationItems.value.some((navItem) => navItem.path === item.path),
|
||||
);
|
||||
desktopFavoriteRoutes.value = readDesktopFavoriteRoutes().filter((item) =>
|
||||
desktopNavigationItems.value.some((navItem) => navItem.path === item.path),
|
||||
);
|
||||
@@ -1084,7 +1069,6 @@ watch(() => route.path, () => {
|
||||
if (isDesktop) {
|
||||
const current = currentDesktopRoutePreference.value;
|
||||
if (current) {
|
||||
desktopRecentRoutes.value = recordDesktopRecentRoute(current);
|
||||
refreshDesktopRoutePreferences();
|
||||
}
|
||||
}
|
||||
@@ -1145,10 +1129,7 @@ onMounted(async () => {
|
||||
}, 1000);
|
||||
if (isDesktop) {
|
||||
window.addEventListener(DESKTOP_SERVER_URL_CHANGED_EVENT, updateDesktopServerUrl);
|
||||
const current = currentDesktopRoutePreference.value;
|
||||
if (current) {
|
||||
desktopRecentRoutes.value = recordDesktopRecentRoute(current);
|
||||
}
|
||||
clearLegacyDesktopRouteHistoryPreference();
|
||||
refreshDesktopRoutePreferences();
|
||||
desktopMenuUnlisten = await listenDesktopMenuCommand(handleDesktopMenuCommand).catch(() => undefined);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user