mirror of
https://github.com/certd/certd.git
synced 2026-05-16 13:17:29 +08:00
Merge branch 'v2-translation' into v2-dev
# Conflicts: # packages/ui/certd-client/src/components/plugins/common/remote-select.vue # packages/ui/certd-client/src/router/source/modules/certd.ts # packages/ui/certd-client/src/views/certd/pipeline/certd-form/use.tsx # packages/ui/certd-client/src/views/certd/pipeline/crud.tsx
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
import type { CaptchaPoint, PointSelectionCaptchaProps } from '../types';
|
||||
|
||||
import { RotateCw } from '/@/vben/icons';
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { VbenButton, VbenIconButton } from '/@/vben/shadcn-ui';
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { PointSelectionCaptchaCardProps } from '../types';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import {
|
||||
Card,
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import type {
|
||||
|
||||
import { reactive, unref, useTemplateRef, watch, watchEffect } from 'vue';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { cn } from '/@/vben/shared/utils';
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import type {
|
||||
|
||||
import { computed, reactive, unref, useTemplateRef, watch } from 'vue';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { useTimeoutFn } from '@vueuse/core';
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { computed, ref, watch, watchEffect } from 'vue';
|
||||
|
||||
import { usePagination } from '/@/vben/hooks';
|
||||
import { EmptyIcon, Grip, listIcons } from '/@/vben/icons';
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import {
|
||||
Button,
|
||||
|
||||
@@ -14,7 +14,7 @@ import { computed, useAttrs } from 'vue';
|
||||
// @ts-ignore
|
||||
import VueJsonViewer from 'vue-json-viewer';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { isBoolean } from '/@/vben/shared/utils';
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { VbenFormSchema } from '/@/vben/form-ui';
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { useVbenForm } from '/@/vben/form-ui';
|
||||
import { VbenButton } from '/@/vben/shadcn-ui';
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { VbenFormSchema } from '/@/vben/form-ui';
|
||||
import type { VbenFormSchema } from "/@/vben/form-ui";
|
||||
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { computed, reactive } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import { useVbenForm } from '/@/vben/form-ui';
|
||||
import { VbenButton } from '/@/vben/shadcn-ui';
|
||||
import { useVbenForm } from "/@/vben/form-ui";
|
||||
import { VbenButton } from "/@/vben/shadcn-ui";
|
||||
|
||||
import Title from './auth-title.vue';
|
||||
import Title from "./auth-title.vue";
|
||||
|
||||
interface Props {
|
||||
formSchema: VbenFormSchema[];
|
||||
@@ -36,15 +36,15 @@ interface Props {
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'ForgetPassword',
|
||||
name: "ForgetPassword",
|
||||
});
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
loading: false,
|
||||
loginPath: '/auth/login',
|
||||
submitButtonText: '',
|
||||
subTitle: '',
|
||||
title: '',
|
||||
loginPath: "/auth/login",
|
||||
submitButtonText: "",
|
||||
subTitle: "",
|
||||
title: "",
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -59,7 +59,7 @@ const [Form, formApi] = useVbenForm(
|
||||
},
|
||||
schema: computed(() => props.formSchema),
|
||||
showDefaultActions: false,
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
const router = useRouter();
|
||||
@@ -68,7 +68,7 @@ async function handleSubmit() {
|
||||
const { valid } = await formApi.validate();
|
||||
const values = await formApi.getValues();
|
||||
if (valid) {
|
||||
emit('submit', values);
|
||||
emit("submit", values);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,12 +84,10 @@ defineExpose({
|
||||
<template>
|
||||
<div>
|
||||
<Title>
|
||||
<slot name="title">
|
||||
{{ title || $t('authentication.forgetPassword') }} 🤦🏻♂️
|
||||
</slot>
|
||||
<slot name="title"> {{ title || $t("authentication.forgetPassword") }} 🤦🏻♂️ </slot>
|
||||
<template #desc>
|
||||
<slot name="subTitle">
|
||||
{{ subTitle || $t('authentication.forgetPasswordSubtitle') }}
|
||||
{{ subTitle || $t("authentication.forgetPasswordSubtitle") }}
|
||||
</slot>
|
||||
</template>
|
||||
</Title>
|
||||
@@ -105,11 +103,11 @@ defineExpose({
|
||||
@click="handleSubmit"
|
||||
>
|
||||
<slot name="submitButtonText">
|
||||
{{ submitButtonText || $t('authentication.sendResetLink') }}
|
||||
{{ submitButtonText || $t("authentication.sendResetLink") }}
|
||||
</slot>
|
||||
</VbenButton>
|
||||
<VbenButton class="mt-4 w-full" variant="outline" @click="goToLogin()">
|
||||
{{ $t('common.back') }}
|
||||
{{ $t("common.back") }}
|
||||
</VbenButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { AuthenticationProps } from './types';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { useVbenForm } from '/@/vben/form-ui';
|
||||
import { VbenButton, VbenCheckbox } from '/@/vben/shadcn-ui';
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { VbenFormSchema } from '/@/vben/form-ui';
|
||||
import { computed, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { useVbenForm } from '/@/vben/form-ui';
|
||||
import { VbenButton } from '/@/vben/shadcn-ui';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { MdiGithub, MdiGoogle, MdiQqchat, MdiWechat } from '/@/vben/icons';
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { VbenIconButton } from '/@/vben/shadcn-ui';
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { computed, defineAsyncComponent } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { ArrowLeft, RotateCw } from '/@/vben/icons';
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { VbenButton } from '/@/vben/shadcn-ui';
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import "./styles";
|
||||
import "./styles/antd/index.css";
|
||||
|
||||
import { useTitle } from "@vueuse/core";
|
||||
import { setupI18n } from "/@/vben/locales";
|
||||
import { setupI18n } from "../locales";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
|
||||
export async function setupVben(app: any, { loadMessages, router }: any) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { MenuRecordRaw } from "../../types";
|
||||
import { computed, useSlots, watch } from "vue";
|
||||
|
||||
import { useRefresh } from "../../hooks";
|
||||
import { $t, i18n } from "../../locales";
|
||||
import { $t, i18n } from "/@/locales";
|
||||
import { preferences, updatePreferences, usePreferences } from "../../preferences";
|
||||
import { useLockStore } from "../../stores";
|
||||
import { cloneDeep, mapTree } from "../../utils";
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
import { useContentMaximize, useTabs } from "../../../hooks";
|
||||
import { ArrowLeftToLine, ArrowRightLeft, ArrowRightToLine, ExternalLink, FoldHorizontal, Fullscreen, Minimize2, Pin, PinOff, RotateCw, X } from "../../../icons";
|
||||
import { $t, useI18n } from "../../../locales";
|
||||
import { $t, useI18n } from "/@/locales";
|
||||
import { useAccessStore, useTabbarStore } from "../../../stores";
|
||||
import { filterTree } from "../../../utils";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { IBreadcrumb } from "/@/vben//shadcn-ui";
|
||||
import { computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import { VbenBreadcrumbView } from "/@/vben//shadcn-ui";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from "vue";
|
||||
|
||||
import { $t } from "../../../locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import { useVbenModal } from "../../../popup-ui";
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { MenuRecordRaw } from "../../../types";
|
||||
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
|
||||
|
||||
import { ArrowDown, ArrowUp, CornerDownLeft, MdiKeyboardEsc, Search } from "../../../icons";
|
||||
import { $t } from "../../../locales";
|
||||
import { $t } from "/@/locales";
|
||||
import { isWindowsOs } from "../../../utils";
|
||||
|
||||
import { useVbenModal } from "../../../popup-ui";
|
||||
|
||||
@@ -5,7 +5,7 @@ import { nextTick, onMounted, ref, shallowRef, watch } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
import { SearchX, X } from "../../../icons";
|
||||
import { $t } from "../../../locales";
|
||||
import { $t } from "/@/locales";
|
||||
import { mapTree, traverseTreeValues, uniqueByField } from "../../../utils";
|
||||
|
||||
import { VbenIcon, VbenScrollbar } from "../../../shadcn-ui";
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export { default as Breadcrumb } from './breadcrumb.vue';
|
||||
export * from './check-updates';
|
||||
export { default as AuthenticationColorToggle } from './color-toggle.vue';
|
||||
export * from './global-search';
|
||||
export { default as LanguageToggle } from './language-toggle.vue';
|
||||
export { default as AuthenticationLayoutToggle } from './layout-toggle.vue';
|
||||
export * from './lock-screen';
|
||||
export * from './notification';
|
||||
export * from './preferences';
|
||||
export * from './theme-toggle';
|
||||
export * from './user-dropdown';
|
||||
export { default as Breadcrumb } from "./breadcrumb.vue";
|
||||
export * from "./check-updates";
|
||||
export { default as AuthenticationColorToggle } from "./color-toggle.vue";
|
||||
export * from "./global-search";
|
||||
export { default as LanguageToggle } from "./language-toggle.vue";
|
||||
export { default as AuthenticationLayoutToggle } from "./layout-toggle.vue";
|
||||
export * from "./lock-screen";
|
||||
export * from "./notification";
|
||||
export * from "./preferences";
|
||||
export * from "./theme-toggle";
|
||||
export * from "./user-dropdown";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import type { SupportedLanguagesType } from "/@/vben/locales";
|
||||
import type { SupportedLanguagesType } from "/@/locales";
|
||||
|
||||
import { SUPPORT_LANGUAGES } from "/@/vben/constants";
|
||||
import { Languages } from "/@/vben/icons";
|
||||
import { loadLocaleMessages } from "/@/vben/locales";
|
||||
import { loadLocaleMessages } from "/@/locales";
|
||||
import { preferences, updatePreferences } from "/@/vben/preferences";
|
||||
|
||||
import { VbenDropdownRadioMenu, VbenIconButton } from "/@/vben//shadcn-ui";
|
||||
|
||||
@@ -6,31 +6,31 @@ import type { VbenDropdownMenuItem } from "/@/vben//shadcn-ui";
|
||||
import { computed } from "vue";
|
||||
|
||||
import { InspectionPanel, PanelLeft, PanelRight } from "/@/vben/icons";
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
import { preferences, updatePreferences, usePreferences } from "/@/vben/preferences";
|
||||
|
||||
import { VbenDropdownRadioMenu, VbenIconButton } from "/@/vben//shadcn-ui";
|
||||
|
||||
defineOptions({
|
||||
name: "AuthenticationLayoutToggle"
|
||||
name: "AuthenticationLayoutToggle",
|
||||
});
|
||||
|
||||
const menus = computed((): VbenDropdownMenuItem[] => [
|
||||
{
|
||||
icon: PanelLeft,
|
||||
label: $t("authentication.layout.alignLeft"),
|
||||
value: "panel-left"
|
||||
value: "panel-left",
|
||||
},
|
||||
{
|
||||
icon: InspectionPanel,
|
||||
label: $t("authentication.layout.center"),
|
||||
value: "panel-center"
|
||||
value: "panel-center",
|
||||
},
|
||||
{
|
||||
icon: PanelRight,
|
||||
label: $t("authentication.layout.alignRight"),
|
||||
value: "panel-right"
|
||||
}
|
||||
value: "panel-right",
|
||||
},
|
||||
]);
|
||||
|
||||
const { authPanelCenter, authPanelLeft, authPanelRight } = usePreferences();
|
||||
@@ -38,8 +38,8 @@ const { authPanelCenter, authPanelLeft, authPanelRight } = usePreferences();
|
||||
function handleUpdate(value: string) {
|
||||
updatePreferences({
|
||||
app: {
|
||||
authPageLayout: value as AuthPageLayoutType
|
||||
}
|
||||
authPageLayout: value as AuthPageLayoutType,
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Recordable } from "../../../types";
|
||||
|
||||
import { computed, reactive } from "vue";
|
||||
|
||||
import { $t } from "../../../locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import { useVbenForm, z } from "../../../form-ui";
|
||||
import { useVbenModal } from "../../../popup-ui";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { computed, reactive, ref } from "vue";
|
||||
|
||||
import { LockKeyhole } from "../../../icons";
|
||||
import { $t, useI18n } from "../../../locales";
|
||||
import { $t, useI18n } from "/@/locales";
|
||||
import { storeToRefs, useLockStore } from "../../../stores";
|
||||
|
||||
import { useScrollLock } from "../../../composables";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import type { NotificationItem } from "./types";
|
||||
|
||||
import { Bell, MailCheck } from "/@/vben/icons";
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import { VbenButton, VbenIconButton, VbenPopover, VbenScrollbar } from "/@/vben//shadcn-ui";
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import SwitchItem from "../switch-item.vue";
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { SUPPORT_LANGUAGES } from "/@/vben/constants";
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import SelectItem from "../select-item.vue";
|
||||
import SwitchItem from "../switch-item.vue";
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { SelectOption } from "/@/vben/types";
|
||||
|
||||
import { computed } from "vue";
|
||||
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import SwitchItem from "../switch-item.vue";
|
||||
import ToggleItem from "../toggle-item.vue";
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { Component } from "vue";
|
||||
|
||||
import { computed } from "vue";
|
||||
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import { ContentCompact, ContentWide } from "../../icons";
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import InputItem from "../input-item.vue";
|
||||
import SwitchItem from "../switch-item.vue";
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import SwitchItem from "../switch-item.vue";
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import type {
|
||||
SelectOption,
|
||||
} from '/@/vben/types';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import SelectItem from '../select-item.vue';
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
|
||||
+73
-78
@@ -6,107 +6,102 @@ import type { LayoutType } from '/@/vben/types';
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { CircleHelp } from '/@/vben/icons';
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import { VbenTooltip } from '/@/vben//shadcn-ui';
|
||||
|
||||
import {
|
||||
FullContent,
|
||||
HeaderMixedNav,
|
||||
HeaderNav,
|
||||
HeaderSidebarNav,
|
||||
MixedNav,
|
||||
SidebarMixedNav,
|
||||
SidebarNav,
|
||||
FullContent,
|
||||
HeaderMixedNav,
|
||||
HeaderNav,
|
||||
HeaderSidebarNav,
|
||||
MixedNav,
|
||||
SidebarMixedNav,
|
||||
SidebarNav,
|
||||
} from '../../icons';
|
||||
|
||||
interface PresetItem {
|
||||
name: string;
|
||||
tip: string;
|
||||
type: LayoutType;
|
||||
name: string;
|
||||
tip: string;
|
||||
type: LayoutType;
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'PreferenceLayout',
|
||||
name: 'PreferenceLayout',
|
||||
});
|
||||
|
||||
const modelValue = defineModel<LayoutType>({ default: 'sidebar-nav' });
|
||||
|
||||
const components: Record<LayoutType, Component> = {
|
||||
'full-content': FullContent,
|
||||
'header-nav': HeaderNav,
|
||||
'mixed-nav': MixedNav,
|
||||
'sidebar-mixed-nav': SidebarMixedNav,
|
||||
'sidebar-nav': SidebarNav,
|
||||
'header-mixed-nav': HeaderMixedNav,
|
||||
'header-sidebar-nav': HeaderSidebarNav,
|
||||
'full-content': FullContent,
|
||||
'header-nav': HeaderNav,
|
||||
'mixed-nav': MixedNav,
|
||||
'sidebar-mixed-nav': SidebarMixedNav,
|
||||
'sidebar-nav': SidebarNav,
|
||||
'header-mixed-nav': HeaderMixedNav,
|
||||
'header-sidebar-nav': HeaderSidebarNav,
|
||||
};
|
||||
|
||||
const PRESET = computed((): PresetItem[] => [
|
||||
{
|
||||
name: $t('preferences.vertical'),
|
||||
tip: $t('preferences.verticalTip'),
|
||||
type: 'sidebar-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.twoColumn'),
|
||||
tip: $t('preferences.twoColumnTip'),
|
||||
type: 'sidebar-mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.horizontal'),
|
||||
tip: $t('preferences.horizontalTip'),
|
||||
type: 'header-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.headerSidebarNav'),
|
||||
tip: $t('preferences.headerSidebarNavTip'),
|
||||
type: 'header-sidebar-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.mixedMenu'),
|
||||
tip: $t('preferences.mixedMenuTip'),
|
||||
type: 'mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.headerTwoColumn'),
|
||||
tip: $t('preferences.headerTwoColumnTip'),
|
||||
type: 'header-mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.fullContent'),
|
||||
tip: $t('preferences.fullContentTip'),
|
||||
type: 'full-content',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.vertical'),
|
||||
tip: $t('preferences.verticalTip'),
|
||||
type: 'sidebar-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.twoColumn'),
|
||||
tip: $t('preferences.twoColumnTip'),
|
||||
type: 'sidebar-mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.horizontal'),
|
||||
tip: $t('preferences.horizontalTip'),
|
||||
type: 'header-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.headerSidebarNav'),
|
||||
tip: $t('preferences.headerSidebarNavTip'),
|
||||
type: 'header-sidebar-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.mixedMenu'),
|
||||
tip: $t('preferences.mixedMenuTip'),
|
||||
type: 'mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.headerTwoColumn'),
|
||||
tip: $t('preferences.headerTwoColumnTip'),
|
||||
type: 'header-mixed-nav',
|
||||
},
|
||||
{
|
||||
name: $t('preferences.fullContent'),
|
||||
tip: $t('preferences.fullContentTip'),
|
||||
type: 'full-content',
|
||||
},
|
||||
]);
|
||||
|
||||
function activeClass(theme: string): string[] {
|
||||
return theme === modelValue.value ? ['outline-box-active'] : [];
|
||||
return theme === modelValue.value ? ['outline-box-active'] : [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex w-full flex-wrap gap-5">
|
||||
<template v-for="theme in PRESET" :key="theme.name">
|
||||
<div
|
||||
class="flex w-[100px] cursor-pointer flex-col"
|
||||
@click="modelValue = theme.type"
|
||||
>
|
||||
<div :class="activeClass(theme.type)" class="outline-box flex-center">
|
||||
<component :is="components[theme.type]" />
|
||||
</div>
|
||||
<div
|
||||
class="text-muted-foreground flex-center hover:text-foreground mt-2 text-center text-xs"
|
||||
>
|
||||
{{ theme.name }}
|
||||
<VbenTooltip v-if="theme.tip" side="bottom">
|
||||
<template #trigger>
|
||||
<CircleHelp class="ml-1 size-3 cursor-help" />
|
||||
</template>
|
||||
{{ theme.tip }}
|
||||
</VbenTooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex w-full flex-wrap gap-5">
|
||||
<template v-for="theme in PRESET" :key="theme.name">
|
||||
<div class="flex w-[100px] cursor-pointer flex-col" @click="modelValue = theme.type">
|
||||
<div :class="activeClass(theme.type)" class="outline-box flex-center">
|
||||
<component :is="components[theme.type]" />
|
||||
</div>
|
||||
<div class="text-muted-foreground flex-center hover:text-foreground mt-2 text-center text-xs">
|
||||
{{ theme.name }}
|
||||
<VbenTooltip v-if="theme.tip" side="bottom">
|
||||
<template #trigger>
|
||||
<CircleHelp class="ml-1 size-3 cursor-help" />
|
||||
</template>
|
||||
{{ theme.tip }}
|
||||
</VbenTooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectOption } from '/@/vben/types';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
import ToggleItem from '../toggle-item.vue';
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { LayoutType } from '/@/vben/types';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import NumberFieldItem from '../number-field-item.vue';
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { SelectOption } from '/@/vben/types';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import NumberFieldItem from '../number-field-item.vue';
|
||||
import SelectItem from '../select-item.vue';
|
||||
|
||||
+30
-32
@@ -1,71 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import type { SelectOption } from '/@/vben/types';
|
||||
import type { SelectOption } from "/@/vben/types";
|
||||
|
||||
import { computed } from 'vue';
|
||||
import { computed } from "vue";
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from "/@/locales";
|
||||
|
||||
import SelectItem from '../select-item.vue';
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
import SelectItem from "../select-item.vue";
|
||||
import SwitchItem from "../switch-item.vue";
|
||||
|
||||
defineOptions({
|
||||
name: 'PreferenceInterfaceControl',
|
||||
name: "PreferenceInterfaceControl",
|
||||
});
|
||||
|
||||
const widgetGlobalSearch = defineModel<boolean>('widgetGlobalSearch');
|
||||
const widgetFullscreen = defineModel<boolean>('widgetFullscreen');
|
||||
const widgetLanguageToggle = defineModel<boolean>('widgetLanguageToggle');
|
||||
const widgetNotification = defineModel<boolean>('widgetNotification');
|
||||
const widgetThemeToggle = defineModel<boolean>('widgetThemeToggle');
|
||||
const widgetSidebarToggle = defineModel<boolean>('widgetSidebarToggle');
|
||||
const widgetLockScreen = defineModel<boolean>('widgetLockScreen');
|
||||
const appPreferencesButtonPosition = defineModel<string>(
|
||||
'appPreferencesButtonPosition',
|
||||
);
|
||||
const widgetRefresh = defineModel<boolean>('widgetRefresh');
|
||||
const widgetGlobalSearch = defineModel<boolean>("widgetGlobalSearch");
|
||||
const widgetFullscreen = defineModel<boolean>("widgetFullscreen");
|
||||
const widgetLanguageToggle = defineModel<boolean>("widgetLanguageToggle");
|
||||
const widgetNotification = defineModel<boolean>("widgetNotification");
|
||||
const widgetThemeToggle = defineModel<boolean>("widgetThemeToggle");
|
||||
const widgetSidebarToggle = defineModel<boolean>("widgetSidebarToggle");
|
||||
const widgetLockScreen = defineModel<boolean>("widgetLockScreen");
|
||||
const appPreferencesButtonPosition = defineModel<string>("appPreferencesButtonPosition");
|
||||
const widgetRefresh = defineModel<boolean>("widgetRefresh");
|
||||
|
||||
const positionItems = computed((): SelectOption[] => [
|
||||
{
|
||||
label: $t('preferences.position.auto'),
|
||||
value: 'auto',
|
||||
label: $t("preferences.position.auto"),
|
||||
value: "auto",
|
||||
},
|
||||
{
|
||||
label: $t('preferences.position.header'),
|
||||
value: 'header',
|
||||
label: $t("preferences.position.header"),
|
||||
value: "header",
|
||||
},
|
||||
{
|
||||
label: $t('preferences.position.fixed'),
|
||||
value: 'fixed',
|
||||
label: $t("preferences.position.fixed"),
|
||||
value: "fixed",
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SwitchItem v-model="widgetGlobalSearch">
|
||||
{{ $t('preferences.widget.globalSearch') }}
|
||||
{{ $t("preferences.widget.globalSearch") }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="widgetThemeToggle">
|
||||
{{ $t('preferences.widget.themeToggle') }}
|
||||
{{ $t("preferences.widget.themeToggle") }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="widgetLanguageToggle">
|
||||
{{ $t('preferences.widget.languageToggle') }}
|
||||
{{ $t("preferences.widget.languageToggle") }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="widgetFullscreen">
|
||||
{{ $t('preferences.widget.fullscreen') }}
|
||||
{{ $t("preferences.widget.fullscreen") }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="widgetNotification">
|
||||
{{ $t('preferences.widget.notification') }}
|
||||
{{ $t("preferences.widget.notification") }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="widgetLockScreen">
|
||||
{{ $t('preferences.widget.lockScreen') }}
|
||||
{{ $t("preferences.widget.lockScreen") }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="widgetSidebarToggle">
|
||||
{{ $t('preferences.widget.sidebarToggle') }}
|
||||
{{ $t("preferences.widget.sidebarToggle") }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="widgetRefresh">
|
||||
{{ $t('preferences.widget.refresh') }}
|
||||
{{ $t("preferences.widget.refresh") }}
|
||||
</SwitchItem>
|
||||
<SelectItem v-model="appPreferencesButtonPosition" :items="positionItems">
|
||||
{{ $t('preferences.position.title') }}
|
||||
{{ $t("preferences.position.title") }}
|
||||
</SelectItem>
|
||||
</template>
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
import { isWindowsOs } from '/@/vben/utils';
|
||||
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import type { BuiltinThemeType } from '/@/vben/types';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
import { UserRoundPen } from '/@/vben/icons';
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
import { BUILT_IN_THEME_PRESETS } from '/@/vben/preferences';
|
||||
import { convertToHsl, TinyColor } from '/@/vben/utils';
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import type { Component } from 'vue';
|
||||
import type { ThemeModeType } from '/@/vben/types';
|
||||
|
||||
import { MoonStar, Sun, SunMoon } from '/@/vben/icons';
|
||||
import { $t } from '/@/vben/locales';
|
||||
import { $t } from '/@/locales';
|
||||
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { SupportedLanguagesType } from "/@/vben/locales";
|
||||
import type { SupportedLanguagesType } from "/@/locales";
|
||||
import type {
|
||||
BreadcrumbStyleType,
|
||||
BuiltinThemeType,
|
||||
@@ -17,7 +17,7 @@ import type { SegmentedItem } from "/@/vben//shadcn-ui";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
import { Copy, RotateCw, X } from "/@/vben/icons";
|
||||
import { $t, loadLocaleMessages } from "/@/vben/locales";
|
||||
import { $t, loadLocaleMessages } from "/@/locales";
|
||||
import { clearPreferencesCache, preferences, resetPreferences, usePreferences } from "/@/vben/preferences";
|
||||
|
||||
import { useVbenDrawer } from "/@/vben//popup-ui";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { computed } from "vue";
|
||||
|
||||
import { Settings } from "/@/vben/icons";
|
||||
import { $t, loadLocaleMessages } from "/@/vben/locales";
|
||||
import { $t, loadLocaleMessages } from "/@/locales";
|
||||
import { preferences, updatePreferences } from "/@/vben/preferences";
|
||||
import { capitalizeFirstLetter } from "/@/vben/utils";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import type { ThemeModeType } from "/@/vben/types";
|
||||
|
||||
import { MoonStar, Sun, SunMoon } from "/@/vben/icons";
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
import { preferences, updatePreferences, usePreferences } from "/@/vben/preferences";
|
||||
|
||||
import { ToggleGroup, ToggleGroupItem, VbenTooltip } from "/@/vben//shadcn-ui";
|
||||
|
||||
@@ -7,7 +7,7 @@ import { computed, useTemplateRef, watch } from "vue";
|
||||
|
||||
import { useHoverToggle } from "/@/vben/hooks";
|
||||
import { LockKeyhole, LogOut } from "/@/vben/icons";
|
||||
import { $t } from "/@/vben/locales";
|
||||
import { $t } from "/@/locales";
|
||||
import { preferences, usePreferences } from "/@/vben/preferences";
|
||||
import { useLockStore } from "/@/vben/stores";
|
||||
import { isWindowsOs } from "/@/vben/utils";
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
import type { App } from "vue";
|
||||
import type { Locale } from "vue-i18n";
|
||||
|
||||
import type { ImportLocaleFn, LoadMessageFn, LocaleSetupOptions, SupportedLanguagesType } from "./typing";
|
||||
|
||||
import { unref } from "vue";
|
||||
import { createI18n } from "vue-i18n";
|
||||
|
||||
import { useSimpleLocale } from "/@/vben/composables";
|
||||
|
||||
const i18n = createI18n({
|
||||
globalInjection: true,
|
||||
legacy: false,
|
||||
locale: "",
|
||||
messages: {}
|
||||
});
|
||||
|
||||
const modules = import.meta.glob("./langs/**/*.json");
|
||||
|
||||
const { setSimpleLocale } = useSimpleLocale();
|
||||
|
||||
const localesMap = loadLocalesMapFromDir(/\.\/langs\/([^/]+)\/(.*)\.json$/, modules);
|
||||
let loadMessages: LoadMessageFn;
|
||||
|
||||
/**
|
||||
* Load locale modules
|
||||
* @param modules
|
||||
*/
|
||||
function loadLocalesMap(modules: Record<string, () => Promise<unknown>>) {
|
||||
const localesMap: Record<Locale, ImportLocaleFn> = {};
|
||||
|
||||
for (const [path, loadLocale] of Object.entries(modules)) {
|
||||
const key = path.match(/([\w-]*)\.(json)/)?.[1];
|
||||
if (key) {
|
||||
localesMap[key] = loadLocale as ImportLocaleFn;
|
||||
}
|
||||
}
|
||||
return localesMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load locale modules with directory structure
|
||||
* @param regexp - Regular expression to match language and file names
|
||||
* @param modules - The modules object containing paths and import functions
|
||||
* @returns A map of locales to their corresponding import functions
|
||||
*/
|
||||
function loadLocalesMapFromDir(regexp: RegExp, modules: Record<string, () => Promise<unknown>>): Record<Locale, ImportLocaleFn> {
|
||||
const localesRaw: Record<Locale, Record<string, () => Promise<unknown>>> = {};
|
||||
const localesMap: Record<Locale, ImportLocaleFn> = {};
|
||||
|
||||
// Iterate over the modules to extract language and file names
|
||||
for (const path in modules) {
|
||||
const match = path.match(regexp);
|
||||
if (match) {
|
||||
const [_, locale, fileName] = match;
|
||||
if (locale && fileName) {
|
||||
if (!localesRaw[locale]) {
|
||||
localesRaw[locale] = {};
|
||||
}
|
||||
if (modules[path]) {
|
||||
localesRaw[locale][fileName] = modules[path];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert raw locale data into async import functions
|
||||
for (const [locale, files] of Object.entries(localesRaw)) {
|
||||
localesMap[locale] = async () => {
|
||||
const messages: Record<string, any> = {};
|
||||
for (const [fileName, importFn] of Object.entries(files)) {
|
||||
messages[fileName] = ((await importFn()) as any)?.default;
|
||||
}
|
||||
return { default: messages };
|
||||
};
|
||||
}
|
||||
|
||||
return localesMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set i18n language
|
||||
* @param locale
|
||||
*/
|
||||
function setI18nLanguage(locale: Locale) {
|
||||
i18n.global.locale.value = locale;
|
||||
|
||||
document?.querySelector("html")?.setAttribute("lang", locale);
|
||||
}
|
||||
|
||||
async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
|
||||
const { defaultLocale = "zh-CN" } = options;
|
||||
// app可以自行扩展一些第三方库和组件库的国际化
|
||||
loadMessages = options.loadMessages || (async () => ({}));
|
||||
app.use(i18n);
|
||||
await loadLocaleMessages(defaultLocale);
|
||||
|
||||
// 在控制台打印警告
|
||||
i18n.global.setMissingHandler((locale, key) => {
|
||||
if (options.missingWarn && key.includes(".")) {
|
||||
console.warn(`[intlify] Not found '${key}' key in '${locale}' locale messages.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load locale messages
|
||||
* @param lang
|
||||
*/
|
||||
async function loadLocaleMessages(lang: SupportedLanguagesType) {
|
||||
if (unref(i18n.global.locale) === lang) {
|
||||
return setI18nLanguage(lang);
|
||||
}
|
||||
setSimpleLocale(lang);
|
||||
|
||||
const message = await localesMap[lang]?.();
|
||||
|
||||
if (message?.default) {
|
||||
i18n.global.setLocaleMessage(lang, message.default);
|
||||
}
|
||||
|
||||
const mergeMessage = await loadMessages(lang);
|
||||
i18n.global.mergeLocaleMessage(lang, mergeMessage);
|
||||
|
||||
return setI18nLanguage(lang);
|
||||
}
|
||||
|
||||
export { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n };
|
||||
@@ -1,12 +0,0 @@
|
||||
import { i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n } from "./i18n";
|
||||
|
||||
const $t = i18n.global.t;
|
||||
const $te = i18n.global.te;
|
||||
|
||||
export { $t, $te, i18n, loadLocaleMessages, loadLocalesMap, loadLocalesMapFromDir, setupI18n };
|
||||
export { type ImportLocaleFn, type LocaleSetupOptions, type SupportedLanguagesType } from "./typing";
|
||||
// export type { CompileError } from "@intlify/core-base";
|
||||
|
||||
export { useI18n } from "vue-i18n";
|
||||
|
||||
export type { Locale } from "vue-i18n";
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"welcomeBack": "Welcome Back",
|
||||
"pageTitle": "Plug-and-play Admin system",
|
||||
"pageDesc": "Efficient, versatile frontend template",
|
||||
"loginSuccess": "Login Successful",
|
||||
"loginSuccessDesc": "Welcome Back",
|
||||
"loginSubtitle": "Enter your account details to manage your projects",
|
||||
"selectAccount": "Quick Select Account",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"usernameTip": "Please enter username",
|
||||
"passwordErrorTip": "Password is incorrect",
|
||||
"passwordTip": "Please enter password",
|
||||
"verifyRequiredTip": "Please complete the verification first",
|
||||
"rememberMe": "Remember Me",
|
||||
"createAnAccount": "Create an Account",
|
||||
"createAccount": "Create Account",
|
||||
"alreadyHaveAccount": "Already have an account?",
|
||||
"accountTip": "Don't have an account?",
|
||||
"signUp": "Sign Up",
|
||||
"signUpSubtitle": "Make managing your applications simple and fun",
|
||||
"confirmPassword": "Confirm Password",
|
||||
"confirmPasswordTip": "The passwords do not match",
|
||||
"agree": "I agree to",
|
||||
"privacyPolicy": "Privacy-policy",
|
||||
"terms": "Terms",
|
||||
"agreeTip": "Please agree to the Privacy Policy and Terms",
|
||||
"goToLogin": "Login instead",
|
||||
"passwordStrength": "Use 8 or more characters with a mix of letters, numbers & symbols",
|
||||
"forgetPassword": "Forget Password?",
|
||||
"forgetPasswordSubtitle": "Enter your email and we'll send you instructions to reset your password",
|
||||
"emailTip": "Please enter email",
|
||||
"emailValidErrorTip": "The email format you entered is incorrect",
|
||||
"sendResetLink": "Send Reset Link",
|
||||
"email": "Email",
|
||||
"qrcodeSubtitle": "Scan the QR code with your phone to login",
|
||||
"qrcodePrompt": "Click 'Confirm' after scanning to complete login",
|
||||
"qrcodeLogin": "QR Code Login",
|
||||
"codeSubtitle": "Enter your phone number to start managing your project",
|
||||
"code": "Security code",
|
||||
"codeTip": "Security code required {0} characters",
|
||||
"mobile": "Mobile",
|
||||
"mobileLogin": "Mobile Login",
|
||||
"mobileTip": "Please enter mobile number",
|
||||
"mobileErrortip": "The phone number format is incorrect",
|
||||
"sendCode": "Get Security code",
|
||||
"sendText": "Resend in {0}s",
|
||||
"thirdPartyLogin": "Or continue with",
|
||||
"loginAgainTitle": "Please Log In Again",
|
||||
"loginAgainSubTitle": "Your login session has expired. Please log in again to continue.",
|
||||
"layout": {
|
||||
"center": "Align Center",
|
||||
"alignLeft": "Align Left",
|
||||
"alignRight": "Align Right"
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"back": "Back",
|
||||
"backToHome": "Back To Home",
|
||||
"login": "Login",
|
||||
"logout": "Logout",
|
||||
"prompt": "Prompt",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm",
|
||||
"reset": "Reset",
|
||||
"noData": "No Data",
|
||||
"refresh": "Refresh",
|
||||
"loadingMenu": "Loading Menu",
|
||||
"query": "Search",
|
||||
"search": "Search",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"create": "Create",
|
||||
"yes": "Yes",
|
||||
"no": "No"
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
{
|
||||
"title": "Preferences",
|
||||
"subtitle": "Customize Preferences & Preview in Real Time",
|
||||
"resetTip": "Data has changed, click to reset",
|
||||
"resetTitle": "Reset Preferences",
|
||||
"resetSuccess": "Preferences reset successfully",
|
||||
"appearance": "Appearance",
|
||||
"layout": "Layout",
|
||||
"content": "Content",
|
||||
"other": "Other",
|
||||
"wide": "Wide",
|
||||
"compact": "Fixed",
|
||||
"followSystem": "Follow System",
|
||||
"vertical": "Vertical",
|
||||
"verticalTip": "Side vertical menu mode",
|
||||
"horizontal": "Horizontal",
|
||||
"horizontalTip": "Horizontal menu mode, all menus displayed at the top",
|
||||
"twoColumn": "Two Column",
|
||||
"twoColumnTip": "Vertical Two Column Menu Mode",
|
||||
"headerSidebarNav": "Header Vertical",
|
||||
"headerSidebarNavTip": "Header Full Width, Sidebar Navigation Mode",
|
||||
"headerTwoColumn": "Header Two Column",
|
||||
"headerTwoColumnTip": "Header Navigation & Sidebar Two Column co-exists",
|
||||
"mixedMenu": "Mixed Menu",
|
||||
"mixedMenuTip": "Vertical & Horizontal Menu Co-exists",
|
||||
"fullContent": "Full Content",
|
||||
"fullContentTip": "Only display content body, hide all menus",
|
||||
"normal": "Normal",
|
||||
"plain": "Plain",
|
||||
"rounded": "Rounded",
|
||||
"copyPreferences": "Copy Preferences",
|
||||
"copyPreferencesSuccessTitle": "Copy successful",
|
||||
"copyPreferencesSuccess": "Copy successful, please override in `src/preferences.ts` under app",
|
||||
"clearAndLogout": "Clear Cache & Logout",
|
||||
"mode": "Mode",
|
||||
"general": "General",
|
||||
"language": "Language",
|
||||
"dynamicTitle": "Dynamic Title",
|
||||
"watermark": "Watermark",
|
||||
"checkUpdates": "Periodic update check",
|
||||
"position": {
|
||||
"title": "Preferences Postion",
|
||||
"header": "Header",
|
||||
"auto": "Auto",
|
||||
"fixed": "Fixed"
|
||||
},
|
||||
"sidebar": {
|
||||
"title": "Sidebar",
|
||||
"width": "Width",
|
||||
"visible": "Show Sidebar",
|
||||
"collapsed": "Collpase Menu",
|
||||
"collapsedShowTitle": "Show Menu Title",
|
||||
"autoActivateChild": "Auto Activate SubMenu",
|
||||
"autoActivateChildTip": "`Enabled` to automatically activate the submenu while click menu.",
|
||||
"expandOnHover": "Expand On Hover",
|
||||
"expandOnHoverTip": "When the mouse hovers over menu, \n `Enabled` to expand children menus \n `Disabled` to expand whole sidebar."
|
||||
},
|
||||
"tabbar": {
|
||||
"title": "Tabbar",
|
||||
"enable": "Enable Tab Bar",
|
||||
"icon": "Show Tabbar Icon",
|
||||
"showMore": "Show More Button",
|
||||
"showMaximize": "Show Maximize Button",
|
||||
"persist": "Persist Tabs",
|
||||
"maxCount": "Max Count of Tabs",
|
||||
"maxCountTip": "When the number of tabs exceeds the maximum,\nthe oldest tab will be closed.\n Set to 0 to disable count checking.",
|
||||
"draggable": "Enable Draggable Sort",
|
||||
"wheelable": "Support Mouse Wheel",
|
||||
"middleClickClose": "Close Tab when Mouse Middle Button Click",
|
||||
"wheelableTip": "When enabled, the Tabbar area responds to vertical scrolling events of the scroll wheel.",
|
||||
"styleType": {
|
||||
"title": "Tabs Style",
|
||||
"chrome": "Chrome",
|
||||
"card": "Card",
|
||||
"plain": "Plain",
|
||||
"brisk": "Brisk"
|
||||
},
|
||||
"contextMenu": {
|
||||
"reload": "Reload",
|
||||
"close": "Close",
|
||||
"pin": "Pin",
|
||||
"unpin": "Unpin",
|
||||
"closeLeft": "Close Left Tabs",
|
||||
"closeRight": "Close Right Tabs",
|
||||
"closeOther": "Close Other Tabs",
|
||||
"closeAll": "Close All Tabs",
|
||||
"openInNewWindow": "Open in New Window",
|
||||
"maximize": "Maximize",
|
||||
"restoreMaximize": "Restore"
|
||||
}
|
||||
},
|
||||
"navigationMenu": {
|
||||
"title": "Navigation Menu",
|
||||
"style": "Navigation Menu Style",
|
||||
"accordion": "Sidebar Accordion Menu",
|
||||
"split": "Navigation Menu Separation",
|
||||
"splitTip": "When enabled, the sidebar displays the top bar's submenu"
|
||||
},
|
||||
"breadcrumb": {
|
||||
"title": "Breadcrumb",
|
||||
"home": "Show Home Button",
|
||||
"enable": "Enable Breadcrumb",
|
||||
"icon": "Show Breadcrumb Icon",
|
||||
"background": "background",
|
||||
"style": "Breadcrumb Style",
|
||||
"hideOnlyOne": "Hidden when only one"
|
||||
},
|
||||
"animation": {
|
||||
"title": "Animation",
|
||||
"loading": "Page Loading",
|
||||
"transition": "Page Transition",
|
||||
"progress": "Page Progress"
|
||||
},
|
||||
"theme": {
|
||||
"title": "Theme",
|
||||
"radius": "Radius",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"darkSidebar": "Semi Dark Sidebar",
|
||||
"darkHeader": "Semi Dark Header",
|
||||
"weakMode": "Weak Mode",
|
||||
"grayMode": "Gray Mode",
|
||||
"builtin": {
|
||||
"title": "Built-in",
|
||||
"default": "Default",
|
||||
"violet": "Violet",
|
||||
"pink": "Pink",
|
||||
"rose": "Rose",
|
||||
"skyBlue": "Sky Blue",
|
||||
"deepBlue": "Deep Blue",
|
||||
"green": "Green",
|
||||
"deepGreen": "Deep Green",
|
||||
"orange": "Orange",
|
||||
"yellow": "Yellow",
|
||||
"zinc": "Zinc",
|
||||
"neutral": "Neutral",
|
||||
"slate": "Slate",
|
||||
"gray": "Gray",
|
||||
"custom": "Custom"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "Header",
|
||||
"visible": "Show Header",
|
||||
"modeStatic": "Static",
|
||||
"modeFixed": "Fixed",
|
||||
"modeAuto": "Auto hide & Show",
|
||||
"modeAutoScroll": "Scroll to Hide & Show",
|
||||
"menuAlign": "Menu Align",
|
||||
"menuAlignStart": "Start",
|
||||
"menuAlignEnd": "End",
|
||||
"menuAlignCenter": "Center"
|
||||
},
|
||||
"footer": {
|
||||
"title": "Footer",
|
||||
"visible": "Show Footer",
|
||||
"fixed": "Fixed at Bottom"
|
||||
},
|
||||
"copyright": {
|
||||
"title": "Copyright",
|
||||
"enable": "Enable Copyright",
|
||||
"companyName": "Company Name",
|
||||
"companySiteLink": "Company Site Link",
|
||||
"date": "Date",
|
||||
"icp": "ICP License Number",
|
||||
"icpLink": "ICP Site Link"
|
||||
},
|
||||
"shortcutKeys": {
|
||||
"title": "Shortcut Keys",
|
||||
"global": "Global",
|
||||
"search": "Global Search",
|
||||
"logout": "Logout",
|
||||
"preferences": "Preferences"
|
||||
},
|
||||
"widget": {
|
||||
"title": "Widget",
|
||||
"globalSearch": "Enable Global Search",
|
||||
"fullscreen": "Enable Fullscreen",
|
||||
"themeToggle": "Enable Theme Toggle",
|
||||
"languageToggle": "Enable Language Toggle",
|
||||
"notification": "Enable Notification",
|
||||
"sidebarToggle": "Enable Sidebar Toggle",
|
||||
"lockScreen": "Enable Lock Screen",
|
||||
"refresh": "Enable Refresh"
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"formRules": {
|
||||
"required": "Please enter {0}",
|
||||
"selectRequired": "Please select {0}",
|
||||
"minLength": "{0} must be at least {1} characters",
|
||||
"maxLength": "{0} can be at most {1} characters",
|
||||
"length": "{0} must be {1} characters long",
|
||||
"alreadyExists": "{0} `{1}` already exists",
|
||||
"startWith": "{0} must start with `{1}`",
|
||||
"invalidURL": "Please input a valid URL"
|
||||
},
|
||||
"actionTitle": {
|
||||
"edit": "Modify {0}",
|
||||
"create": "Create {0}",
|
||||
"delete": "Delete {0}",
|
||||
"view": "View {0}"
|
||||
},
|
||||
"actionMessage": {
|
||||
"deleteConfirm": "Are you sure to delete {0}?",
|
||||
"deleting": "Deleting {0} ...",
|
||||
"deleteSuccess": "{0} deleted successfully",
|
||||
"operationSuccess": "Operation succeeded",
|
||||
"operationFailed": "Operation failed"
|
||||
},
|
||||
"placeholder": {
|
||||
"input": "Please enter",
|
||||
"select": "Please select"
|
||||
},
|
||||
"captcha": {
|
||||
"title": "Please complete the security verification",
|
||||
"sliderSuccessText": "Passed",
|
||||
"sliderDefaultText": "Slider and drag",
|
||||
"alt": "Supports img tag src attribute value",
|
||||
"sliderRotateDefaultTip": "Click picture to refresh",
|
||||
"sliderRotateFailTip": "Validation failed",
|
||||
"sliderRotateSuccessTip": "Validation successful, time {0} seconds",
|
||||
"refreshAriaLabel": "Refresh captcha",
|
||||
"confirmAriaLabel": "Confirm selection",
|
||||
"confirm": "Confirm",
|
||||
"pointAriaLabel": "Click point",
|
||||
"clickInOrder": "Please click in order"
|
||||
},
|
||||
"iconPicker": {
|
||||
"placeholder": "Select an icon",
|
||||
"search": "Search icon..."
|
||||
},
|
||||
"jsonViewer": {
|
||||
"copy": "Copy",
|
||||
"copied": "Copied"
|
||||
},
|
||||
"fallback": {
|
||||
"pageNotFound": "Oops! Page Not Found",
|
||||
"pageNotFoundDesc": "Sorry, we couldn't find the page you were looking for.",
|
||||
"forbidden": "Oops! Access Denied",
|
||||
"forbiddenDesc": "Sorry, but you don't have permission to access this page.",
|
||||
"internalError": "Oops! Something Went Wrong",
|
||||
"internalErrorDesc": "Sorry, but the server encountered an error.",
|
||||
"offline": "Offline Page",
|
||||
"offlineError": "Oops! Network Error",
|
||||
"offlineErrorDesc": "Sorry, can't connect to the internet. Check your connection.",
|
||||
"comingSoon": "Coming Soon",
|
||||
"http": {
|
||||
"requestTimeout": "The request timed out. Please try again later.",
|
||||
"networkError": "A network error occurred. Please check your internet connection and try again.",
|
||||
"badRequest": "Bad Request. Please check your input and try again.",
|
||||
"unauthorized": "Unauthorized. Please log in to continue.",
|
||||
"forbidden": "Forbidden. You do not have permission to access this resource.",
|
||||
"notFound": "Not Found. The requested resource could not be found.",
|
||||
"internalServerError": "Internal Server Error. Something went wrong on our end. Please try again later."
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
"document": "Document",
|
||||
"qa": "Q&A",
|
||||
"setting": "Settings",
|
||||
"logoutTip": "Do you want to logout?",
|
||||
"viewAll": "View All Messages",
|
||||
"notifications": "Notifications",
|
||||
"markAllAsRead": "Make All as Read",
|
||||
"clearNotifications": "Clear",
|
||||
"checkUpdatesTitle": "New Version Available",
|
||||
"checkUpdatesDescription": "Click to refresh and get the latest version",
|
||||
"search": {
|
||||
"title": "Search",
|
||||
"searchNavigate": "Search Navigation",
|
||||
"select": "Select",
|
||||
"navigate": "Navigate",
|
||||
"close": "Close",
|
||||
"noResults": "No Search Results Found",
|
||||
"noRecent": "No Search History",
|
||||
"recent": "Search History"
|
||||
},
|
||||
"lockScreen": {
|
||||
"title": "Lock Screen",
|
||||
"screenButton": "Locking",
|
||||
"password": "Password",
|
||||
"placeholder": "Please enter password",
|
||||
"unlock": "Click to unlock",
|
||||
"errorPasswordTip": "Password error, please re-enter",
|
||||
"backToLogin": "Back to login",
|
||||
"entry": "Enter the system"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"welcomeBack": "欢迎回来",
|
||||
"pageTitle": "开箱即用的大型中后台管理系统",
|
||||
"pageDesc": "工程化、高性能、跨组件库的前端模版",
|
||||
"loginSuccess": "登录成功",
|
||||
"loginSuccessDesc": "欢迎回来",
|
||||
"loginSubtitle": "请输入您的帐户信息以开始管理您的项目",
|
||||
"selectAccount": "快速选择账号",
|
||||
"username": "账号",
|
||||
"password": "密码",
|
||||
"usernameTip": "请输入用户名",
|
||||
"passwordTip": "请输入密码",
|
||||
"verifyRequiredTip": "请先完成验证",
|
||||
"passwordErrorTip": "密码错误",
|
||||
"rememberMe": "记住账号",
|
||||
"createAnAccount": "创建一个账号",
|
||||
"createAccount": "创建账号",
|
||||
"alreadyHaveAccount": "已经有账号了?",
|
||||
"accountTip": "还没有账号?",
|
||||
"signUp": "注册",
|
||||
"signUpSubtitle": "让您的应用程序管理变得简单而有趣",
|
||||
"confirmPassword": "确认密码",
|
||||
"confirmPasswordTip": "两次输入的密码不一致",
|
||||
"agree": "我同意",
|
||||
"privacyPolicy": "隐私政策",
|
||||
"terms": "条款",
|
||||
"agreeTip": "请同意隐私政策和条款",
|
||||
"goToLogin": "去登录",
|
||||
"passwordStrength": "使用 8 个或更多字符,混合字母、数字和符号",
|
||||
"forgetPassword": "忘记密码?",
|
||||
"forgetPasswordSubtitle": "输入您的电子邮件,我们将向您发送重置密码的连接",
|
||||
"emailTip": "请输入邮箱",
|
||||
"emailValidErrorTip": "你输入的邮箱格式不正确",
|
||||
"sendResetLink": "发送重置链接",
|
||||
"email": "邮箱",
|
||||
"qrcodeSubtitle": "请用手机扫描二维码登录",
|
||||
"qrcodePrompt": "扫码后点击 '确认',即可完成登录",
|
||||
"qrcodeLogin": "扫码登录",
|
||||
"codeSubtitle": "请输入您的手机号码以开始管理您的项目",
|
||||
"code": "验证码",
|
||||
"codeTip": "请输入{0}位验证码",
|
||||
"mobile": "手机号码",
|
||||
"mobileTip": "请输入手机号",
|
||||
"mobileErrortip": "手机号码格式错误",
|
||||
"mobileLogin": "手机号登录",
|
||||
"sendCode": "获取验证码",
|
||||
"sendText": "{0}秒后重新获取",
|
||||
"thirdPartyLogin": "其他登录方式",
|
||||
"loginAgainTitle": "重新登录",
|
||||
"loginAgainSubTitle": "您的登录状态已过期,请重新登录以继续。",
|
||||
"layout": {
|
||||
"center": "居中",
|
||||
"alignLeft": "居左",
|
||||
"alignRight": "居右"
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"back": "返回",
|
||||
"backToHome": "返回首页",
|
||||
"login": "登录",
|
||||
"logout": "退出登录",
|
||||
"prompt": "提示",
|
||||
"cancel": "取消",
|
||||
"confirm": "确认",
|
||||
"reset": "重置",
|
||||
"noData": "暂无数据",
|
||||
"refresh": "刷新",
|
||||
"loadingMenu": "加载菜单中",
|
||||
"query": "查询",
|
||||
"search": "搜索",
|
||||
"enabled": "已启用",
|
||||
"disabled": "已禁用",
|
||||
"edit": "修改",
|
||||
"delete": "删除",
|
||||
"create": "新增",
|
||||
"yes": "是",
|
||||
"no": "否"
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
{
|
||||
"title": "偏好设置",
|
||||
"subtitle": "自定义偏好设置 & 实时预览",
|
||||
"resetTitle": "重置偏好设置",
|
||||
"resetTip": "数据有变化,点击可进行重置",
|
||||
"resetSuccess": "重置偏好设置成功",
|
||||
"appearance": "外观",
|
||||
"layout": "布局",
|
||||
"content": "内容",
|
||||
"other": "其它",
|
||||
"wide": "流式",
|
||||
"compact": "定宽",
|
||||
"followSystem": "跟随系统",
|
||||
"vertical": "垂直",
|
||||
"verticalTip": "侧边垂直菜单模式",
|
||||
"horizontal": "水平",
|
||||
"horizontalTip": "水平菜单模式,菜单全部显示在顶部",
|
||||
"twoColumn": "双列菜单",
|
||||
"twoColumnTip": "垂直双列菜单模式",
|
||||
"headerSidebarNav": "侧边导航",
|
||||
"headerSidebarNavTip": "顶部通栏,侧边导航模式",
|
||||
"headerTwoColumn": "混合双列",
|
||||
"headerTwoColumnTip": "双列、水平菜单共存模式",
|
||||
"mixedMenu": "混合垂直",
|
||||
"mixedMenuTip": "垂直水平菜单共存",
|
||||
"fullContent": "内容全屏",
|
||||
"fullContentTip": "不显示任何菜单,只显示内容主体",
|
||||
"normal": "常规",
|
||||
"plain": "朴素",
|
||||
"rounded": "圆润",
|
||||
"copyPreferences": "复制偏好设置",
|
||||
"copyPreferencesSuccessTitle": "复制成功",
|
||||
"copyPreferencesSuccess": "复制成功,请在 app 下的 `src/preferences.ts`内进行覆盖",
|
||||
"clearAndLogout": "清空缓存 & 退出登录",
|
||||
"mode": "模式",
|
||||
"general": "通用",
|
||||
"language": "语言",
|
||||
"dynamicTitle": "动态标题",
|
||||
"watermark": "水印",
|
||||
"checkUpdates": "定时检查更新",
|
||||
"position": {
|
||||
"title": "偏好设置位置",
|
||||
"header": "顶栏",
|
||||
"auto": "自动",
|
||||
"fixed": "固定"
|
||||
},
|
||||
"sidebar": {
|
||||
"title": "侧边栏",
|
||||
"width": "宽度",
|
||||
"visible": "显示侧边栏",
|
||||
"collapsed": "折叠菜单",
|
||||
"collapsedShowTitle": "折叠显示菜单名",
|
||||
"autoActivateChild": "自动激活子菜单",
|
||||
"autoActivateChildTip": "点击顶层菜单时,自动激活第一个子菜单或者上一次激活的子菜单",
|
||||
"expandOnHover": "鼠标悬停展开",
|
||||
"expandOnHoverTip": "鼠标在折叠区域悬浮时,`启用`则展开当前子菜单,`禁用`则展开整个侧边栏"
|
||||
},
|
||||
"tabbar": {
|
||||
"title": "标签栏",
|
||||
"enable": "启用标签栏",
|
||||
"icon": "显示标签栏图标",
|
||||
"showMore": "显示更多按钮",
|
||||
"showMaximize": "显示最大化按钮",
|
||||
"persist": "持久化标签页",
|
||||
"maxCount": "最大标签数",
|
||||
"maxCountTip": "每次打开新的标签时如果超过最大标签数,\n会自动关闭一个最先打开的标签\n设置为 0 则不限制",
|
||||
"draggable": "启动拖拽排序",
|
||||
"wheelable": "启用纵向滚轮响应",
|
||||
"middleClickClose": "点击鼠标中键关闭标签页",
|
||||
"wheelableTip": "开启后,标签栏区域可以响应滚轮的纵向滚动事件。\n关闭时,只能响应系统的横向滚动事件(需要按下Shift再滚动滚轮)",
|
||||
"styleType": {
|
||||
"title": "标签页风格",
|
||||
"chrome": "谷歌",
|
||||
"card": "卡片",
|
||||
"plain": "朴素",
|
||||
"brisk": "轻快"
|
||||
},
|
||||
"contextMenu": {
|
||||
"reload": "重新加载",
|
||||
"close": "关闭",
|
||||
"pin": "固定",
|
||||
"unpin": "取消固定",
|
||||
"closeLeft": "关闭左侧标签页",
|
||||
"closeRight": "关闭右侧标签页",
|
||||
"closeOther": "关闭其它标签页",
|
||||
"closeAll": "关闭全部标签页",
|
||||
"openInNewWindow": "在新窗口打开",
|
||||
"maximize": "最大化",
|
||||
"restoreMaximize": "还原"
|
||||
}
|
||||
},
|
||||
"navigationMenu": {
|
||||
"title": "导航菜单",
|
||||
"style": "导航菜单风格",
|
||||
"accordion": "侧边导航菜单手风琴模式",
|
||||
"split": "导航菜单分离",
|
||||
"splitTip": "开启时,侧边栏显示顶栏对应菜单的子菜单"
|
||||
},
|
||||
"breadcrumb": {
|
||||
"title": "面包屑导航",
|
||||
"enable": "开启面包屑导航",
|
||||
"icon": "显示面包屑图标",
|
||||
"home": "显示首页按钮",
|
||||
"style": "面包屑风格",
|
||||
"hideOnlyOne": "仅有一个时隐藏",
|
||||
"background": "背景"
|
||||
},
|
||||
"animation": {
|
||||
"title": "动画",
|
||||
"loading": "页面切换 Loading",
|
||||
"transition": "页面切换动画",
|
||||
"progress": "页面切换进度条"
|
||||
},
|
||||
"theme": {
|
||||
"title": "主题",
|
||||
"radius": "圆角",
|
||||
"light": "浅色",
|
||||
"dark": "深色",
|
||||
"darkSidebar": "深色侧边栏",
|
||||
"darkHeader": "深色顶栏",
|
||||
"weakMode": "色弱模式",
|
||||
"grayMode": "灰色模式",
|
||||
"builtin": {
|
||||
"title": "内置主题",
|
||||
"default": "默认",
|
||||
"violet": "紫罗兰",
|
||||
"pink": "樱花粉",
|
||||
"rose": "玫瑰红",
|
||||
"skyBlue": "天蓝色",
|
||||
"deepBlue": "深蓝色",
|
||||
"green": "浅绿色",
|
||||
"deepGreen": "深绿色",
|
||||
"orange": "橙黄色",
|
||||
"yellow": "柠檬黄",
|
||||
"zinc": "锌色灰",
|
||||
"neutral": "中性色",
|
||||
"slate": "石板灰",
|
||||
"gray": "中灰色",
|
||||
"custom": "自定义"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"title": "顶栏",
|
||||
"modeStatic": "静止",
|
||||
"modeFixed": "固定",
|
||||
"modeAuto": "自动隐藏和显示",
|
||||
"modeAutoScroll": "滚动隐藏和显示",
|
||||
"visible": "显示顶栏",
|
||||
"menuAlign": "菜单位置",
|
||||
"menuAlignStart": "左侧",
|
||||
"menuAlignEnd": "右侧",
|
||||
"menuAlignCenter": "居中"
|
||||
},
|
||||
"footer": {
|
||||
"title": "底栏",
|
||||
"visible": "显示底栏",
|
||||
"fixed": "固定在底部"
|
||||
},
|
||||
"copyright": {
|
||||
"title": "版权",
|
||||
"enable": "启用版权",
|
||||
"companyName": "公司名",
|
||||
"companySiteLink": "公司主页",
|
||||
"date": "日期",
|
||||
"icp": "ICP 备案号",
|
||||
"icpLink": "ICP 网站链接"
|
||||
},
|
||||
"shortcutKeys": {
|
||||
"title": "快捷键",
|
||||
"global": "全局",
|
||||
"search": "全局搜索",
|
||||
"logout": "退出登录",
|
||||
"preferences": "偏好设置"
|
||||
},
|
||||
"widget": {
|
||||
"title": "小部件",
|
||||
"globalSearch": "启用全局搜索",
|
||||
"fullscreen": "启用全屏",
|
||||
"themeToggle": "启用主题切换",
|
||||
"languageToggle": "启用语言切换",
|
||||
"notification": "启用通知",
|
||||
"sidebarToggle": "启用侧边栏切换",
|
||||
"lockScreen": "启用锁屏",
|
||||
"refresh": "启用刷新"
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"formRules": {
|
||||
"required": "请输入{0}",
|
||||
"selectRequired": "请选择{0}",
|
||||
"minLength": "{0}至少{1}个字符",
|
||||
"maxLength": "{0}最多{1}个字符",
|
||||
"length": "{0}长度必须为{1}个字符",
|
||||
"alreadyExists": "{0} `{1}` 已存在",
|
||||
"startWith": "{0}必须以 {1} 开头",
|
||||
"invalidURL": "请输入有效的链接"
|
||||
},
|
||||
"actionTitle": {
|
||||
"edit": "修改{0}",
|
||||
"create": "新增{0}",
|
||||
"delete": "删除{0}",
|
||||
"view": "查看{0}"
|
||||
},
|
||||
"actionMessage": {
|
||||
"deleteConfirm": "确定删除 {0} 吗?",
|
||||
"deleting": "正在删除 {0} ...",
|
||||
"deleteSuccess": "{0} 删除成功",
|
||||
"operationSuccess": "操作成功",
|
||||
"operationFailed": "操作失败"
|
||||
},
|
||||
"placeholder": {
|
||||
"input": "请输入",
|
||||
"select": "请选择"
|
||||
},
|
||||
"captcha": {
|
||||
"title": "请完成安全验证",
|
||||
"sliderSuccessText": "验证通过",
|
||||
"sliderDefaultText": "请按住滑块拖动",
|
||||
"sliderRotateDefaultTip": "点击图片可刷新",
|
||||
"sliderRotateFailTip": "验证失败",
|
||||
"sliderRotateSuccessTip": "验证成功,耗时{0}秒",
|
||||
"alt": "支持img标签src属性值",
|
||||
"refreshAriaLabel": "刷新验证码",
|
||||
"confirmAriaLabel": "确认选择",
|
||||
"confirm": "确认",
|
||||
"pointAriaLabel": "点击点",
|
||||
"clickInOrder": "请依次点击"
|
||||
},
|
||||
"iconPicker": {
|
||||
"placeholder": "选择一个图标",
|
||||
"search": "搜索图标..."
|
||||
},
|
||||
"jsonViewer": {
|
||||
"copy": "复制",
|
||||
"copied": "已复制"
|
||||
},
|
||||
"fallback": {
|
||||
"pageNotFound": "哎呀!未找到页面",
|
||||
"pageNotFoundDesc": "抱歉,我们无法找到您要找的页面。",
|
||||
"forbidden": "哎呀!访问被拒绝",
|
||||
"forbiddenDesc": "抱歉,您没有权限访问此页面。",
|
||||
"internalError": "哎呀!出错了",
|
||||
"internalErrorDesc": "抱歉,服务器遇到错误。",
|
||||
"offline": "离线页面",
|
||||
"offlineError": "哎呀!网络错误",
|
||||
"offlineErrorDesc": "抱歉,无法连接到互联网,请检查您的网络连接并重试。",
|
||||
"comingSoon": "即将推出",
|
||||
"http": {
|
||||
"requestTimeout": "请求超时,请稍后再试。",
|
||||
"networkError": "网络异常,请检查您的网络连接后重试。",
|
||||
"badRequest": "请求错误。请检查您的输入并重试。",
|
||||
"unauthorized": "登录认证过期,请重新登录后继续。",
|
||||
"forbidden": "禁止访问, 您没有权限访问此资源。",
|
||||
"notFound": "未找到, 请求的资源不存在。",
|
||||
"internalServerError": "内部服务器错误,请稍后再试。"
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
"document": "文档",
|
||||
"qa": "问题 & 帮助",
|
||||
"setting": "设置",
|
||||
"logoutTip": "是否退出登录?",
|
||||
"viewAll": "查看所有消息",
|
||||
"notifications": "通知",
|
||||
"markAllAsRead": "全部标记为已读",
|
||||
"clearNotifications": "清空",
|
||||
"checkUpdatesTitle": "新版本可用",
|
||||
"checkUpdatesDescription": "点击刷新以获取最新版本",
|
||||
"search": {
|
||||
"title": "搜索",
|
||||
"searchNavigate": "搜索导航菜单",
|
||||
"select": "选择",
|
||||
"navigate": "导航",
|
||||
"close": "关闭",
|
||||
"noResults": "未找到搜索结果",
|
||||
"noRecent": "没有搜索历史",
|
||||
"recent": "搜索历史"
|
||||
},
|
||||
"lockScreen": {
|
||||
"title": "锁定屏幕",
|
||||
"screenButton": "锁定",
|
||||
"password": "密码",
|
||||
"placeholder": "请输入锁屏密码",
|
||||
"unlock": "点击解锁",
|
||||
"errorPasswordTip": "密码错误,请重新输入",
|
||||
"backToLogin": "返回登录",
|
||||
"entry": "进入系统"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
export type SupportedLanguagesType = "en-US" | "zh-CN";
|
||||
|
||||
export type ImportLocaleFn = () => Promise<{ default: Record<string, string> }>;
|
||||
|
||||
export type LoadMessageFn = (lang: SupportedLanguagesType) => Promise<Record<string, string> | undefined>;
|
||||
|
||||
export interface LocaleSetupOptions {
|
||||
/**
|
||||
* Default language
|
||||
* @default zh-CN
|
||||
*/
|
||||
defaultLocale?: SupportedLanguagesType;
|
||||
/**
|
||||
* Load message function
|
||||
* @param lang
|
||||
* @returns
|
||||
*/
|
||||
loadMessages?: LoadMessageFn;
|
||||
/**
|
||||
* Whether to warn when the key is not found
|
||||
*/
|
||||
missingWarn?: boolean;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ const defaultPreferences: Preferences = {
|
||||
widget: {
|
||||
fullscreen: true,
|
||||
globalSearch: true,
|
||||
languageToggle: false,
|
||||
languageToggle: true,
|
||||
lockScreen: true,
|
||||
notification: false,
|
||||
refresh: true,
|
||||
|
||||
@@ -1,35 +1,23 @@
|
||||
import type { Preferences } from './types';
|
||||
import type { Preferences } from "./types";
|
||||
|
||||
import { preferencesManager } from './preferences';
|
||||
import { preferencesManager } from "./preferences";
|
||||
|
||||
// 偏好设置(带有层级关系)
|
||||
const preferences: Preferences =
|
||||
preferencesManager.getPreferences.apply(preferencesManager);
|
||||
const preferences: Preferences = preferencesManager.getPreferences.apply(preferencesManager);
|
||||
|
||||
// 更新偏好设置
|
||||
const updatePreferences =
|
||||
preferencesManager.updatePreferences.bind(preferencesManager);
|
||||
const updatePreferences = preferencesManager.updatePreferences.bind(preferencesManager);
|
||||
|
||||
// 重置偏好设置
|
||||
const resetPreferences =
|
||||
preferencesManager.resetPreferences.bind(preferencesManager);
|
||||
const resetPreferences = preferencesManager.resetPreferences.bind(preferencesManager);
|
||||
|
||||
const clearPreferencesCache =
|
||||
preferencesManager.clearCache.bind(preferencesManager);
|
||||
const clearPreferencesCache = preferencesManager.clearCache.bind(preferencesManager);
|
||||
|
||||
// 初始化偏好设置
|
||||
const initPreferences =
|
||||
preferencesManager.initPreferences.bind(preferencesManager);
|
||||
const initPreferences = preferencesManager.initPreferences.bind(preferencesManager);
|
||||
|
||||
export {
|
||||
clearPreferencesCache,
|
||||
initPreferences,
|
||||
preferences,
|
||||
preferencesManager,
|
||||
resetPreferences,
|
||||
updatePreferences,
|
||||
};
|
||||
export { clearPreferencesCache, initPreferences, preferences, preferencesManager, resetPreferences, updatePreferences };
|
||||
|
||||
export * from './constants';
|
||||
export type * from './types';
|
||||
export * from './use-preferences';
|
||||
export * from "./constants";
|
||||
export type * from "./types";
|
||||
export * from "./use-preferences";
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
import type { DeepPartial } from '/@/vben/typings';
|
||||
import type { DeepPartial } from "/@/vben/typings";
|
||||
|
||||
import type { InitialOptions, Preferences } from './types';
|
||||
import type { InitialOptions, Preferences } from "./types";
|
||||
|
||||
import { markRaw, reactive, readonly, watch } from 'vue';
|
||||
import { markRaw, reactive, readonly, watch } from "vue";
|
||||
|
||||
import { StorageManager } from '/@/vben/shared/cache';
|
||||
import { isMacOs, merge } from '/@/vben/shared/utils';
|
||||
import { StorageManager } from "/@/vben/shared/cache";
|
||||
import { isMacOs, merge } from "/@/vben/shared/utils";
|
||||
|
||||
import {
|
||||
breakpointsTailwind,
|
||||
useBreakpoints,
|
||||
useDebounceFn,
|
||||
} from '@vueuse/core';
|
||||
import { breakpointsTailwind, useBreakpoints, useDebounceFn } from "@vueuse/core";
|
||||
|
||||
import { defaultPreferences } from './config';
|
||||
import { updateCSSVariables } from './update-css-variables';
|
||||
import { defaultPreferences } from "./config";
|
||||
import { updateCSSVariables } from "./update-css-variables";
|
||||
|
||||
const STORAGE_KEY = 'preferences';
|
||||
const STORAGE_KEY = "preferences";
|
||||
const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`;
|
||||
const STORAGE_KEY_THEME = `${STORAGE_KEY}-theme`;
|
||||
|
||||
@@ -33,14 +29,11 @@ class PreferenceManager {
|
||||
this.cache = new StorageManager();
|
||||
|
||||
// 避免频繁的操作缓存
|
||||
this.savePreferences = useDebounceFn(
|
||||
(preference: Preferences) => this._savePreferences(preference),
|
||||
150,
|
||||
);
|
||||
this.savePreferences = useDebounceFn((preference: Preferences) => this._savePreferences(preference), 150);
|
||||
}
|
||||
|
||||
clearCache() {
|
||||
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => {
|
||||
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach(key => {
|
||||
this.cache?.removeItem(key);
|
||||
});
|
||||
}
|
||||
@@ -73,7 +66,7 @@ class PreferenceManager {
|
||||
{},
|
||||
// overrides,
|
||||
this.loadCachedPreferences() || {},
|
||||
this.initialPreferences,
|
||||
this.initialPreferences
|
||||
);
|
||||
|
||||
// 更新偏好设置
|
||||
@@ -103,7 +96,7 @@ class PreferenceManager {
|
||||
// 保存重置后的偏好设置
|
||||
this.savePreferences(this.state);
|
||||
// 从存储中移除偏好设置项
|
||||
[STORAGE_KEY, STORAGE_KEY_THEME, STORAGE_KEY_LOCALE].forEach((key) => {
|
||||
[STORAGE_KEY, STORAGE_KEY_THEME, STORAGE_KEY_LOCALE].forEach(key => {
|
||||
this.cache?.removeItem(key);
|
||||
});
|
||||
this.updatePreferences(this.state);
|
||||
@@ -145,17 +138,14 @@ class PreferenceManager {
|
||||
updateCSSVariables(this.state);
|
||||
}
|
||||
|
||||
if (
|
||||
Reflect.has(appUpdates, 'colorGrayMode') ||
|
||||
Reflect.has(appUpdates, 'colorWeakMode')
|
||||
) {
|
||||
if (Reflect.has(appUpdates, "colorGrayMode") || Reflect.has(appUpdates, "colorWeakMode")) {
|
||||
this.updateColorMode(this.state);
|
||||
}
|
||||
}
|
||||
|
||||
private initPlatform() {
|
||||
const dom = document.documentElement;
|
||||
dom.dataset.platform = isMacOs() ? 'macOs' : 'window';
|
||||
dom.dataset.platform = isMacOs() ? "macOs" : "window";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,25 +173,23 @@ class PreferenceManager {
|
||||
|
||||
// 监听断点,判断是否移动端
|
||||
const breakpoints = useBreakpoints(breakpointsTailwind);
|
||||
const isMobile = breakpoints.smaller('md');
|
||||
const isMobile = breakpoints.smaller("md");
|
||||
watch(
|
||||
() => isMobile.value,
|
||||
(val) => {
|
||||
val => {
|
||||
this.updatePreferences({
|
||||
app: { isMobile: val },
|
||||
});
|
||||
},
|
||||
{ immediate: true },
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 监听系统主题偏好设置变化
|
||||
window
|
||||
.matchMedia('(prefers-color-scheme: dark)')
|
||||
.addEventListener('change', ({ matches: isDark }) => {
|
||||
this.updatePreferences({
|
||||
theme: { mode: isDark ? 'dark' : 'light' },
|
||||
});
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", ({ matches: isDark }) => {
|
||||
this.updatePreferences({
|
||||
theme: { mode: isDark ? "dark" : "light" },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,14 +200,10 @@ class PreferenceManager {
|
||||
if (preference.app) {
|
||||
const { colorGrayMode, colorWeakMode } = preference.app;
|
||||
const dom = document.documentElement;
|
||||
const COLOR_WEAK = 'invert-mode';
|
||||
const COLOR_GRAY = 'grayscale-mode';
|
||||
colorWeakMode
|
||||
? dom.classList.add(COLOR_WEAK)
|
||||
: dom.classList.remove(COLOR_WEAK);
|
||||
colorGrayMode
|
||||
? dom.classList.add(COLOR_GRAY)
|
||||
: dom.classList.remove(COLOR_GRAY);
|
||||
const COLOR_WEAK = "invert-mode";
|
||||
const COLOR_GRAY = "grayscale-mode";
|
||||
colorWeakMode ? dom.classList.add(COLOR_WEAK) : dom.classList.remove(COLOR_WEAK);
|
||||
colorGrayMode ? dom.classList.add(COLOR_GRAY) : dom.classList.remove(COLOR_GRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Preferences } from './types';
|
||||
import type { Preferences } from "./types";
|
||||
|
||||
import { generatorColorVariables } from '/@/vben/shared/color';
|
||||
import { updateCSSVariables as executeUpdateCSSVariables } from '/@/vben/shared/utils';
|
||||
import { generatorColorVariables } from "/@/vben/shared/color";
|
||||
import { updateCSSVariables as executeUpdateCSSVariables } from "/@/vben/shared/utils";
|
||||
|
||||
import { BUILT_IN_THEME_PRESETS } from './constants';
|
||||
import { BUILT_IN_THEME_PRESETS } from "./constants";
|
||||
|
||||
/**
|
||||
* 更新主题的 CSS 变量以及其他 CSS 变量
|
||||
@@ -21,13 +21,13 @@ function updateCSSVariables(preferences: Preferences) {
|
||||
const { builtinType, mode, radius } = theme;
|
||||
|
||||
// html 设置 dark 类
|
||||
if (Reflect.has(theme, 'mode')) {
|
||||
if (Reflect.has(theme, "mode")) {
|
||||
const dark = isDarkTheme(mode);
|
||||
root.classList.toggle('dark', dark);
|
||||
root.classList.toggle("dark", dark);
|
||||
}
|
||||
|
||||
// html 设置 data-theme=[builtinType]
|
||||
if (Reflect.has(theme, 'builtinType')) {
|
||||
if (Reflect.has(theme, "builtinType")) {
|
||||
const rootTheme = root.dataset.theme;
|
||||
if (rootTheme !== builtinType) {
|
||||
root.dataset.theme = builtinType;
|
||||
@@ -35,36 +35,26 @@ function updateCSSVariables(preferences: Preferences) {
|
||||
}
|
||||
|
||||
// 获取当前的内置主题
|
||||
const currentBuiltType = [...BUILT_IN_THEME_PRESETS].find(
|
||||
(item) => item.type === builtinType,
|
||||
);
|
||||
const currentBuiltType = [...BUILT_IN_THEME_PRESETS].find(item => item.type === builtinType);
|
||||
|
||||
let builtinTypeColorPrimary: string | undefined = '';
|
||||
let builtinTypeColorPrimary: string | undefined = "";
|
||||
|
||||
if (currentBuiltType) {
|
||||
const isDark = isDarkTheme(preferences.theme.mode);
|
||||
// 设置不同主题的主要颜色
|
||||
const color = isDark
|
||||
? currentBuiltType.darkPrimaryColor || currentBuiltType.primaryColor
|
||||
: currentBuiltType.primaryColor;
|
||||
const color = isDark ? currentBuiltType.darkPrimaryColor || currentBuiltType.primaryColor : currentBuiltType.primaryColor;
|
||||
builtinTypeColorPrimary = color || currentBuiltType.color;
|
||||
}
|
||||
|
||||
// 如果内置主题颜色和自定义颜色都不存在,则不更新主题颜色
|
||||
if (
|
||||
builtinTypeColorPrimary ||
|
||||
Reflect.has(theme, 'colorPrimary') ||
|
||||
Reflect.has(theme, 'colorDestructive') ||
|
||||
Reflect.has(theme, 'colorSuccess') ||
|
||||
Reflect.has(theme, 'colorWarning')
|
||||
) {
|
||||
if (builtinTypeColorPrimary || Reflect.has(theme, "colorPrimary") || Reflect.has(theme, "colorDestructive") || Reflect.has(theme, "colorSuccess") || Reflect.has(theme, "colorWarning")) {
|
||||
// preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary;
|
||||
updateMainColorVariables(preferences);
|
||||
}
|
||||
|
||||
// 更新圆角
|
||||
if (Reflect.has(theme, 'radius')) {
|
||||
document.documentElement.style.setProperty('--radius', `${radius}rem`);
|
||||
if (Reflect.has(theme, "radius")) {
|
||||
document.documentElement.style.setProperty("--radius", `${radius}rem`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,22 +66,21 @@ function updateMainColorVariables(preference: Preferences) {
|
||||
if (!preference.theme) {
|
||||
return;
|
||||
}
|
||||
const { colorDestructive, colorPrimary, colorSuccess, colorWarning } =
|
||||
preference.theme;
|
||||
const { colorDestructive, colorPrimary, colorSuccess, colorWarning } = preference.theme;
|
||||
|
||||
const colorVariables = generatorColorVariables([
|
||||
{ color: colorPrimary, name: 'primary' },
|
||||
{ alias: 'warning', color: colorWarning, name: 'yellow' },
|
||||
{ alias: 'success', color: colorSuccess, name: 'green' },
|
||||
{ alias: 'destructive', color: colorDestructive, name: 'red' },
|
||||
{ color: colorPrimary, name: "primary" },
|
||||
{ alias: "warning", color: colorWarning, name: "yellow" },
|
||||
{ alias: "success", color: colorSuccess, name: "green" },
|
||||
{ alias: "destructive", color: colorDestructive, name: "red" },
|
||||
]);
|
||||
|
||||
// 要设置的 CSS 变量映射
|
||||
const colorMappings = {
|
||||
'--green-500': '--success',
|
||||
'--primary-500': '--primary',
|
||||
'--red-500': '--destructive',
|
||||
'--yellow-500': '--warning',
|
||||
"--green-500": "--success",
|
||||
"--primary-500": "--primary",
|
||||
"--red-500": "--destructive",
|
||||
"--yellow-500": "--warning",
|
||||
};
|
||||
|
||||
// 统一处理颜色变量的更新
|
||||
@@ -106,9 +95,9 @@ function updateMainColorVariables(preference: Preferences) {
|
||||
}
|
||||
|
||||
function isDarkTheme(theme: string) {
|
||||
let dark = theme === 'dark';
|
||||
if (theme === 'auto') {
|
||||
dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
let dark = theme === "dark";
|
||||
if (theme === "auto") {
|
||||
dark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
}
|
||||
return dark;
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ function usePreferences() {
|
||||
if (!enablePreferences) {
|
||||
return {
|
||||
fixed: false,
|
||||
header: false
|
||||
header: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ function usePreferences() {
|
||||
if (preferencesButtonPosition !== "auto") {
|
||||
return {
|
||||
fixed: preferencesButtonPosition === "fixed",
|
||||
header: isHeaderPosition
|
||||
header: isHeaderPosition,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ function usePreferences() {
|
||||
|
||||
return {
|
||||
fixed,
|
||||
header: !fixed
|
||||
header: !fixed,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -219,7 +219,7 @@ function usePreferences() {
|
||||
locale,
|
||||
preferencesButtonPosition,
|
||||
sidebarCollapsed,
|
||||
theme
|
||||
theme,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user