feat: support pwa
parent
222c73963d
commit
382652e0f4
|
@ -7,6 +7,7 @@ coverage
|
||||||
**/.vitepress/cache
|
**/.vitepress/cache
|
||||||
.cache
|
.cache
|
||||||
.turbo
|
.turbo
|
||||||
|
dev-dist
|
||||||
.stylelintcache
|
.stylelintcache
|
||||||
yarn.lock
|
yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { Fallback } from '@vben/common-ui';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Fallback status="hello" />
|
||||||
|
</template>
|
|
@ -1,24 +1,47 @@
|
||||||
import { defineConfig } from '@vben/vite-config';
|
import { defineConfig } from '@vben/vite-config';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
application: {
|
application: ({ mode }) => {
|
||||||
compress: false,
|
return {
|
||||||
compressTypes: ['brotli', 'gzip'],
|
compress: false,
|
||||||
importmap: false,
|
compressTypes: ['brotli', 'gzip'],
|
||||||
importmapOptions: {
|
importmap: false,
|
||||||
// 通过 Importmap CDN 方式引入,
|
importmapOptions: {
|
||||||
// 目前只有esm.sh源兼容性好一点,jspm.io对于 esm 入口要求高
|
// 通过 Importmap CDN 方式引入,
|
||||||
defaultProvider: 'esm.sh',
|
// 目前只有esm.sh源兼容性好一点,jspm.io对于 esm 入口要求高
|
||||||
importmap: [
|
defaultProvider: 'esm.sh',
|
||||||
{ name: 'vue' },
|
importmap: [
|
||||||
{ name: 'pinia' },
|
{ name: 'vue' },
|
||||||
{ name: 'vue-router' },
|
{ name: 'pinia' },
|
||||||
{ name: 'vue-i18n' },
|
{ name: 'vue-router' },
|
||||||
{ name: 'dayjs' },
|
{ name: 'vue-i18n' },
|
||||||
{ name: 'vue-demi' },
|
{ name: 'dayjs' },
|
||||||
],
|
{ name: 'vue-demi' },
|
||||||
},
|
],
|
||||||
visualizer: false,
|
},
|
||||||
|
pwa: false,
|
||||||
|
pwaOptions: {
|
||||||
|
manifest: {
|
||||||
|
description:
|
||||||
|
'Vben Admin Pro is a modern admin dashboard template based on Vue 3. ',
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
sizes: '192x192',
|
||||||
|
src: 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.1/source/pwa-icon-192.png',
|
||||||
|
type: 'image/png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sizes: '512x512',
|
||||||
|
src: 'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.1/source/pwa-icon-512.png',
|
||||||
|
type: 'image/png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
name: `Vben Admin Pro ${mode}`,
|
||||||
|
short_name: `Vben Admin Pro ${mode}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
visualizer: false,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
vite: {
|
vite: {
|
||||||
server: {
|
server: {
|
||||||
|
|
|
@ -57,6 +57,10 @@ export default {
|
||||||
'collapsible-up': 'collapsible-up 0.2s ease-in-out',
|
'collapsible-up': 'collapsible-up 0.2s ease-in-out',
|
||||||
float: 'float 5s linear 0ms infinite',
|
float: 'float 5s linear 0ms infinite',
|
||||||
},
|
},
|
||||||
|
animationDuration: {
|
||||||
|
'2000': '2000ms',
|
||||||
|
'3000': '3000ms',
|
||||||
|
},
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
lg: 'var(--radius-base)',
|
lg: 'var(--radius-base)',
|
||||||
md: 'calc(var(--radius-base) - 2px)',
|
md: 'calc(var(--radius-base) - 2px)',
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"html-minifier-terser": "^7.2.0",
|
"html-minifier-terser": "^7.2.0",
|
||||||
"resolve.exports": "^2.0.2",
|
"resolve.exports": "^2.0.2",
|
||||||
"vite-plugin-lib-inject-css": "^2.1.1",
|
"vite-plugin-lib-inject-css": "^2.1.1",
|
||||||
|
"vite-plugin-pwa": "^0.20.0",
|
||||||
"vite-plugin-vue-devtools": "^7.2.1"
|
"vite-plugin-vue-devtools": "^7.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -10,7 +10,8 @@ import { getApplicationConditionPlugins } from '../plugins';
|
||||||
import { getCommonConfig } from './common';
|
import { getCommonConfig } from './common';
|
||||||
|
|
||||||
function defineApplicationConfig(options: DefineApplicationOptions = {}) {
|
function defineApplicationConfig(options: DefineApplicationOptions = {}) {
|
||||||
return defineConfig(async ({ command, mode }) => {
|
return defineConfig(async (config) => {
|
||||||
|
const { command, mode } = config;
|
||||||
const { application = {}, vite = {} } = options;
|
const { application = {}, vite = {} } = options;
|
||||||
const root = process.cwd();
|
const root = process.cwd();
|
||||||
const isBuild = command === 'build';
|
const isBuild = command === 'build';
|
||||||
|
@ -28,8 +29,11 @@ function defineApplicationConfig(options: DefineApplicationOptions = {}) {
|
||||||
isBuild,
|
isBuild,
|
||||||
mock: true,
|
mock: true,
|
||||||
mode,
|
mode,
|
||||||
|
pwa: true,
|
||||||
turboConsole: false,
|
turboConsole: false,
|
||||||
...application,
|
...(typeof application === 'function'
|
||||||
|
? application(config)
|
||||||
|
: application),
|
||||||
});
|
});
|
||||||
|
|
||||||
const applicationConfig: UserConfig = {
|
const applicationConfig: UserConfig = {
|
||||||
|
@ -91,7 +95,10 @@ function defineApplicationConfig(options: DefineApplicationOptions = {}) {
|
||||||
await getCommonConfig(),
|
await getCommonConfig(),
|
||||||
applicationConfig,
|
applicationConfig,
|
||||||
);
|
);
|
||||||
return mergeConfig(mergedConfig, vite);
|
return mergeConfig(
|
||||||
|
mergedConfig,
|
||||||
|
typeof vite === 'function' ? vite(config) : vite,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@ import { getLibraryConditionPlugins } from '../plugins';
|
||||||
import { getCommonConfig } from './common';
|
import { getCommonConfig } from './common';
|
||||||
|
|
||||||
function defineLibraryConfig(options: DefineLibraryOptions = {}) {
|
function defineLibraryConfig(options: DefineLibraryOptions = {}) {
|
||||||
return defineConfig(async ({ command, mode }) => {
|
return defineConfig(async (config) => {
|
||||||
|
const { command, mode } = config;
|
||||||
const root = process.cwd();
|
const root = process.cwd();
|
||||||
const { library = {}, vite = {} } = options;
|
const { library = {}, vite = {} } = options;
|
||||||
const isBuild = command === 'build';
|
const isBuild = command === 'build';
|
||||||
|
@ -20,7 +21,7 @@ function defineLibraryConfig(options: DefineLibraryOptions = {}) {
|
||||||
injectLibCss: true,
|
injectLibCss: true,
|
||||||
isBuild,
|
isBuild,
|
||||||
mode,
|
mode,
|
||||||
...library,
|
...(typeof library === 'function' ? library(config) : library),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { dependencies = {}, peerDependencies = {} } =
|
const { dependencies = {}, peerDependencies = {} } =
|
||||||
|
@ -45,7 +46,10 @@ function defineLibraryConfig(options: DefineLibraryOptions = {}) {
|
||||||
};
|
};
|
||||||
const commonConfig = await getCommonConfig();
|
const commonConfig = await getCommonConfig();
|
||||||
const mergedConfig = mergeConfig(commonConfig, packageConfig);
|
const mergedConfig = mergeConfig(commonConfig, packageConfig);
|
||||||
return mergeConfig(mergedConfig, vite);
|
return mergeConfig(
|
||||||
|
mergedConfig,
|
||||||
|
typeof vite === 'function' ? vite(config) : vite,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import viteDtsPlugin from 'vite-plugin-dts';
|
||||||
import { createHtmlPlugin as viteHtmlPlugin } from 'vite-plugin-html';
|
import { createHtmlPlugin as viteHtmlPlugin } from 'vite-plugin-html';
|
||||||
import { libInjectCss as viteLibInjectCss } from 'vite-plugin-lib-inject-css';
|
import { libInjectCss as viteLibInjectCss } from 'vite-plugin-lib-inject-css';
|
||||||
import { viteMockServe as viteMockPlugin } from 'vite-plugin-mock';
|
import { viteMockServe as viteMockPlugin } from 'vite-plugin-mock';
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
import viteVueDevTools from 'vite-plugin-vue-devtools';
|
import viteVueDevTools from 'vite-plugin-vue-devtools';
|
||||||
|
|
||||||
import { viteExtraAppConfigPlugin } from './extra-app-config';
|
import { viteExtraAppConfigPlugin } from './extra-app-config';
|
||||||
|
@ -100,6 +101,8 @@ async function getApplicationConditionPlugins(
|
||||||
importmapOptions,
|
importmapOptions,
|
||||||
injectAppLoading,
|
injectAppLoading,
|
||||||
mock,
|
mock,
|
||||||
|
pwa,
|
||||||
|
pwaOptions,
|
||||||
turboConsole,
|
turboConsole,
|
||||||
...commonOptions
|
...commonOptions
|
||||||
} = options;
|
} = options;
|
||||||
|
@ -125,7 +128,24 @@ async function getApplicationConditionPlugins(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
condition: injectAppLoading,
|
condition: injectAppLoading,
|
||||||
plugins: async () => [await viteInjectAppLoadingPlugin(isBuild, env)],
|
plugins: async () => [await viteInjectAppLoadingPlugin(!!isBuild, env)],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: pwa,
|
||||||
|
plugins: () =>
|
||||||
|
VitePWA({
|
||||||
|
injectRegister: false,
|
||||||
|
workbox: {
|
||||||
|
globPatterns: [],
|
||||||
|
},
|
||||||
|
...pwaOptions,
|
||||||
|
manifest: {
|
||||||
|
display: 'standalone',
|
||||||
|
start_url: '/',
|
||||||
|
theme_color: '#ffffff',
|
||||||
|
...pwaOptions?.manifest,
|
||||||
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
condition: isBuild && !!compress,
|
condition: isBuild && !!compress,
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { type PluginOption } from 'vite';
|
||||||
* 为多app提供loading样式,无需在每个 app -> index.html单独引入
|
* 为多app提供loading样式,无需在每个 app -> index.html单独引入
|
||||||
*/
|
*/
|
||||||
async function viteInjectAppLoadingPlugin(
|
async function viteInjectAppLoadingPlugin(
|
||||||
isBuild: string,
|
isBuild: boolean,
|
||||||
env: Record<string, any>,
|
env: Record<string, any> = {},
|
||||||
): Promise<PluginOption | undefined> {
|
): Promise<PluginOption | undefined> {
|
||||||
const loadingHtml = await getLoadingRawByHtmlTemplate();
|
const loadingHtml = await getLoadingRawByHtmlTemplate();
|
||||||
const envRaw = isBuild ? 'prod' : 'dev';
|
const envRaw = isBuild ? 'prod' : 'dev';
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import type { PluginVisualizerOptions } from 'rollup-plugin-visualizer';
|
import type { PluginVisualizerOptions } from 'rollup-plugin-visualizer';
|
||||||
import type { PluginOption, UserConfig } from 'vite';
|
import type { ConfigEnv, PluginOption, UserConfig } from 'vite';
|
||||||
import type { PluginOptions } from 'vite-plugin-dts';
|
import type { PluginOptions } from 'vite-plugin-dts';
|
||||||
|
import type { Options as PwaPluginOptions } from 'vite-plugin-pwa';
|
||||||
|
|
||||||
import viteTurboConsolePlugin from 'unplugin-turbo-console/vite';
|
import viteTurboConsolePlugin from 'unplugin-turbo-console/vite';
|
||||||
|
|
||||||
|
@ -68,6 +69,10 @@ interface ApplicationPluginOptions extends CommonPluginOptions {
|
||||||
injectAppLoading?: boolean;
|
injectAppLoading?: boolean;
|
||||||
/** mock 插件配置 */
|
/** mock 插件配置 */
|
||||||
mock?: boolean;
|
mock?: boolean;
|
||||||
|
/** 是否开启pwa */
|
||||||
|
pwa?: boolean;
|
||||||
|
/** pwa 插件配置 */
|
||||||
|
pwaOptions?: Partial<PwaPluginOptions>;
|
||||||
/** turbo-console 插件配置 */
|
/** turbo-console 插件配置 */
|
||||||
turboConsole?: Parameters<typeof viteTurboConsolePlugin>[0] | boolean;
|
turboConsole?: Parameters<typeof viteTurboConsolePlugin>[0] | boolean;
|
||||||
}
|
}
|
||||||
|
@ -85,13 +90,15 @@ interface ApplicationOptions extends ApplicationPluginOptions {}
|
||||||
interface LibraryOptions extends LibraryPluginOptions {}
|
interface LibraryOptions extends LibraryPluginOptions {}
|
||||||
|
|
||||||
interface DefineApplicationOptions {
|
interface DefineApplicationOptions {
|
||||||
application?: ApplicationOptions;
|
application?:
|
||||||
vite?: UserConfig;
|
| ((config: ConfigEnv) => ApplicationOptions)
|
||||||
|
| ApplicationOptions;
|
||||||
|
vite?: ((config: ConfigEnv) => UserConfig) | UserConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DefineLibraryOptions {
|
interface DefineLibraryOptions {
|
||||||
library?: LibraryOptions;
|
library?: ((config: ConfigEnv) => LibraryOptions) | LibraryOptions;
|
||||||
vite?: UserConfig;
|
vite?: ((config: ConfigEnv) => UserConfig) | UserConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefineConfig = {
|
type DefineConfig = {
|
||||||
|
|
|
@ -245,7 +245,11 @@ class PreferenceManager {
|
||||||
this.initialPreferences = merge({}, overrides, defaultPreferences);
|
this.initialPreferences = merge({}, overrides, defaultPreferences);
|
||||||
|
|
||||||
// 加载并合并当前存储的偏好设置
|
// 加载并合并当前存储的偏好设置
|
||||||
const mergedPreference = merge({}, this.loadCachedPreferences(), overrides);
|
const mergedPreference = merge(
|
||||||
|
{},
|
||||||
|
this.loadCachedPreferences(),
|
||||||
|
this.initialPreferences,
|
||||||
|
);
|
||||||
|
|
||||||
// 更新偏好设置
|
// 更新偏好设置
|
||||||
this.updatePreferences(mergedPreference);
|
this.updatePreferences(mergedPreference);
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
:root.dark {
|
:root.dark {
|
||||||
/* 基础背景颜色颜色 */
|
/* 基础背景颜色颜色 */
|
||||||
|
|
||||||
/* --color-background: 240 6% 18%; */
|
|
||||||
// --color-body: 220deg 13.04% 8%;
|
|
||||||
// --color-body: hsl(240deg 11% 4%);
|
|
||||||
--color-background: 220deg 13.04% 8%;
|
--color-background: 220deg 13.04% 8%;
|
||||||
|
|
||||||
/* --color-background: 219 42% 11%; */
|
|
||||||
|
|
||||||
/* 基础文本颜色 */
|
/* 基础文本颜色 */
|
||||||
--color-foreground: 220 13% 91%;
|
--color-foreground: 220 13% 91%;
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
/* https://gavin-yyc.github.io/colorconvert/ */
|
/* https://gavin-yyc.github.io/colorconvert/ */
|
||||||
:root {
|
:root {
|
||||||
/* 基础背景颜色颜色 */
|
|
||||||
|
|
||||||
/* --color-background: 210deg 25% 96.86%; */
|
|
||||||
// --color-main: 210deg 25% 96.86%;
|
|
||||||
--color-background: 0 0 100%;
|
--color-background: 0 0 100%;
|
||||||
// --color-darken-background: 220deg 13.04% 8%;
|
|
||||||
|
|
||||||
/* --color-background: 220 14% 95%; */
|
|
||||||
|
|
||||||
/* 基础文本颜色 */
|
/* 基础文本颜色 */
|
||||||
--color-foreground: 210 6% 21%;
|
--color-foreground: 210 6% 21%;
|
||||||
|
@ -85,12 +78,9 @@
|
||||||
/* menu */
|
/* menu */
|
||||||
--color-menu-dark: 225deg 12% 13%;
|
--color-menu-dark: 225deg 12% 13%;
|
||||||
--color-menu-dark-darken: 223deg 11% 10%;
|
--color-menu-dark-darken: 223deg 11% 10%;
|
||||||
// --color-menu-darken: var(--color-background);
|
|
||||||
// --color-menu-opened-dark: 225deg 12.12% 11%;
|
|
||||||
--color-menu: 0deg 0% 100%;
|
--color-menu: 0deg 0% 100%;
|
||||||
--color-menu-darken: 0deg 0% 95%;
|
--color-menu-darken: 0deg 0% 95%;
|
||||||
|
|
||||||
accent-color: var(--color-primary);
|
accent-color: var(--color-primary);
|
||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
// --color-menu-opened: 0deg 0% 100%;
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import './default/index.scss';
|
import './default/index.css';
|
||||||
import './dark/index.scss';
|
import './dark/index.css';
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|
|
@ -296,43 +296,3 @@ function handleMouseleave() {
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
// @include b('sidebar') {
|
|
||||||
// --color-surface: var(--color-menu);
|
|
||||||
|
|
||||||
// @include is('dark') {
|
|
||||||
// --color-surface: var(--color-menu-dark);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @include e('shadow') {
|
|
||||||
// position: absolute;
|
|
||||||
// top: 0;
|
|
||||||
// z-index: 1;
|
|
||||||
// inline-size: 100%;
|
|
||||||
// block-size: 40px;
|
|
||||||
// height: 50px;
|
|
||||||
// pointer-events: none;
|
|
||||||
// background: linear-gradient(
|
|
||||||
// to bottom,
|
|
||||||
// hsl(var(--color-surface)),
|
|
||||||
// transparent
|
|
||||||
// );
|
|
||||||
// opacity: 0;
|
|
||||||
// transition: opacity 0.15s ease-in-out;
|
|
||||||
// will-change: opacity;
|
|
||||||
|
|
||||||
// &.scrolled {
|
|
||||||
// opacity: 1;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @include is('dark') {
|
|
||||||
// .#{$namespace}-side__extra {
|
|
||||||
// &-content {
|
|
||||||
// border-color: hsl(var(--color-dark-border)) !important;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ function handlerSubmit() {
|
||||||
<SheetContent :style="contentStyle" class="!w-full pb-12 sm:rounded-l-lg">
|
<SheetContent :style="contentStyle" class="!w-full pb-12 sm:rounded-l-lg">
|
||||||
<SheetHeader
|
<SheetHeader
|
||||||
:class="description ? 'h-16' : 'h-12'"
|
:class="description ? 'h-16' : 'h-12'"
|
||||||
class="border-border flex flex-row items-center justify-between border-b pl-5 pr-3"
|
class="border-border flex flex-row items-center justify-between border-b pl-3 pr-3"
|
||||||
>
|
>
|
||||||
<div class="flex w-full items-center justify-between">
|
<div class="flex w-full items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -49,6 +49,9 @@ const titleText = computed(() => {
|
||||||
case 'offline': {
|
case 'offline': {
|
||||||
return $t('fallback.offline-error');
|
return $t('fallback.offline-error');
|
||||||
}
|
}
|
||||||
|
case 'hello': {
|
||||||
|
return $t('fallback.coming-soon');
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,10 @@ const { copy } = useClipboard();
|
||||||
|
|
||||||
const tabs = computed((): SegmentedItem[] => {
|
const tabs = computed((): SegmentedItem[] => {
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
label: $t('preferences.general'),
|
||||||
|
value: 'general',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: $t('preferences.appearance'),
|
label: $t('preferences.appearance'),
|
||||||
value: 'appearance',
|
value: 'appearance',
|
||||||
|
@ -133,10 +137,7 @@ const tabs = computed((): SegmentedItem[] => {
|
||||||
label: $t('preferences.layout'),
|
label: $t('preferences.layout'),
|
||||||
value: 'layout',
|
value: 'layout',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: $t('preferences.general'),
|
|
||||||
value: 'general',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: $t('preferences.shortcut-keys.title'),
|
label: $t('preferences.shortcut-keys.title'),
|
||||||
value: 'shortcutKey',
|
value: 'shortcutKey',
|
||||||
|
@ -171,7 +172,7 @@ function handleReset() {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="z-100 fixed right-0 top-1/3">
|
<div class="z-100 fixed right-0 top-2/3">
|
||||||
<VbenSheet
|
<VbenSheet
|
||||||
v-model:open="openPreferences"
|
v-model:open="openPreferences"
|
||||||
:description="$t('preferences.preferences-subtitle')"
|
:description="$t('preferences.preferences-subtitle')"
|
||||||
|
@ -194,8 +195,8 @@ function handleReset() {
|
||||||
</VbenIconButton>
|
</VbenIconButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="p-5 pt-4">
|
<div class="p-4 pt-4">
|
||||||
<VbenSegmented :tabs="tabs" default-value="appearance">
|
<VbenSegmented :tabs="tabs" default-value="general">
|
||||||
<template #appearance>
|
<template #appearance>
|
||||||
<Block :title="$t('preferences.theme')">
|
<Block :title="$t('preferences.theme')">
|
||||||
<Theme
|
<Theme
|
||||||
|
|
|
@ -12,8 +12,8 @@ defineOptions({
|
||||||
<template>
|
<template>
|
||||||
<VbenButton
|
<VbenButton
|
||||||
:title="$t('preferences.preferences')"
|
:title="$t('preferences.preferences')"
|
||||||
class="bg-primary flex-col-center h-9 w-9 cursor-pointer rounded-l-md rounded-r-none border-none"
|
class="bg-primary flex-col-center h-12 w-12 cursor-pointer rounded-l-lg rounded-r-none border-none"
|
||||||
>
|
>
|
||||||
<IconSetting class="text-lg" />
|
<IconSetting class="duration-3000 animate-spin text-2xl" />
|
||||||
</VbenButton>
|
</VbenButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -67,7 +67,6 @@ function showSpinning(index: number) {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<template v-if="showIframe">
|
<template v-if="showIframe">
|
||||||
{{ iframeRoutes.length }}
|
|
||||||
<template v-for="(item, index) in iframeRoutes" :key="item.fullPath">
|
<template v-for="(item, index) in iframeRoutes" :key="item.fullPath">
|
||||||
<div
|
<div
|
||||||
v-if="canRender(item)"
|
v-if="canRender(item)"
|
||||||
|
|
|
@ -7,5 +7,5 @@ const VBEN_GITHUB_URL = 'https://github.com/vbenjs/vue-vben-admin';
|
||||||
* @zh_CN Vben Logo
|
* @zh_CN Vben Logo
|
||||||
*/
|
*/
|
||||||
const VBEN_LOGO =
|
const VBEN_LOGO =
|
||||||
'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.0/source/logo-v1.webp';
|
'https://cdn.jsdelivr.net/npm/@vbenjs/static-source@0.1.1/source/logo-v1.webp';
|
||||||
export { VBEN_GITHUB_URL, VBEN_LOGO };
|
export { VBEN_GITHUB_URL, VBEN_LOGO };
|
||||||
|
|
|
@ -25,6 +25,7 @@ fallback:
|
||||||
offline: Offline Page
|
offline: Offline Page
|
||||||
offline-error: Oops! Network Error
|
offline-error: Oops! Network Error
|
||||||
offline-error-desc: Sorry, can't connect to the internet. Check your connection.
|
offline-error-desc: Sorry, can't connect to the internet. Check your connection.
|
||||||
|
coming-soon: Coming soon
|
||||||
|
|
||||||
widgets:
|
widgets:
|
||||||
document: Document
|
document: Document
|
||||||
|
|
|
@ -24,6 +24,7 @@ fallback:
|
||||||
offline: 离线页面
|
offline: 离线页面
|
||||||
offline-error: 哎呀!网络错误
|
offline-error: 哎呀!网络错误
|
||||||
offline-error-desc: 抱歉,无法连接到互联网,请检查您的网络连接并重试。
|
offline-error-desc: 抱歉,无法连接到互联网,请检查您的网络连接并重试。
|
||||||
|
coming-soon: 即将推出
|
||||||
|
|
||||||
widgets:
|
widgets:
|
||||||
document: 文档
|
document: 文档
|
||||||
|
|
1683
pnpm-lock.yaml
1683
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue