2024-05-19 21:20:42 +08:00
|
|
|
<script setup lang="ts">
|
2024-05-21 22:14:25 +08:00
|
|
|
import type { LayoutHeaderMode, LayoutType } from '@vben/types';
|
2024-05-19 21:20:42 +08:00
|
|
|
import type { SegmentedItem } from '@vben-core/shadcn-ui';
|
|
|
|
|
|
|
|
import { IcRoundFolderCopy, IcRoundRestartAlt } from '@vben-core/iconify';
|
|
|
|
import {
|
|
|
|
VbenButton,
|
|
|
|
VbenIconButton,
|
|
|
|
VbenSegmented,
|
|
|
|
VbenSheet,
|
|
|
|
toast,
|
|
|
|
} from '@vben-core/shadcn-ui';
|
|
|
|
|
|
|
|
import { $t } from '@vben/locales';
|
|
|
|
import { preference, resetPreference, usePreference } from '@vben/preference';
|
|
|
|
import { useClipboard } from '@vueuse/core';
|
|
|
|
import { computed, ref } from 'vue';
|
|
|
|
|
|
|
|
import {
|
|
|
|
Animation,
|
|
|
|
Block,
|
|
|
|
Breadcrumb,
|
|
|
|
ColorMode,
|
|
|
|
Content,
|
|
|
|
Footer,
|
|
|
|
General,
|
|
|
|
Header,
|
|
|
|
Layout,
|
|
|
|
Navigation,
|
|
|
|
Sidebar,
|
|
|
|
Tabs,
|
|
|
|
Theme,
|
|
|
|
ThemeColor,
|
|
|
|
} from './blocks';
|
|
|
|
import Trigger from './trigger.vue';
|
|
|
|
|
|
|
|
withDefaults(defineProps<{ colorPrimaryPresets: string[] }>(), {
|
|
|
|
colorPrimaryPresets: () => [],
|
|
|
|
});
|
|
|
|
|
|
|
|
const theme = defineModel<string>('theme');
|
|
|
|
const locale = defineModel<string>('locale');
|
|
|
|
const semiDarkMenu = defineModel<boolean>('semiDarkMenu');
|
|
|
|
const breadcrumbVisible = defineModel<boolean>('breadcrumbVisible');
|
|
|
|
const breadcrumbIcon = defineModel<boolean>('breadcrumbIcon');
|
|
|
|
const breadcrumbHome = defineModel<boolean>('breadcrumbHome');
|
|
|
|
const breadcrumbStyle = defineModel<string>('breadcrumbStyle');
|
|
|
|
const breadcrumbHideOnlyOne = defineModel<boolean>('breadcrumbHideOnlyOne');
|
|
|
|
const sideCollapseShowTitle = defineModel<boolean>('sideCollapseShowTitle');
|
|
|
|
const sideCollapse = defineModel<boolean>('sideCollapse');
|
|
|
|
const colorWeakMode = defineModel<boolean>('colorWeakMode');
|
|
|
|
const colorGrayMode = defineModel<boolean>('colorGrayMode');
|
|
|
|
const colorPrimary = defineModel<string>('colorPrimary');
|
|
|
|
const navigationStyle = defineModel<string>('navigationStyle');
|
|
|
|
const pageProgress = defineModel<boolean>('pageProgress');
|
|
|
|
const pageTransition = defineModel<string>('pageTransition');
|
|
|
|
const pageTransitionEnable = defineModel<boolean>('pageTransitionEnable');
|
|
|
|
const layout = defineModel<LayoutType>('layout');
|
|
|
|
const contentCompact = defineModel<string>('contentCompact');
|
|
|
|
const sideVisible = defineModel<boolean>('sideVisible');
|
|
|
|
const tabsVisible = defineModel<boolean>('tabsVisible');
|
|
|
|
const tabsIcon = defineModel<boolean>('tabsIcon');
|
|
|
|
// const logoVisible = defineModel<boolean>('logoVisible');
|
|
|
|
const headerVisible = defineModel<boolean>('headerVisible');
|
|
|
|
const headerMode = defineModel<LayoutHeaderMode>('headerMode');
|
|
|
|
const footerVisible = defineModel<boolean>('footerVisible');
|
|
|
|
const footerFixed = defineModel<boolean>('footerFixed');
|
|
|
|
|
|
|
|
const { diffPreference, isFullContent, isHeaderNav, isMixedNav, isSideMode } =
|
|
|
|
usePreference();
|
|
|
|
const { copy } = useClipboard();
|
|
|
|
|
|
|
|
const tabs = computed((): SegmentedItem[] => {
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
label: $t('preference.appearance'),
|
|
|
|
value: 'appearance',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: $t('preference.layout'),
|
|
|
|
value: 'layout',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: $t('preference.general'),
|
|
|
|
value: 'general',
|
|
|
|
},
|
|
|
|
];
|
|
|
|
});
|
|
|
|
|
|
|
|
const showBreadcrumbConfig = computed(() => {
|
|
|
|
return (
|
|
|
|
!isFullContent.value &&
|
|
|
|
!isMixedNav.value &&
|
|
|
|
!isHeaderNav.value &&
|
|
|
|
preference.headerVisible
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
const openSheet = ref(false);
|
|
|
|
|
|
|
|
function handlerOpenSheet() {
|
|
|
|
openSheet.value = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function handleCopy() {
|
|
|
|
await copy(JSON.stringify(diffPreference.value, null, 2));
|
|
|
|
|
|
|
|
toast($t('preference.copy-success'));
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleReset() {
|
|
|
|
if (!diffPreference.value) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
resetPreference();
|
|
|
|
toast($t('preference.reset-success'));
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<div class="z-100 fixed right-0 top-1/3">
|
|
|
|
<VbenSheet
|
|
|
|
:description="$t('preference.preferences-subtitle')"
|
|
|
|
:title="$t('preference.preferences')"
|
|
|
|
>
|
|
|
|
<template #trigger>
|
|
|
|
<Trigger @click="handlerOpenSheet" />
|
|
|
|
</template>
|
|
|
|
<template #extra>
|
|
|
|
<VbenIconButton
|
|
|
|
class="relative"
|
|
|
|
:disabled="!diffPreference"
|
|
|
|
:tooltip="$t('preference.reset-tip')"
|
|
|
|
>
|
|
|
|
<span
|
|
|
|
v-if="diffPreference"
|
|
|
|
class="bg-primary absolute right-0.5 top-0.5 h-2 w-2 rounded"
|
|
|
|
></span>
|
|
|
|
<IcRoundRestartAlt class="size-5" @click="handleReset" />
|
|
|
|
</VbenIconButton>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<div class="p-5 pt-4">
|
|
|
|
<VbenSegmented :tabs="tabs" default-value="appearance">
|
|
|
|
<template #appearance>
|
|
|
|
<Block :title="$t('preference.theme')">
|
|
|
|
<Theme v-model="theme" v-model:semi-dark-menu="semiDarkMenu" />
|
|
|
|
</Block>
|
|
|
|
<Block :title="$t('preference.theme-color')">
|
|
|
|
<ThemeColor
|
|
|
|
v-model="colorPrimary"
|
|
|
|
:color-primary-presets="colorPrimaryPresets"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
<Block :title="$t('preference.other')">
|
|
|
|
<ColorMode
|
|
|
|
v-model:color-gray-mode="colorGrayMode"
|
|
|
|
v-model:color-weak-mode="colorWeakMode"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
</template>
|
|
|
|
<template #layout>
|
|
|
|
<Block :title="$t('preference.layout')">
|
|
|
|
<Layout v-model="layout" />
|
|
|
|
</Block>
|
|
|
|
<Block :title="$t('preference.content')">
|
|
|
|
<Content v-model="contentCompact" />
|
|
|
|
</Block>
|
|
|
|
|
|
|
|
<Block :title="$t('preference.sidebar')">
|
|
|
|
<Sidebar
|
|
|
|
v-model:side-visible="sideVisible"
|
|
|
|
v-model:side-collapse="sideCollapse"
|
|
|
|
v-model:side-collapse-show-title="sideCollapseShowTitle"
|
|
|
|
:disabled="!isSideMode"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
|
|
|
|
<Block :title="$t('preference.header')">
|
|
|
|
<Header
|
|
|
|
v-model:header-visible="headerVisible"
|
|
|
|
v-model:headerMode="headerMode"
|
|
|
|
:disabled="isFullContent"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
|
|
|
|
<Block :title="$t('preference.breadcrumb')">
|
|
|
|
<Breadcrumb
|
|
|
|
v-model:breadcrumb-visible="breadcrumbVisible"
|
|
|
|
v-model:breadcrumb-icon="breadcrumbIcon"
|
|
|
|
v-model:breadcrumb-style="breadcrumbStyle"
|
|
|
|
v-model:breadcrumb-home="breadcrumbHome"
|
|
|
|
v-model:breadcrumb-hide-only-one="breadcrumbHideOnlyOne"
|
|
|
|
:disabled="!showBreadcrumbConfig"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
|
|
|
|
<Block :title="$t('preference.tabs')">
|
|
|
|
<Tabs
|
|
|
|
v-model:tabs-visible="tabsVisible"
|
|
|
|
v-model:tabs-icon="tabsIcon"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
<Block :title="$t('preference.footer')">
|
|
|
|
<Footer
|
|
|
|
v-model:footer-visible="footerVisible"
|
|
|
|
v-model:footer-fixed="footerFixed"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
</template>
|
|
|
|
<template #general>
|
|
|
|
<Block :title="$t('preference.general')">
|
|
|
|
<General v-model:locale="locale" />
|
|
|
|
</Block>
|
|
|
|
<Block :title="$t('preference.navigation-menu')">
|
|
|
|
<Navigation
|
|
|
|
v-model:navigation-style="navigationStyle"
|
|
|
|
:disabled="isFullContent"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
|
|
|
|
<Block :title="$t('preference.animation')">
|
|
|
|
<Animation
|
|
|
|
v-model:page-progress="pageProgress"
|
|
|
|
v-model:page-transition="pageTransition"
|
|
|
|
v-model:page-transition-enable="pageTransitionEnable"
|
|
|
|
/>
|
|
|
|
</Block>
|
|
|
|
</template>
|
|
|
|
</VbenSegmented>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<template #footer>
|
|
|
|
<VbenButton
|
|
|
|
class="mx-6 w-full"
|
|
|
|
variant="default"
|
|
|
|
size="sm"
|
|
|
|
:disabled="!diffPreference"
|
|
|
|
@click="handleCopy"
|
|
|
|
>
|
|
|
|
<IcRoundFolderCopy class="mr-2 size-3" />
|
|
|
|
{{ $t('preference.copy') }}
|
|
|
|
</VbenButton>
|
|
|
|
</template>
|
|
|
|
</VbenSheet>
|
|
|
|
</div>
|
|
|
|
</template>
|