diff --git a/config/routes.ts b/config/routes.ts
index 4545fe74..ab67058e 100644
--- a/config/routes.ts
+++ b/config/routes.ts
@@ -38,7 +38,7 @@ export default [
},
{
name: '404',
- component: './404',
+ component: './exception/404',
path: '/user/*',
},
],
@@ -292,7 +292,7 @@ export default [
},
{
name: '404',
- component: './404',
+ component: './exception/404',
path: '/*',
},
];
diff --git a/src/app.tsx b/src/app.tsx
index 50db4597..17bf9ecb 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -10,7 +10,13 @@ import React from 'react';
// Initialize dayjs plugins globally
dayjs.extend(relativeTime);
-import { AvatarDropdown, Footer } from '@/components';
+import {
+ AvatarDropdown,
+ DocLink,
+ Footer,
+ LangDropdown,
+ VersionDropdown,
+} from '@/components';
import { currentUser as queryCurrentUser } from '@/services/ant-design-pro/api';
import defaultSettings from '../config/defaultSettings';
import { errorConfig } from './requestErrorConfig';
@@ -80,6 +86,11 @@ export const layout: RunTimeLayoutConfig = ({
}
return dom;
},
+ actionsRender: () => [
+ ,
+ ,
+ ,
+ ],
avatarProps: {
src: initialState?.currentUser?.avatar,
title: 'ProUser',
diff --git a/src/components/RightContent/AvatarDropdown.tsx b/src/components/RightContent/AvatarDropdown.tsx
index b66897a8..fbc587e3 100644
--- a/src/components/RightContent/AvatarDropdown.tsx
+++ b/src/components/RightContent/AvatarDropdown.tsx
@@ -1,20 +1,9 @@
import {
- BookOutlined,
- CheckOutlined,
- GlobalOutlined,
- HistoryOutlined,
LogoutOutlined,
SettingOutlined,
SkinOutlined,
} from '@ant-design/icons';
-import {
- getAllLocales,
- getLocale,
- history,
- setLocale,
- useIntl,
- useModel,
-} from '@umijs/max';
+import { history, useModel } from '@umijs/max';
import type { MenuProps } from 'antd';
import { Spin } from 'antd';
import React from 'react';
@@ -26,14 +15,6 @@ export type GlobalHeaderRightProps = {
children?: React.ReactNode;
};
-const localeLabelMap: Record = {
- 'zh-CN': { emoji: '🇨🇳', label: '简体中文' },
- 'zh-TW': { emoji: '🇭🇰', label: '繁体中文' },
- 'en-US': { emoji: '🇺🇸', label: 'English' },
-};
-
-const supportLocaleKeys = Object.keys(localeLabelMap);
-
export const AvatarDropdown: React.FC = ({
children,
}) => {
@@ -53,7 +34,6 @@ export const AvatarDropdown: React.FC = ({
}
};
const { initialState, setInitialState } = useModel('@@initialState');
- const intl = useIntl();
const onMenuClick: MenuProps['onClick'] = (event) => {
const { key } = event;
@@ -68,19 +48,6 @@ export const AvatarDropdown: React.FC = ({
setInitialState((s) => ({ ...s, settingDrawerOpen: true }));
return;
}
- if (key === 'doc') {
- history.push('/welcome');
- return;
- }
- if (key.startsWith('lang-')) {
- setLocale(key.replace('lang-', ''), false);
- return;
- }
- if (key.startsWith('version-')) {
- const url = key.replace('version-', '');
- window.open(url, '_blank', 'noopener,noreferrer');
- return;
- }
history.push(`/account/${key}`);
};
@@ -94,12 +61,6 @@ export const AvatarDropdown: React.FC = ({
return ;
}
- const allLocales = getAllLocales();
- const currentLocale = getLocale();
- const supportLocales = allLocales.filter((l) =>
- supportLocaleKeys.includes(l),
- );
-
const menuItems: MenuProps['items'] = [
{
key: 'settings',
@@ -111,55 +72,6 @@ export const AvatarDropdown: React.FC = ({
icon: ,
label: '主题设置',
},
- {
- key: 'doc',
- icon: ,
- label: '使用文档',
- },
- {
- key: 'version',
- icon: ,
- label: intl.formatMessage({
- id: 'component.globalHeader.historyVersion',
- }),
- children: [
- {
- key: 'version-https://v5.pro.ant.design',
- label: 'v5',
- },
- {
- key: 'version-https://v4.pro.ant.design',
- label: 'v4',
- },
- {
- key: 'version-https://v2.pro.ant.design',
- label: 'v2',
- },
- {
- key: 'version-https://v1.pro.ant.design',
- label: 'v1',
- },
- ],
- },
- ...(supportLocales.length > 1
- ? [
- {
- key: 'lang',
- icon: ,
- label: localeLabelMap[currentLocale]?.label ?? currentLocale,
- children: supportLocales.map((locale) => ({
- key: `lang-${locale}`,
- icon:
- locale === currentLocale ? (
-
- ) : (
-
- ),
- label: `${localeLabelMap[locale]?.emoji ?? ''} ${localeLabelMap[locale]?.label ?? locale}`,
- })),
- },
- ]
- : []),
{
type: 'divider' as const,
},
diff --git a/src/components/RightContent/index.tsx b/src/components/RightContent/index.tsx
index 5430bbfa..ea0b19f2 100644
--- a/src/components/RightContent/index.tsx
+++ b/src/components/RightContent/index.tsx
@@ -1,20 +1,130 @@
-import { QuestionCircleOutlined } from '@ant-design/icons';
-import { history, SelectLang as UmiSelectLang } from '@umijs/max';
+import {
+ BookOutlined,
+ CheckOutlined,
+ ForkOutlined,
+ GlobalOutlined,
+} from '@ant-design/icons';
+import { getAllLocales, getLocale, history, setLocale } from '@umijs/max';
+import type { MenuProps } from 'antd';
+import { Button, Tooltip } from 'antd';
+import { createStyles } from 'antd-style';
+import React, { useMemo } from 'react';
+import HeaderDropdown from '../HeaderDropdown';
-export type SiderTheme = 'light' | 'dark';
+export const localeLabelMap: Record =
+ {
+ 'zh-CN': { emoji: '🇨🇳', label: '简体中文' },
+ 'zh-TW': { emoji: '🇭🇰', label: '繁體中文' },
+ 'en-US': { emoji: '🇺🇸', label: 'English' },
+ 'ja-JP': { emoji: '🇯🇵', label: '日本語' },
+ 'pt-BR': { emoji: '🇧🇷', label: 'Português' },
+ 'id-ID': { emoji: '🇮🇩', label: 'Bahasa Indonesia' },
+ 'fa-IR': { emoji: '🇮🇷', label: 'فارسی' },
+ 'bn-BD': { emoji: '🇧🇩', label: 'বাংলা' },
+ };
-export const SelectLang: React.FC = () => {
- return ;
+const useStyles = createStyles(({ token, css }) => ({
+ action: css`
+ display: inline-flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ height: 36px !important;
+ min-width: 36px;
+ padding-inline: 8px !important;
+ padding-block: 0 !important;
+ border-radius: ${token.borderRadius}px !important;
+ `,
+}));
+
+export const DocLink: React.FC = () => {
+ const { styles } = useStyles();
+ return (
+
+ }
+ aria-label="使用文档"
+ onClick={() => {
+ history.push('/welcome');
+ }}
+ />
+
+ );
+};
+
+const versionItems: MenuProps['items'] = [
+ { key: 'https://v5.pro.ant.design', label: 'v5' },
+ { key: 'https://v4.pro.ant.design', label: 'v4' },
+ { key: 'https://v2.pro.ant.design', label: 'v2' },
+ { key: 'https://v1.pro.ant.design', label: 'v1' },
+];
+
+const onVersionClick: MenuProps['onClick'] = ({ key }) => {
+ window.open(key, '_blank', 'noopener,noreferrer');
+};
+
+export const VersionDropdown: React.FC = () => {
+ const { styles } = useStyles();
+ return (
+
+
+
+ );
};
-export const Question: React.FC = () => {
+export const LangDropdown: React.FC = () => {
+ const { styles } = useStyles();
+ const allLocales = useMemo(() => getAllLocales(), []);
+ const currentLocale = getLocale();
+ const supportLocales = allLocales.filter((l) => l in localeLabelMap);
+
+ if (supportLocales.length <= 1) {
+ return null;
+ }
+
+ const langItems: MenuProps['items'] = supportLocales.map((locale) => ({
+ key: `lang-${locale}`,
+ icon:
+ locale === currentLocale ? (
+
+ ) : (
+
+ ),
+ label: `${localeLabelMap[locale]?.emoji ?? ''} ${localeLabelMap[locale]?.label ?? locale}`,
+ }));
+
+ const onLangClick: MenuProps['onClick'] = ({ key }) => {
+ if (key.startsWith('lang-')) {
+ setLocale(key.replace('lang-', ''), false);
+ }
+ };
+
return (
- {
- history.push('/welcome');
+
-
-
+
+
);
};
diff --git a/src/components/index.ts b/src/components/index.ts
index d6ae96e4..94092f55 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -6,7 +6,7 @@
* 布局组件
*/
import Footer from './Footer';
-import { Question, SelectLang } from './RightContent';
+import { DocLink, LangDropdown, VersionDropdown } from './RightContent';
import { AvatarDropdown } from './RightContent/AvatarDropdown';
/**
@@ -17,4 +17,4 @@ export { default as AvatarList } from './AvatarList';
export { default as StandardFormRow } from './StandardFormRow';
export { default as TagSelect } from './TagSelect';
-export { AvatarDropdown, Footer, Question, SelectLang };
+export { AvatarDropdown, DocLink, Footer, LangDropdown, VersionDropdown };
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
deleted file mode 100644
index 6d4dd981..00000000
--- a/src/pages/404.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Link, useIntl } from '@umijs/max';
-import { Button, Card, Result } from 'antd';
-import React from 'react';
-
-const NoFoundPage: React.FC = () => (
-
-
-
-
- }
- />
-
-);
-
-export default NoFoundPage;
diff --git a/src/pages/exception/404/index.tsx b/src/pages/exception/404/index.tsx
index a1bb7685..ee1e7529 100644
--- a/src/pages/exception/404/index.tsx
+++ b/src/pages/exception/404/index.tsx
@@ -1,17 +1,25 @@
-import { Link } from '@umijs/max';
+import { Link, useIntl } from '@umijs/max';
import { Button, Card, Result } from 'antd';
+import React from 'react';
-export default () => (
-
-
-
-
- }
- />
-
-);
+const Exception404: React.FC = () => {
+ const intl = useIntl();
+ return (
+
+
+
+
+ }
+ />
+
+ );
+};
+
+export default Exception404;