feat: 统一管理端弹窗与内容区交互样式
- 收敛管理端公共 Modal 链路,新增表单弹窗与普通内容弹窗包装\n- 迁移 Bot、知识库、插件、工作流、资源、MCP、数据中枢与系统管理页面级弹窗\n- 统一内容区工具栏、列表容器、导航与顶部按钮的视觉密度和交互节奏
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user