mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-02-02 18:28:40 +08:00
chore: update uikit -> ui-kit
This commit is contained in:
parent
89586ef2c4
commit
d4f61c283f
@ -7,7 +7,7 @@ ls:
|
|||||||
.css: kebab-case | pointcase
|
.css: kebab-case | pointcase
|
||||||
.d.ts: kebab-case | pointcase
|
.d.ts: kebab-case | pointcase
|
||||||
# shadcn 自动生成文件为 PascalCase 格式
|
# shadcn 自动生成文件为 PascalCase 格式
|
||||||
packages/@vben-core/uikit/shadcn-ui/src/components/ui:
|
packages/@vben-core/ui-kit/shadcn-ui/src/components/ui:
|
||||||
.vue: PascalCase
|
.vue: PascalCase
|
||||||
|
|
||||||
ignore:
|
ignore:
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
- @vben-core/request@5.0.1
|
- @vben-core/request@5.0.1
|
||||||
- @vben-core/stores@5.0.1
|
- @vben-core/stores@5.0.1
|
||||||
- @vben/layouts@5.0.1
|
- @vben/layouts@5.0.1
|
||||||
- @vben/universal-ui@5.0.1
|
- @vben/widgets@5.0.1
|
||||||
- @vben/constants@5.0.1
|
- @vben/constants@5.0.1
|
||||||
- @vben/hooks@5.0.1
|
- @vben/hooks@5.0.1
|
||||||
- @vben/icons@5.0.1
|
- @vben/icons@5.0.1
|
||||||
|
@ -35,10 +35,11 @@
|
|||||||
"@vben/icons": "workspace:*",
|
"@vben/icons": "workspace:*",
|
||||||
"@vben/layouts": "workspace:*",
|
"@vben/layouts": "workspace:*",
|
||||||
"@vben/locales": "workspace:*",
|
"@vben/locales": "workspace:*",
|
||||||
|
"@vben/universal-ui": "workspace:*",
|
||||||
"@vben/styles": "workspace:*",
|
"@vben/styles": "workspace:*",
|
||||||
"@vben/types": "workspace:*",
|
"@vben/types": "workspace:*",
|
||||||
"@vben/universal-ui": "workspace:*",
|
|
||||||
"@vben/utils": "workspace:*",
|
"@vben/utils": "workspace:*",
|
||||||
|
"@vben/widgets": "workspace:*",
|
||||||
"@vueuse/core": "^10.11.0",
|
"@vueuse/core": "^10.11.0",
|
||||||
"ant-design-vue": "^4.2.3",
|
"ant-design-vue": "^4.2.3",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.11",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { GlobalProvider } from '@vben/universal-ui';
|
import { GlobalProvider } from '@vben/widgets';
|
||||||
import { preferences, usePreferences } from '@vben-core/preferences';
|
import { preferences, usePreferences } from '@vben-core/preferences';
|
||||||
|
|
||||||
import { App, ConfigProvider, theme } from 'ant-design-vue';
|
import { App, ConfigProvider, theme } from 'ant-design-vue';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { NotificationItem } from '@vben/universal-ui';
|
import type { NotificationItem } from '@vben/widgets';
|
||||||
|
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
@ -7,8 +7,8 @@ import { useRouter } from 'vue-router';
|
|||||||
import { IcRoundCreditScore, MdiDriveDocument, MdiGithub } from '@vben/icons';
|
import { IcRoundCreditScore, MdiDriveDocument, MdiGithub } from '@vben/icons';
|
||||||
import { BasicLayout } from '@vben/layouts';
|
import { BasicLayout } from '@vben/layouts';
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
import { Notification, UserDropdown } from '@vben/universal-ui';
|
|
||||||
import { openWindow } from '@vben/utils';
|
import { openWindow } from '@vben/utils';
|
||||||
|
import { Notification, UserDropdown } from '@vben/widgets';
|
||||||
import { preferences } from '@vben-core/preferences';
|
import { preferences } from '@vben-core/preferences';
|
||||||
import { useAccessStore } from '@vben-core/stores';
|
import { useAccessStore } from '@vben-core/stores';
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ function setupCommonGuard(router: Router) {
|
|||||||
// 动态修改标题
|
// 动态修改标题
|
||||||
if (preferences.app.dynamicTitle) {
|
if (preferences.app.dynamicTitle) {
|
||||||
const { title } = to.meta;
|
const { title } = to.meta;
|
||||||
|
// useTitle(`${$t(title)} - ${preferences.app.name}`);
|
||||||
useTitle(`${$t(title)} - ${preferences.app.name}`);
|
useTitle(`${$t(title)} - ${preferences.app.name}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"nuxt",
|
"nuxt",
|
||||||
"lockb",
|
"lockb",
|
||||||
"astro",
|
"astro",
|
||||||
"uikit",
|
"ui-kit",
|
||||||
"styl",
|
"styl",
|
||||||
"nocheck",
|
"nocheck",
|
||||||
"prefixs",
|
"prefixs",
|
||||||
|
@ -2,7 +2,7 @@ import type { Linter } from 'eslint';
|
|||||||
|
|
||||||
const customConfig: Linter.FlatConfig[] = [
|
const customConfig: Linter.FlatConfig[] = [
|
||||||
{
|
{
|
||||||
files: ['packages/@core/uikit/shadcn-ui/**/**'],
|
files: ['packages/@core/ui-kit/shadcn-ui/**/**'],
|
||||||
rules: {
|
rules: {
|
||||||
'vue/require-default-prop': 'off',
|
'vue/require-default-prop': 'off',
|
||||||
},
|
},
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
||||||
|
|
||||||
import { StorageManager } from './storage-manager';
|
|
||||||
|
|
||||||
describe('storageManager', () => {
|
|
||||||
let storageManager: StorageManager<{ age: number; name: string }>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
vi.useFakeTimers();
|
|
||||||
localStorage.clear();
|
|
||||||
storageManager = new StorageManager<{ age: number; name: string }>({
|
|
||||||
prefix: 'test_',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set and get an item', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' });
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toEqual({ age: 30, name: 'John Doe' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return default value if item does not exist', () => {
|
|
||||||
const user = storageManager.getItem('nonexistent', {
|
|
||||||
age: 0,
|
|
||||||
name: 'Default User',
|
|
||||||
});
|
|
||||||
expect(user).toEqual({ age: 0, name: 'Default User' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove an item', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' });
|
|
||||||
storageManager.removeItem('user');
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clear all items with the prefix', () => {
|
|
||||||
storageManager.setItem('user1', { age: 30, name: 'John Doe' });
|
|
||||||
storageManager.setItem('user2', { age: 25, name: 'Jane Doe' });
|
|
||||||
storageManager.clear();
|
|
||||||
expect(storageManager.getItem('user1')).toBeNull();
|
|
||||||
expect(storageManager.getItem('user2')).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clear expired items', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' }, 1000); // 1秒过期
|
|
||||||
vi.advanceTimersByTime(1001); // 快进时间
|
|
||||||
storageManager.clearExpiredItems();
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not clear non-expired items', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' }, 10_000); // 10秒过期
|
|
||||||
vi.advanceTimersByTime(5000); // 快进时间
|
|
||||||
storageManager.clearExpiredItems();
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toEqual({ age: 30, name: 'John Doe' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle JSON parse errors gracefully', () => {
|
|
||||||
localStorage.setItem('test_user', '{ invalid JSON }');
|
|
||||||
const user = storageManager.getItem('user', {
|
|
||||||
age: 0,
|
|
||||||
name: 'Default User',
|
|
||||||
});
|
|
||||||
expect(user).toEqual({ age: 0, name: 'Default User' });
|
|
||||||
});
|
|
||||||
it('should return null for non-existent items without default value', () => {
|
|
||||||
const user = storageManager.getItem('nonexistent');
|
|
||||||
expect(user).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should overwrite existing items', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' });
|
|
||||||
storageManager.setItem('user', { age: 25, name: 'Jane Doe' });
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toEqual({ age: 25, name: 'Jane Doe' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle items without expiry correctly', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' });
|
|
||||||
vi.advanceTimersByTime(5000);
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toEqual({ age: 30, name: 'John Doe' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove expired items when accessed', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' }, 1000); // 1秒过期
|
|
||||||
vi.advanceTimersByTime(1001); // 快进时间
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not remove non-expired items when accessed', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' }, 10_000); // 10秒过期
|
|
||||||
vi.advanceTimersByTime(5000); // 快进时间
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toEqual({ age: 30, name: 'John Doe' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle multiple items with different expiry times', () => {
|
|
||||||
storageManager.setItem('user1', { age: 30, name: 'John Doe' }, 1000); // 1秒过期
|
|
||||||
storageManager.setItem('user2', { age: 25, name: 'Jane Doe' }, 2000); // 2秒过期
|
|
||||||
vi.advanceTimersByTime(1500); // 快进时间
|
|
||||||
storageManager.clearExpiredItems();
|
|
||||||
const user1 = storageManager.getItem('user1');
|
|
||||||
const user2 = storageManager.getItem('user2');
|
|
||||||
expect(user1).toBeNull();
|
|
||||||
expect(user2).toEqual({ age: 25, name: 'Jane Doe' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle items with no expiry', () => {
|
|
||||||
storageManager.setItem('user', { age: 30, name: 'John Doe' });
|
|
||||||
vi.advanceTimersByTime(10_000); // 快进时间
|
|
||||||
storageManager.clearExpiredItems();
|
|
||||||
const user = storageManager.getItem('user');
|
|
||||||
expect(user).toEqual({ age: 30, name: 'John Doe' });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clear all items correctly', () => {
|
|
||||||
storageManager.setItem('user1', { age: 30, name: 'John Doe' });
|
|
||||||
storageManager.setItem('user2', { age: 25, name: 'Jane Doe' });
|
|
||||||
storageManager.clear();
|
|
||||||
const user1 = storageManager.getItem('user1');
|
|
||||||
const user2 = storageManager.getItem('user2');
|
|
||||||
expect(user1).toBeNull();
|
|
||||||
expect(user2).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,118 +0,0 @@
|
|||||||
type StorageType = 'localStorage' | 'sessionStorage';
|
|
||||||
|
|
||||||
interface StorageManagerOptions {
|
|
||||||
prefix?: string;
|
|
||||||
storageType?: StorageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface StorageItem<T> {
|
|
||||||
expiry?: number;
|
|
||||||
value: T;
|
|
||||||
}
|
|
||||||
|
|
||||||
class StorageManager {
|
|
||||||
private prefix: string;
|
|
||||||
private storage: Storage;
|
|
||||||
|
|
||||||
constructor({
|
|
||||||
prefix = '',
|
|
||||||
storageType = 'localStorage',
|
|
||||||
}: StorageManagerOptions = {}) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.storage =
|
|
||||||
storageType === 'localStorage'
|
|
||||||
? window.localStorage
|
|
||||||
: window.sessionStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取完整的存储键
|
|
||||||
* @param key 原始键
|
|
||||||
* @returns 带前缀的完整键
|
|
||||||
*/
|
|
||||||
private getFullKey(key: string): string {
|
|
||||||
return `${this.prefix}-${key}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除所有带前缀的存储项
|
|
||||||
*/
|
|
||||||
clear(): void {
|
|
||||||
const keysToRemove: string[] = [];
|
|
||||||
for (let i = 0; i < this.storage.length; i++) {
|
|
||||||
const key = this.storage.key(i);
|
|
||||||
if (key && key.startsWith(this.prefix)) {
|
|
||||||
keysToRemove.push(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keysToRemove.forEach((key) => this.storage.removeItem(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除所有过期的存储项
|
|
||||||
*/
|
|
||||||
clearExpiredItems(): void {
|
|
||||||
for (let i = 0; i < this.storage.length; i++) {
|
|
||||||
const key = this.storage.key(i);
|
|
||||||
if (key && key.startsWith(this.prefix)) {
|
|
||||||
const shortKey = key.replace(this.prefix, '');
|
|
||||||
this.getItem(shortKey); // 调用 getItem 方法检查并移除过期项
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取存储项
|
|
||||||
* @param key 键
|
|
||||||
* @param defaultValue 当项不存在或已过期时返回的默认值
|
|
||||||
* @returns 值,如果项已过期或解析错误则返回默认值
|
|
||||||
*/
|
|
||||||
getItem<T>(key: string, defaultValue: T | null = null): T | null {
|
|
||||||
const fullKey = this.getFullKey(key);
|
|
||||||
const itemStr = this.storage.getItem(fullKey);
|
|
||||||
if (!itemStr) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const item: StorageItem<T> = JSON.parse(itemStr);
|
|
||||||
if (item.expiry && Date.now() > item.expiry) {
|
|
||||||
this.storage.removeItem(fullKey);
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return item.value;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error parsing item with key "${fullKey}":`, error);
|
|
||||||
this.storage.removeItem(fullKey); // 如果解析失败,删除该项
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除存储项
|
|
||||||
* @param key 键
|
|
||||||
*/
|
|
||||||
removeItem(key: string): void {
|
|
||||||
const fullKey = this.getFullKey(key);
|
|
||||||
this.storage.removeItem(fullKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置存储项
|
|
||||||
* @param key 键
|
|
||||||
* @param value 值
|
|
||||||
* @param ttl 存活时间(毫秒)
|
|
||||||
*/
|
|
||||||
setItem<T>(key: string, value: T, ttl?: number): void {
|
|
||||||
const fullKey = this.getFullKey(key);
|
|
||||||
const expiry = ttl ? Date.now() + ttl : undefined;
|
|
||||||
const item: StorageItem<T> = { expiry, value };
|
|
||||||
try {
|
|
||||||
this.storage.setItem(fullKey, JSON.stringify(item));
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error setting item with key "${fullKey}":`, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { StorageManager };
|
|
@ -1,17 +0,0 @@
|
|||||||
type StorageType = 'localStorage' | 'sessionStorage';
|
|
||||||
|
|
||||||
interface StorageValue<T> {
|
|
||||||
data: T;
|
|
||||||
expiry: null | number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IStorageCache {
|
|
||||||
clear(): void;
|
|
||||||
getItem<T>(key: string): T | null;
|
|
||||||
key(index: number): null | string;
|
|
||||||
length(): number;
|
|
||||||
removeItem(key: string): void;
|
|
||||||
setItem<T>(key: string, value: T, expiryInMinutes?: number): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type { IStorageCache, StorageType, StorageValue };
|
|
@ -38,7 +38,6 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "^3.4.30",
|
"@vue/shared": "^3.4.30",
|
||||||
"clsx": "2.1.1",
|
"clsx": "2.1.1",
|
||||||
"dayjs": "^1.11.11",
|
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"tailwind-merge": "^2.3.0"
|
"tailwind-merge": "^2.3.0"
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
|
} from '@vben-core/shadcn-ui/components/ui/dropdown-menu';
|
||||||
|
|
||||||
import { VbenIcon } from '../';
|
import { VbenIcon } from '../icon';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
breadcrumbs: IBreadcrumb[];
|
breadcrumbs: IBreadcrumb[];
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user