feat: 统一管理端弹窗与内容区交互样式

- 收敛管理端公共 Modal 链路,新增表单弹窗与普通内容弹窗包装\n- 迁移 Bot、知识库、插件、工作流、资源、MCP、数据中枢与系统管理页面级弹窗\n- 统一内容区工具栏、列表容器、导航与顶部按钮的视觉密度和交互节奏
This commit is contained in:
2026-03-06 19:58:26 +08:00
parent 76c2954a70
commit b191d1aaed
99 changed files with 3148 additions and 1623 deletions

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup>
import type { CSSProperties } from 'vue';
import { computed, useSlots } from 'vue';
import { useRefresh } from '@easyflow/hooks';
@@ -34,6 +36,26 @@ withDefaults(defineProps<Props>(), {
const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
const REFERENCE_VALUE = 50;
const toolbarButtonClass =
'mr-1 flex h-9 w-9 items-center justify-center rounded-2xl text-[hsl(var(--nav-item-muted-foreground))] backdrop-blur-xl transition-[background-color,color,transform,box-shadow,border-color] hover:-translate-y-0.5 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--primary))/0.2]';
const toolbarButtonStyle: CSSProperties = {
backgroundColor: 'hsl(var(--nav-tool-bg) / 0.92)',
backgroundImage:
'linear-gradient(180deg, hsl(var(--nav-tool-bg) / 0.96), hsl(var(--glass-tint) / 0.8))',
border: '1px solid transparent',
boxShadow: '0 18px 36px -28px hsl(var(--primary) / 0.24)',
};
const breadcrumbShellStyle: CSSProperties = {
backgroundColor: 'hsl(var(--glass-tint) / 0.66)',
backgroundImage:
'linear-gradient(180deg, hsl(var(--glass-tint) / 0.8), hsl(var(--nav-surface-subtle) / 0.58))',
border: '1px solid transparent',
boxShadow:
'inset 0 1px 0 hsl(var(--nav-sheen) / 0.42), 0 18px 36px -30px hsl(var(--primary) / 0.14)',
};
const rightShellStyle: CSSProperties = {
backgroundColor: 'hsl(var(--glass-tint) / 0.28)',
};
const accessStore = useAccessStore();
const { globalSearchShortcutKey, preferencesButtonPosition } = usePreferences();
@@ -120,61 +142,61 @@ function clearPreferencesAndLogout() {
</script>
<template>
<template
v-for="slot in leftSlots.filter((item) => item.index < REFERENCE_VALUE)"
:key="slot.name"
<div
v-if="$slots.breadcrumb"
:style="breadcrumbShellStyle"
class="hidden min-w-0 max-w-[min(520px,46vw)] items-center rounded-full px-3 py-1.5 lg:flex"
>
<slot name="breadcrumb"></slot>
</div>
<template v-for="slot in leftSlots" :key="slot.name">
<slot :name="slot.name">
<template v-if="slot.name === 'refresh'">
<EasyFlowIconButton class="my-0 mr-1 rounded-md" @click="refresh">
<EasyFlowIconButton
:class="toolbarButtonClass"
:style="toolbarButtonStyle"
@click="refresh"
>
<RotateCw class="size-4" />
</EasyFlowIconButton>
</template>
</slot>
</template>
<div class="flex-center hidden lg:block">
<slot name="breadcrumb"></slot>
</div>
<template
v-for="slot in leftSlots.filter((item) => item.index > REFERENCE_VALUE)"
:key="slot.name"
>
<slot :name="slot.name"></slot>
</template>
<div
:class="`menu-align-${preferences.header.menuAlign}`"
class="flex h-full min-w-0 flex-1 items-center"
class="flex h-full min-w-0 flex-1 items-center px-3"
>
<slot name="menu"></slot>
</div>
<div class="flex h-full min-w-0 flex-shrink-0 items-center">
<div :style="rightShellStyle" class="flex h-full min-w-0 flex-shrink-0 items-center gap-1 rounded-full px-2 py-1 pl-2">
<template v-for="slot in rightSlots" :key="slot.name">
<slot :name="slot.name">
<template v-if="slot.name === 'global-search'">
<GlobalSearch
:enable-shortcut-key="globalSearchShortcutKey"
:menus="accessStore.accessMenus"
class="mr-1 sm:mr-4"
class="mr-0"
/>
</template>
<template v-else-if="slot.name === 'preferences'">
<PreferencesButton
class="mr-1"
:class="toolbarButtonClass"
:style="toolbarButtonStyle"
@clear-preferences-and-logout="clearPreferencesAndLogout"
/>
</template>
<template v-else-if="slot.name === 'theme-toggle'">
<ThemeToggle class="mr-1 mt-[2px]" />
<ThemeToggle :class="toolbarButtonClass" :style="toolbarButtonStyle" />
</template>
<template v-else-if="slot.name === 'language-toggle'">
<LanguageToggle class="mr-1" />
<LanguageToggle :class="toolbarButtonClass" :style="toolbarButtonStyle" />
</template>
<template v-else-if="slot.name === 'fullscreen'">
<EasyFlowFullScreen class="mr-1" />
<EasyFlowFullScreen :class="toolbarButtonClass" :style="toolbarButtonStyle" />
</template>
<template v-else-if="slot.name === 'timezone'">
<TimezoneButton class="mr-1 mt-[2px]" />
<TimezoneButton :class="toolbarButtonClass" :style="toolbarButtonStyle" />
</template>
</slot>
</template>

View File

@@ -283,7 +283,7 @@ const headerSlots = computed(() => {
<Breadcrumb
:hide-when-only-one="preferences.breadcrumb.hideOnlyOne"
:show-home="preferences.breadcrumb.showHome"
:show-icon="preferences.breadcrumb.showIcon"
:show-icon="false"
:type="preferences.breadcrumb.styleType"
/>
</template>

View File

@@ -63,7 +63,7 @@ if (!preferences.tabbar.persist) {
@unpin="unpinTab"
@update:active="handleClick"
/>
<div class="flex-center h-full">
<div class="flex-center h-full gap-1 pr-2">
<TabsToolMore v-if="preferences.tabbar.showMore" :menus="menus" />
<TabsToolScreen
v-if="preferences.tabbar.showMaximize"