refactor: refacotr preference

This commit is contained in:
vben
2024-06-01 23:15:29 +08:00
parent f7b97e8a83
commit fed47f5e05
139 changed files with 2205 additions and 1450 deletions

View File

@@ -46,10 +46,10 @@
"dependencies": {
"@vben-core/design": "workspace:*",
"@vben-core/iconify": "workspace:*",
"@vben-core/preferences": "workspace:*",
"@vben-core/shadcn-ui": "workspace:*",
"@vben-core/toolkit": "workspace:*",
"@vben/locales": "workspace:*",
"@vben/preference": "workspace:*",
"@vueuse/core": "^10.10.0",
"@vueuse/integrations": "^10.10.0",
"qrcode": "^1.5.3",

View File

@@ -1,20 +1,21 @@
<script setup lang="ts">
import { IcRoundColorLens } from '@vben-core/iconify';
import { VbenIconButton } from '@vben-core/shadcn-ui';
import {
preference,
staticPreference,
updatePreference,
} from '@vben/preference';
COLOR_PRIMARY_RESETS,
preferences,
updatePreferences,
} from '@vben-core/preferences';
import { VbenIconButton } from '@vben-core/shadcn-ui';
defineOptions({
name: 'AuthenticationColorToggle',
});
function handleUpdate(value: string) {
updatePreference({
colorPrimary: value,
updatePreferences({
theme: {
colorPrimary: value,
},
});
}
</script>
@@ -24,10 +25,7 @@ function handleUpdate(value: string) {
<div
class="ease-ou flex w-0 overflow-hidden transition-all duration-500 group-hover:w-48"
>
<template
v-for="color in staticPreference.colorPrimaryPresets"
:key="color"
>
<template v-for="color in COLOR_PRIMARY_RESETS" :key="color">
<VbenIconButton
class="flex-center flex-shrink-0"
@click="handleUpdate(color)"
@@ -35,7 +33,9 @@ function handleUpdate(value: string) {
<div
class="relative h-3.5 w-3.5 rounded-[2px] before:absolute before:left-0.5 before:top-0.5 before:h-2.5 before:w-2.5 before:rounded-[2px] before:border before:border-gray-900 before:opacity-0 before:transition-all before:duration-150 before:content-[''] hover:scale-110"
:class="[
preference.colorPrimary === color ? `before:opacity-100` : '',
preferences.theme.colorPrimary === color
? `before:opacity-100`
: '',
]"
:style="{ backgroundColor: color }"
></div>

View File

@@ -1,17 +1,15 @@
<script setup lang="ts">
import type { AuthPageLayout } from '@vben/types';
import type { VbenDropdownMenuItem } from '@vben-core/shadcn-ui';
import { MdiDockBottom, MdiDockLeft, MdiDockRight } from '@vben-core/iconify';
import { preferences, usePreferences } from '@vben-core/preferences';
import { VbenDropdownRadioMenu, VbenIconButton } from '@vben-core/shadcn-ui';
import { $t } from '@vben/locales';
import { preference, updatePreference, usePreference } from '@vben/preference';
import { computed } from 'vue';
defineOptions({
name: 'AuthenticationLayoutToggle',
// inheritAttrs: false,
});
const menus = computed((): VbenDropdownMenuItem[] => [
@@ -32,20 +30,13 @@ const menus = computed((): VbenDropdownMenuItem[] => [
},
]);
function handleUpdate(value: string) {
updatePreference({
authPageLayout: value as AuthPageLayout,
});
}
const { authPanelCenter, authPanelLeft, authPanelRight } = usePreference();
const { authPanelCenter, authPanelLeft, authPanelRight } = usePreferences();
</script>
<template>
<VbenDropdownRadioMenu
v-model="preferences.app.authPageLayout"
:menus="menus"
:model-value="preference.authPageLayout"
@update:model-value="handleUpdate"
>
<VbenIconButton>
<MdiDockRight v-if="authPanelRight" class="size-5" />

View File

@@ -4,7 +4,7 @@ export * from './global-provider';
export * from './global-search';
export * from './language-toggle';
export * from './notification';
export * from './preference';
export * from './preferences';
export * from './spinner';
export * from './theme-toggle';
export * from './user-dropdown';

View File

@@ -1,26 +1,28 @@
<script setup lang="ts">
import type { SupportLocale } from '@vben/types';
import type { LocaleSupportType } from '@vben/types';
import { IcBaselineLanguage } from '@vben-core/iconify';
import {
SUPPORT_LANGUAGES,
preferences,
updatePreferences,
} from '@vben-core/preferences';
import { VbenDropdownRadioMenu, VbenIconButton } from '@vben-core/shadcn-ui';
import { loadLocaleMessages } from '@vben/locales';
import {
preference,
staticPreference,
updatePreference,
} from '@vben/preference';
defineOptions({
name: 'LanguageToggle',
});
const menus = staticPreference.supportLanguages;
const menus = SUPPORT_LANGUAGES;
async function handleUpdate(value: string) {
const locale = value as SupportLocale;
updatePreference({
locale,
const locale = value as LocaleSupportType;
updatePreferences({
app: {
locale,
},
});
// 更改预览
await loadLocaleMessages(locale);
@@ -31,7 +33,7 @@ async function handleUpdate(value: string) {
<div>
<VbenDropdownRadioMenu
:menus="menus"
:model-value="preference.locale"
:model-value="preferences.app.locale"
@update:model-value="handleUpdate"
>
<VbenIconButton>

View File

@@ -1 +0,0 @@
export { default as PreferenceWidget } from './preference-widget.vue';

View File

@@ -1,102 +0,0 @@
<script lang="ts" setup>
import type { PreferenceKeys, SupportLocale } from '@vben/types';
import { loadLocaleMessages } from '@vben/locales';
import {
preference,
staticPreference,
updatePreference,
} from '@vben/preference';
import Preference from './preference.vue';
function handleUpdate(key: PreferenceKeys, value: boolean | string) {
updatePreference({
[key]: value,
});
}
function updateLocale(value: string) {
const locale = value as SupportLocale;
updatePreference({
locale,
});
// 更改预览
loadLocaleMessages(locale);
}
</script>
<template>
<Preference
:color-primary-presets="staticPreference.colorPrimaryPresets"
:breadcrumb-visible="preference.breadcrumbVisible"
:breadcrumb-style="preference.breadcrumbStyle"
:color-gray-mode="preference.colorGrayMode"
:breadcrumb-icon="preference.breadcrumbIcon"
:color-primary="preference.colorPrimary"
:color-weak-mode="preference.colorWeakMode"
:content-compact="preference.contentCompact"
:breadcrumb-home="preference.breadcrumbHome"
:side-collapse="preference.sideCollapse"
:layout="preference.layout"
:semi-dark-menu="preference.semiDarkMenu"
:side-visible="preference.sideVisible"
:footer-visible="preference.footerVisible"
:tabs-visible="preference.tabsVisible"
:header-visible="preference.headerVisible"
:footer-fixed="preference.footerFixed"
:header-mode="preference.headerMode"
:theme="preference.theme"
:dynamic-title="preference.dynamicTitle"
:breadcrumb-hide-only-one="preference.breadcrumbHideOnlyOne"
:page-transition="preference.pageTransition"
:page-progress="preference.pageProgress"
:tabs-icon="preference.tabsIcon"
:locale="preference.locale"
:navigation-accordion="preference.navigationAccordion"
:navigation-style="preference.navigationStyle"
:shortcut-keys="preference.shortcutKeys"
:navigation-split="preference.navigationSplit"
:side-collapse-show-title="preference.sideCollapseShowTitle"
:page-transition-enable="preference.pageTransitionEnable"
@update:shortcut-keys="(value) => handleUpdate('shortcutKeys', value)"
@update:navigation-style="(value) => handleUpdate('navigationStyle', value)"
@update:navigation-accordion="
(value) => handleUpdate('navigationAccordion', value)
"
@update:navigation-split="(value) => handleUpdate('navigationSplit', value)"
@update:dynamic-title="(value) => handleUpdate('dynamicTitle', value)"
@update:tabs-icon="(value) => handleUpdate('tabsIcon', value)"
@update:side-collapse="(value) => handleUpdate('sideCollapse', value)"
@update:locale="updateLocale"
@update:header-visible="(value) => handleUpdate('headerVisible', value)"
@update:side-visible="(value) => handleUpdate('sideVisible', value)"
@update:footer-visible="(value) => handleUpdate('footerVisible', value)"
@update:tabs-visible="(value) => handleUpdate('tabsVisible', value)"
@update:header-mode="(value) => handleUpdate('headerMode', value)"
@update:footer-fixed="(value) => handleUpdate('footerFixed', value)"
@update:breadcrumb-visible="
(value) => handleUpdate('breadcrumbVisible', value)
"
@update:breadcrumb-hide-only-one="
(value) => handleUpdate('breadcrumbHideOnlyOne', value)
"
@update:side-collapse-show-title="
(value) => handleUpdate('sideCollapseShowTitle', value)
"
@update:breadcrumb-home="(value) => handleUpdate('breadcrumbHome', value)"
@update:breadcrumb-icon="(value) => handleUpdate('breadcrumbIcon', value)"
@update:breadcrumb-style="(value) => handleUpdate('breadcrumbStyle', value)"
@update:page-transition-enable="
(value) => handleUpdate('pageTransitionEnable', value)
"
@update:color-gray-mode="(value) => handleUpdate('colorGrayMode', value)"
@update:page-transition="(value) => handleUpdate('pageTransition', value)"
@update:page-progress="(value) => handleUpdate('pageProgress', value)"
@update:color-primary="(value) => handleUpdate('colorPrimary', value)"
@update:color-weak-mode="(value) => handleUpdate('colorWeakMode', value)"
@update:content-compact="(value) => handleUpdate('contentCompact', value)"
@update:layout="(value) => handleUpdate('layout', value)"
@update:semi-dark-menu="(value) => handleUpdate('semiDarkMenu', value)"
@update:theme="(value) => handleUpdate('theme', value)"
/>
</template>

View File

@@ -1,16 +0,0 @@
import { ref } from 'vue';
const openPreference = ref(false);
function useOpenPreference() {
function handleOpenPreference() {
openPreference.value = true;
}
return {
handleOpenPreference,
openPreference,
};
}
export { useOpenPreference };

View File

@@ -1,8 +1,9 @@
<script setup lang="ts">
import type { SelectListItem } from '@vben/types';
import { SUPPORT_LANGUAGES } from '@vben-core/preferences';
import { $t } from '@vben/locales';
import { staticPreference } from '@vben/preference';
import SelectItem from '../select-item.vue';
import SwitchItem from '../switch-item.vue';
@@ -15,12 +16,10 @@ const locale = defineModel<string>('locale');
const dynamicTitle = defineModel<boolean>('dynamicTitle');
const shortcutKeys = defineModel<boolean>('shortcutKeys');
const localeItems: SelectListItem[] = staticPreference.supportLanguages.map(
(item) => ({
label: item.text,
value: item.key,
}),
);
const localeItems: SelectListItem[] = SUPPORT_LANGUAGES.map((item) => ({
label: item.text,
value: item.key,
}));
</script>
<template>

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import type { LayoutHeaderMode, SelectListItem } from '@vben/types';
import type { LayoutHeaderModeType, SelectListItem } from '@vben/types';
import { $t } from '@vben/locales';
@@ -13,7 +13,7 @@ defineOptions({
defineProps<{ disabled: boolean }>();
const headerVisible = defineModel<boolean>('headerVisible');
const headerMode = defineModel<LayoutHeaderMode>('headerMode');
const headerMode = defineModel<LayoutHeaderModeType>('headerMode');
const localeItems: SelectListItem[] = [
{

View File

@@ -0,0 +1 @@
export { default as PreferencesWidget } from './preferences-widget.vue';

View File

@@ -0,0 +1,58 @@
<script lang="ts" setup>
import type { LocaleSupportType } from '@vben/types';
import {
COLOR_PRIMARY_RESETS,
flatPreferences,
updatePreferences,
} from '@vben-core/preferences';
import { loadLocaleMessages } from '@vben/locales';
import Preferences from './preferences.vue';
function updateLocale(value: string) {
const locale = value as LocaleSupportType;
updatePreferences({
app: { locale },
});
// 更改预览
loadLocaleMessages(locale);
}
</script>
<template>
<Preferences
v-model:breadcrumb-visible="flatPreferences.breadcrumbEnable"
v-model:breadcrumb-style="flatPreferences.breadcrumbStyleType"
v-model:color-gray-mode="flatPreferences.appColorGrayMode"
v-model:breadcrumb-icon="flatPreferences.breadcrumbShowIcon"
v-model:color-primary="flatPreferences.themeColorPrimary"
v-model:color-weak-mode="flatPreferences.appColorWeakMode"
v-model:content-compact="flatPreferences.appContentCompact"
v-model:breadcrumb-home="flatPreferences.breadcrumbShowHome"
v-model:side-collapse="flatPreferences.sidebarCollapse"
v-model:layout="flatPreferences.appLayout"
v-model:semi-dark-menu="flatPreferences.appSemiDarkMenu"
v-model:side-visible="flatPreferences.sidebarEnable"
v-model:footer-visible="flatPreferences.footerEnable"
v-model:tabs-visible="flatPreferences.tabbarEnable"
v-model:header-visible="flatPreferences.headerEnable"
v-model:header-mode="flatPreferences.headerMode"
v-model:footer-fixed="flatPreferences.footerFixed"
v-model:theme="flatPreferences.appThemeMode"
v-model:dynamic-title="flatPreferences.appDynamicTitle"
v-model:breadcrumb-hide-only-one="flatPreferences.breadcrumbHideOnlyOne"
v-model:page-transition="flatPreferences.transitionName"
v-model:page-progress="flatPreferences.transitionProgress"
v-model:tabs-icon="flatPreferences.tabbarShowIcon"
v-model:navigation-accordion="flatPreferences.navigationAccordion"
v-model:navigation-style="flatPreferences.navigationStyleType"
v-model:shortcut-keys="flatPreferences.shortcutKeysEnable"
v-model:navigation-split="flatPreferences.navigationSplit"
v-model:page-transition-enable="flatPreferences.transitionEnable"
v-model:side-collapse-show-title="flatPreferences.sidebarCollapseShowTitle"
:color-primary-presets="COLOR_PRIMARY_RESETS"
:locale="flatPreferences.appLocale"
@update:locale="updateLocale"
/>
</template>

View File

@@ -1,8 +1,13 @@
<script setup lang="ts">
import type { LayoutHeaderMode, LayoutType } from '@vben/types';
import type { LayoutHeaderModeType, LayoutType } from '@vben/types';
import type { SegmentedItem } from '@vben-core/shadcn-ui';
import { IcRoundFolderCopy, IcRoundRestartAlt } from '@vben-core/iconify';
import {
preferences,
resetPreferences,
usePreferences,
} from '@vben-core/preferences';
import {
VbenButton,
VbenIconButton,
@@ -12,7 +17,6 @@ import {
} from '@vben-core/shadcn-ui';
import { $t } from '@vben/locales';
import { preference, resetPreference, usePreference } from '@vben/preference';
import { useClipboard } from '@vueuse/core';
import { computed } from 'vue';
@@ -33,7 +37,7 @@ import {
ThemeColor,
} from './blocks';
import Trigger from './trigger.vue';
import { useOpenPreference } from './use-open-preference';
import { useOpenPreferences } from './use-open-preferences';
withDefaults(defineProps<{ colorPrimaryPresets: string[] }>(), {
colorPrimaryPresets: () => [],
@@ -67,7 +71,7 @@ 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 headerMode = defineModel<LayoutHeaderModeType>('headerMode');
const footerVisible = defineModel<boolean>('footerVisible');
const footerFixed = defineModel<boolean>('footerFixed');
@@ -79,7 +83,7 @@ const {
isSideMixedNav,
isSideMode,
isSideNav,
} = usePreference();
} = usePreferences();
const { copy } = useClipboard();
const tabs = computed((): SegmentedItem[] => {
@@ -108,11 +112,11 @@ const showBreadcrumbConfig = computed(() => {
!isFullContent.value &&
!isMixedNav.value &&
!isHeaderNav.value &&
preference.headerVisible
preferences.header.enable
);
});
const { openPreference } = useOpenPreference();
const { openPreferences } = useOpenPreferences();
async function handleCopy() {
await copy(JSON.stringify(diffPreference.value, null, 2));
@@ -124,7 +128,7 @@ function handleReset() {
if (!diffPreference.value) {
return;
}
resetPreference();
resetPreferences();
toast($t('preference.reset-success'));
}
</script>
@@ -132,7 +136,7 @@ function handleReset() {
<template>
<div class="z-100 fixed right-0 top-1/3">
<VbenSheet
v-model:open="openPreference"
v-model:open="openPreferences"
:description="$t('preference.preferences-subtitle')"
:title="$t('preference.preferences')"
>

View File

@@ -0,0 +1,16 @@
import { ref } from 'vue';
const openPreferences = ref(false);
function useOpenPreferences() {
function handleOpenPreference() {
openPreferences.value = true;
}
return {
handleOpenPreference,
openPreferences,
};
}
export { useOpenPreferences };

View File

@@ -4,6 +4,11 @@ import {
IcRoundWbSunny,
MdiMoonAndStars,
} from '@vben-core/iconify';
import {
preferences,
updatePreferences,
usePreferences,
} from '@vben-core/preferences';
import {
ToggleGroup,
ToggleGroupItem,
@@ -11,7 +16,6 @@ import {
} from '@vben-core/shadcn-ui';
import { $t } from '@vben/locales';
import { preference, updatePreference, usePreference } from '@vben/preference';
import ThemeButton from './theme-button.vue';
@@ -24,10 +28,12 @@ withDefaults(defineProps<{ shouldOnHover?: boolean }>(), {
});
function handleChange(isDark: boolean) {
updatePreference({ theme: isDark ? 'dark' : 'light' });
updatePreferences({
app: { themeMode: isDark ? 'dark' : 'light' },
});
}
const { isDark } = usePreference();
const { isDark } = usePreferences();
const PRESETS = [
{
@@ -58,7 +64,7 @@ const PRESETS = [
/>
</template>
<ToggleGroup
:model-value="preference.theme"
:model-value="preferences.app.themeMode"
type="single"
variant="outline"
class="gap-2"

View File

@@ -2,6 +2,7 @@
import type { AnyFunction } from '@vben/types';
import { IcRoundLogout, IcRoundSettingsSuggest } from '@vben-core/iconify';
import { preferences } from '@vben-core/preferences';
import {
Badge,
DropdownMenu,
@@ -20,11 +21,10 @@ import { isWindowsOs } from '@vben-core/toolkit';
import type { Component } from 'vue';
import { $t } from '@vben/locales';
import { preference } from '@vben/preference';
import { useMagicKeys, whenever } from '@vueuse/core';
import { computed, ref } from 'vue';
import { useOpenPreference } from '../preference/use-open-preference';
import { useOpenPreferences } from '../preferences/use-open-preferences';
interface Props {
/**
@@ -72,12 +72,12 @@ const emit = defineEmits<{ logout: [] }>();
const openPopover = ref(false);
const openDialog = ref(false);
const { handleOpenPreference } = useOpenPreference();
const { handleOpenPreference } = useOpenPreferences();
const altView = computed(() => (isWindowsOs() ? 'Alt' : '⌥'));
const shortcutKeys = computed(() => {
return props.enableShortcutKey && preference.shortcutKeys;
return props.enableShortcutKey && preferences.shortcutKeys.enable;
});
function handleLogout() {
@@ -161,7 +161,7 @@ if (shortcutKeys.value) {
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
v-if="preference"
v-if="preferences.shortcutKeys.enable"
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
@click="handleOpenPreference"
>