feat: add docker shell
This commit is contained in:
3
packages/@vben-core/README.md
Normal file
3
packages/@vben-core/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# @vben-core
|
||||
|
||||
系统一些比较基础的SDK和UI组件库,请勿将任何业务逻辑和业务包放在这里。
|
@@ -91,6 +91,8 @@ interface Preference {
|
||||
pageTransitionEnable: boolean;
|
||||
/** 是否开启半深色菜单(只在theme='light'时生效) */
|
||||
semiDarkMenu: boolean;
|
||||
/** 是否显示偏好设置 */
|
||||
showPreference: boolean;
|
||||
/** 侧边栏是否折叠 */
|
||||
sideCollapse: boolean;
|
||||
/** 侧边栏折叠时,是否显示title */
|
||||
|
@@ -80,6 +80,33 @@ type MaybeReadonlyRef<T> = (() => T) | ComputedRef<T>;
|
||||
*/
|
||||
type MaybeComputedRef<T> = MaybeReadonlyRef<T> | MaybeRef<T>;
|
||||
|
||||
type Merge<O extends object, T extends object> = {
|
||||
[K in keyof O | keyof T]: K extends keyof T
|
||||
? T[K]
|
||||
: K extends keyof O
|
||||
? O[K]
|
||||
: never;
|
||||
};
|
||||
|
||||
/**
|
||||
* T = [
|
||||
* { name: string; age: number; },
|
||||
* { sex: 'male' | 'female'; age: string }
|
||||
* ]
|
||||
* =>
|
||||
* MergeAll<T> = {
|
||||
* name: string;
|
||||
* sex: 'male' | 'female';
|
||||
* age: string
|
||||
* }
|
||||
*/
|
||||
type MergeAll<
|
||||
T extends object[],
|
||||
R extends object = Record<string, any>,
|
||||
> = T extends [infer F extends object, ...infer Rest extends object[]]
|
||||
? MergeAll<Rest, Merge<R, F>>
|
||||
: R;
|
||||
|
||||
export {
|
||||
type AnyFunction,
|
||||
type AnyNormalFunction,
|
||||
@@ -89,6 +116,8 @@ export {
|
||||
type IntervalHandle,
|
||||
type MaybeComputedRef,
|
||||
type MaybeReadonlyRef,
|
||||
type Merge,
|
||||
type MergeAll,
|
||||
type NonNullable,
|
||||
type Nullable,
|
||||
type ReadonlyRecordable,
|
||||
|
@@ -22,6 +22,6 @@ const delegatedProps = computed(() => {
|
||||
<template>
|
||||
<DropdownMenuSeparator
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('bg-muted -mx-1 my-1 h-px', props.class)"
|
||||
:class="cn('bg-border -mx-1 my-1 h-px', props.class)"
|
||||
/>
|
||||
</template>
|
||||
|
@@ -14,7 +14,7 @@ import {
|
||||
import { $t } from '@vben/locales';
|
||||
import { preference, resetPreference, usePreference } from '@vben/preference';
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
import {
|
||||
Animation,
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
ThemeColor,
|
||||
} from './blocks';
|
||||
import Trigger from './trigger.vue';
|
||||
import { useOpenPreference } from './use-open-preference';
|
||||
|
||||
withDefaults(defineProps<{ colorPrimaryPresets: string[] }>(), {
|
||||
colorPrimaryPresets: () => [],
|
||||
@@ -106,11 +107,7 @@ const showBreadcrumbConfig = computed(() => {
|
||||
);
|
||||
});
|
||||
|
||||
const openSheet = ref(false);
|
||||
|
||||
function handlerOpenSheet() {
|
||||
openSheet.value = true;
|
||||
}
|
||||
const { openPreference } = useOpenPreference();
|
||||
|
||||
async function handleCopy() {
|
||||
await copy(JSON.stringify(diffPreference.value, null, 2));
|
||||
@@ -130,11 +127,12 @@ function handleReset() {
|
||||
<template>
|
||||
<div class="z-100 fixed right-0 top-1/3">
|
||||
<VbenSheet
|
||||
v-model:open="openPreference"
|
||||
:description="$t('preference.preferences-subtitle')"
|
||||
:title="$t('preference.preferences')"
|
||||
>
|
||||
<template #trigger>
|
||||
<Trigger @click="handlerOpenSheet" />
|
||||
<Trigger />
|
||||
</template>
|
||||
<template #extra>
|
||||
<VbenIconButton
|
||||
|
@@ -0,0 +1,16 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
const openPreference = ref(false);
|
||||
|
||||
function useOpenPreference() {
|
||||
function handleOpenPreference() {
|
||||
openPreference.value = true;
|
||||
}
|
||||
|
||||
return {
|
||||
handleOpenPreference,
|
||||
openPreference,
|
||||
};
|
||||
}
|
||||
|
||||
export { useOpenPreference };
|
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { IcRoundLogout } from '@vben-core/iconify';
|
||||
import type { AnyFunction } from '@vben/types';
|
||||
|
||||
import { IcRoundLogout, IcRoundSettingsSuggest } from '@vben-core/iconify';
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
@@ -16,9 +18,11 @@ import {
|
||||
import type { Component } from 'vue';
|
||||
|
||||
import { $t } from '@vben/locales';
|
||||
import { AnyFunction } from '@vben/types';
|
||||
import { preference } from '@vben/preference';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useOpenPreference } from '../preference/use-open-preference';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* 头像
|
||||
@@ -59,6 +63,8 @@ const emit = defineEmits<{ logout: [] }>();
|
||||
const openPopover = ref(false);
|
||||
const openDialog = ref(false);
|
||||
|
||||
const { handleOpenPreference } = useOpenPreference();
|
||||
|
||||
function handleLogout() {
|
||||
// emit
|
||||
openDialog.value = true;
|
||||
@@ -90,8 +96,8 @@ function handleSubmitLogout() {
|
||||
</div>
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent class="mr-2 min-w-[240px] p-0">
|
||||
<DropdownMenuLabel class="border-border flex items-center border-b p-3">
|
||||
<DropdownMenuContent class="mr-2 min-w-[240px] p-0 pb-1">
|
||||
<DropdownMenuLabel class="flex items-center p-3">
|
||||
<VbenAvatar
|
||||
:alt="text"
|
||||
:src="avatar"
|
||||
@@ -117,22 +123,28 @@ function handleSubmitLogout() {
|
||||
<DropdownMenuItem
|
||||
v-for="menu in menus"
|
||||
:key="menu.text"
|
||||
class="mx-1 rounded-sm py-2.5"
|
||||
class="lineh mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
|
||||
@click="menu.handler"
|
||||
>
|
||||
<VbenIcon :icon="menu.icon" class="mr-2 size-4" />
|
||||
<VbenIcon :icon="menu.icon" class="mr-2 size-5" />
|
||||
{{ menu.text }}
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem class="w-full p-0">
|
||||
<div
|
||||
class="border-border flex-center hover:bg-accent hover:text-accent-foreground h-10 w-full cursor-pointer border-t"
|
||||
@click="handleLogout"
|
||||
>
|
||||
<IcRoundLogout class="mr-2" />
|
||||
{{ $t('common.logout') }}
|
||||
</div>
|
||||
<DropdownMenuItem
|
||||
v-if="preference"
|
||||
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
|
||||
@click="handleOpenPreference"
|
||||
>
|
||||
<IcRoundSettingsSuggest class="mr-2 size-5" />
|
||||
{{ $t('preference.preferences') }}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
|
||||
@click="handleLogout"
|
||||
>
|
||||
<IcRoundLogout class="mr-2 size-5" />
|
||||
{{ $t('common.logout') }}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
@@ -127,7 +127,7 @@ function wrapperMenus(menus: MenuRecordRaw[]) {
|
||||
(value: boolean) => updatePreference('sideExpandOnHover', value)
|
||||
"
|
||||
>
|
||||
<template #preference>
|
||||
<template v-if="preference.showPreference" #preference>
|
||||
<PreferenceWidget />
|
||||
</template>
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import type { Preference } from '@vben-core/typings';
|
||||
|
||||
class PreferenceCache {
|
||||
cachePrefix: string;
|
||||
constructor(cachePrefix: string = 'vben-admin') {
|
||||
constructor(cachePrefix: string) {
|
||||
this.cachePrefix = cachePrefix;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,7 @@ class PreferenceCache {
|
||||
* 获取偏好设置的缓存键
|
||||
*/
|
||||
getCacheKey(name: string = 'preference') {
|
||||
const env = import.meta.env.DEV ? 'dev' : 'prod';
|
||||
return `__${this.cachePrefix}-${name}-${env}__`;
|
||||
return `__${this.cachePrefix}-${name}__`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -34,8 +34,9 @@ const defaultPreference: Preference = {
|
||||
pageTransition: 'fade-slide',
|
||||
pageTransitionEnable: true,
|
||||
semiDarkMenu: true,
|
||||
showPreference: true,
|
||||
sideCollapse: false,
|
||||
sideCollapseShowTitle: false,
|
||||
sideCollapseShowTitle: true,
|
||||
sideExpandOnHover: true,
|
||||
sideExtraCollapse: true,
|
||||
sideVisible: true,
|
||||
|
@@ -4,22 +4,24 @@ import { PreferenceCache } from './cache';
|
||||
import { overridesPreference } from './preference';
|
||||
|
||||
interface SetupPreferenceOptions {
|
||||
/**
|
||||
* @zh_CN 环境
|
||||
*/
|
||||
env: string;
|
||||
/**
|
||||
* @zh_CN 应用名,由于 @vben/preference 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名
|
||||
* 应用名将被用于持久化的前缀
|
||||
*/
|
||||
cachePrefix?: string;
|
||||
namespace: string;
|
||||
/**
|
||||
* @zh_CN app自行覆盖偏好设置
|
||||
*/
|
||||
overrides?: DeepPartial<Preference>;
|
||||
}
|
||||
|
||||
async function setupPreference(options: SetupPreferenceOptions = {}) {
|
||||
const { cachePrefix = 'vben-admin-pro', overrides = {} } = options;
|
||||
|
||||
const cache = new PreferenceCache(cachePrefix);
|
||||
|
||||
async function setupPreference(options: SetupPreferenceOptions) {
|
||||
const { env, namespace, overrides = {} } = options;
|
||||
const cache = new PreferenceCache(`${namespace}-${env}`);
|
||||
overridesPreference(overrides, cache);
|
||||
}
|
||||
|
||||
|
@@ -3,26 +3,29 @@ import type { App } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
interface SetupStoreOptions {
|
||||
/**
|
||||
* @zh_CN 环境
|
||||
*/
|
||||
env: string;
|
||||
/**
|
||||
* @zh_CN 应用名,由于 @vben/stores 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名
|
||||
* 应用名将被用于持久化的前缀
|
||||
*/
|
||||
cachePrefix?: string;
|
||||
namespace: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh_CN 初始化pinia
|
||||
* @param app vue app 实例
|
||||
*/
|
||||
async function setupStore(app: App, options: SetupStoreOptions = {}) {
|
||||
async function setupStore(app: App, options: SetupStoreOptions) {
|
||||
const { createPersistedState } = await import('pinia-plugin-persistedstate');
|
||||
const pinia = createPinia();
|
||||
const { cachePrefix = 'vben-admin-pro' } = options;
|
||||
const env = import.meta.env.DEV ? 'dev' : 'prod';
|
||||
const { env, namespace } = options;
|
||||
pinia.use(
|
||||
createPersistedState({
|
||||
// key $appName-$store.id
|
||||
key: (storeKey) => `__${cachePrefix}-${storeKey}-${env}__`,
|
||||
key: (storeKey) => `__${namespace}-${env}-${storeKey}__`,
|
||||
storage: localStorage,
|
||||
}),
|
||||
);
|
||||
|
@@ -19,9 +19,6 @@
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"sideEffects": [
|
||||
"**/*.css"
|
||||
],
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"imports": {
|
||||
@@ -42,6 +39,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vben-core/design": "workspace:*",
|
||||
"@vben-core/design-tokens": "workspace:*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vben-core/design": "workspace:*",
|
||||
"@vben-core/design-tokens": "workspace:*"
|
||||
|
Reference in New Issue
Block a user