diff --git a/src/components/PageHeaderWrapper/GridContent.js b/src/components/PageHeaderWrapper/GridContent.tsx
similarity index 56%
rename from src/components/PageHeaderWrapper/GridContent.js
rename to src/components/PageHeaderWrapper/GridContent.tsx
index fee6a9318c263249ffd3aaf67fc656e471aa8984..88e0284b197bf9efae2fddeae2565ff07ac6430a 100644
--- a/src/components/PageHeaderWrapper/GridContent.js
+++ b/src/components/PageHeaderWrapper/GridContent.tsx
@@ -1,8 +1,15 @@
import React from 'react';
import { connect } from 'dva';
import styles from './GridContent.less';
+import ConnectState from '@/models/connect';
+import { ContentWidth } from 'config/defaultSettings';
-const GridContent = props => {
+interface GridContentProps {
+ contentWidth: ContentWidth;
+ children: React.ReactNode;
+}
+
+const GridContent = (props: GridContentProps) => {
const { contentWidth, children } = props;
let className = `${styles.main}`;
if (contentWidth === 'Fixed') {
@@ -11,6 +18,6 @@ const GridContent = props => {
return
{children}
;
};
-export default connect(({ setting }) => ({
+export default connect(({ setting }: ConnectState) => ({
contentWidth: setting.contentWidth,
}))(GridContent);
diff --git a/src/components/PageHeaderWrapper/breadcrumb.js b/src/components/PageHeaderWrapper/breadcrumb.js
deleted file mode 100644
index 02fe66fd26530f68bd99e6a3c863f384a82e611d..0000000000000000000000000000000000000000
--- a/src/components/PageHeaderWrapper/breadcrumb.js
+++ /dev/null
@@ -1,116 +0,0 @@
-import React from 'react';
-import pathToRegexp from 'path-to-regexp';
-import Link from 'umi/link';
-import { FormattedMessage } from 'umi-plugin-react/locale';
-import { urlToList } from '../_utils/pathTools';
-
-// 渲染Breadcrumb 子节点
-// Render the Breadcrumb child node
-const itemRender = (route, params, routes, paths) => {
- const last = routes.indexOf(route) === routes.length - 1;
- return last || !route.component ? (
- {route.breadcrumbName}
- ) : (
- {route.breadcrumbName}
- );
-};
-
-const renderItemLocal = item => {
- if (item.locale) {
- return ;
- }
- return item.name;
-};
-
-export const getBreadcrumb = (breadcrumbNameMap, url) => {
- let breadcrumb = breadcrumbNameMap[url];
- if (!breadcrumb) {
- Object.keys(breadcrumbNameMap).forEach(item => {
- if (pathToRegexp(item).test(url)) {
- breadcrumb = breadcrumbNameMap[item];
- }
- });
- }
- return breadcrumb || {};
-};
-
-export const getBreadcrumbProps = props => {
- const { routes, params, location, breadcrumbNameMap } = props;
- return {
- routes,
- params,
- routerLocation: location,
- breadcrumbNameMap,
- };
-};
-
-// Generated according to props
-const conversionFromProps = props => {
- const { breadcrumbList } = props;
- return breadcrumbList.map(item => {
- const { title, href } = item;
- return {
- path: href,
- breadcrumbName: title,
- };
- });
-};
-
-const conversionFromLocation = (routerLocation, breadcrumbNameMap, props) => {
- const { home } = props;
- // Convert the url to an array
- const pathSnippets = urlToList(routerLocation.pathname);
- // Loop data mosaic routing
- const extraBreadcrumbItems = pathSnippets.map(url => {
- const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
- if (currentBreadcrumb.inherited) {
- return null;
- }
- const name = renderItemLocal(currentBreadcrumb);
- const { hideInBreadcrumb } = currentBreadcrumb;
- return name && !hideInBreadcrumb
- ? {
- path: url,
- breadcrumbName: name,
- }
- : null;
- });
- // Add home breadcrumbs to your head if defined
- if (home) {
- extraBreadcrumbItems.unshift({
- path: '/',
- breadcrumbName: home,
- });
- }
- return extraBreadcrumbItems;
-};
-
-/**
- * 将参数转化为面包屑
- * Convert parameters into breadcrumbs
- */
-export const conversionBreadcrumbList = props => {
- const { breadcrumbList } = props;
- const { routes, params, routerLocation, breadcrumbNameMap } = getBreadcrumbProps(props);
- if (breadcrumbList && breadcrumbList.length) {
- return conversionFromProps();
- }
- // 如果传入 routes 和 params 属性
- // If pass routes and params attributes
- if (routes && params) {
- return {
- routes: routes.filter(route => route.breadcrumbName),
- params,
- itemRender,
- };
- }
- // 根据 location 生成 面包屑
- // Generate breadcrumbs based on location
- if (routerLocation && routerLocation.pathname) {
- return {
- routes: conversionFromLocation(routerLocation, breadcrumbNameMap, props),
- itemRender,
- };
- }
- return {};
-};
diff --git a/src/components/PageHeaderWrapper/breadcrumb.tsx b/src/components/PageHeaderWrapper/breadcrumb.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fcaa3b55c9bace56578d9b38ed9bf54fd12d068a
--- /dev/null
+++ b/src/components/PageHeaderWrapper/breadcrumb.tsx
@@ -0,0 +1,135 @@
+import React from 'react';
+import pathToRegexp from 'path-to-regexp';
+import Link from 'umi/link';
+import { FormattedMessage } from 'umi-plugin-react/locale';
+import { urlToList } from '../_utils/pathTools';
+import { PageHeaderWrapperProps } from './';
+import { MenuDataItem } from '../SiderMenu';
+import { BreadcrumbProps as AntdBreadcrumbProps } from 'antd/lib/breadcrumb';
+
+type BreadcrumbProps = PageHeaderWrapperProps;
+
+// 渲染Breadcrumb 子节点
+// Render the Breadcrumb child node
+const itemRender: AntdBreadcrumbProps['itemRender'] = (route, params, routes, paths) => {
+ const last = routes.indexOf(route) === routes.length - 1;
+ return last || !route.component ? (
+ {route.breadcrumbName}
+ ) : (
+ {route.breadcrumbName}
+ );
+};
+
+const renderItemLocal = (item: MenuDataItem): React.ReactNode => {
+ if (item.locale) {
+ return ;
+ }
+ return item.name;
+};
+
+export const getBreadcrumb = (
+ breadcrumbNameMap: PageHeaderWrapperProps['breadcrumbNameMap'],
+ url: string,
+): MenuDataItem => {
+ if (!breadcrumbNameMap) {
+ return {
+ path: '',
+ };
+ }
+ let breadcrumb = breadcrumbNameMap[url];
+ if (!breadcrumb) {
+ Object.keys(breadcrumbNameMap).forEach(item => {
+ if (pathToRegexp(item).test(url)) {
+ breadcrumb = breadcrumbNameMap[item];
+ }
+ });
+ }
+ return breadcrumb || { path: '' };
+};
+
+export const getBreadcrumbProps = (props: BreadcrumbProps): PageHeaderWrapperProps => {
+ const { location, breadcrumbNameMap } = props;
+ return {
+ location,
+ breadcrumbNameMap,
+ };
+};
+
+// Generated according to props
+const conversionFromProps = (props: BreadcrumbProps): AntdBreadcrumbProps['routes'] => {
+ const { breadcrumbList = [] } = props;
+ return breadcrumbList
+ .map(item => {
+ const { title, href } = item;
+ return {
+ path: href,
+ breadcrumbName: title,
+ };
+ })
+ .filter(item => item.path);
+};
+
+const conversionFromLocation = (
+ routerLocation: PageHeaderWrapperProps['location'],
+ breadcrumbNameMap: PageHeaderWrapperProps['breadcrumbNameMap'],
+ props: BreadcrumbProps,
+): AntdBreadcrumbProps['routes'] => {
+ if (!routerLocation) {
+ return [];
+ }
+ const { home } = props;
+ // Convert the url to an array
+ const pathSnippets = urlToList(routerLocation.pathname);
+ // Loop data mosaic routing
+ const extraBreadcrumbItems: AntdBreadcrumbProps['routes'] = pathSnippets
+ .map(url => {
+ const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
+ if (currentBreadcrumb.inherited) {
+ return { path: '', breadcrumbName: '' };
+ }
+ const name = renderItemLocal(currentBreadcrumb);
+ const { hideInBreadcrumb } = currentBreadcrumb;
+ return name && !hideInBreadcrumb
+ ? {
+ path: url,
+ breadcrumbName: name,
+ }
+ : { path: '', breadcrumbName: '' };
+ })
+ .filter(item => item && item.path);
+ // Add home breadcrumbs to your head if defined
+ if (home) {
+ extraBreadcrumbItems.unshift({
+ path: '/',
+ breadcrumbName: home,
+ });
+ }
+ return extraBreadcrumbItems;
+};
+
+/**
+ * 将参数转化为面包屑
+ * Convert parameters into breadcrumbs
+ */
+export const conversionBreadcrumbList = (props: BreadcrumbProps): AntdBreadcrumbProps => {
+ const { breadcrumbList } = props;
+ const { location, breadcrumbNameMap } = getBreadcrumbProps(props);
+ if (breadcrumbList && breadcrumbList.length) {
+ return {
+ routes: conversionFromProps(props),
+ itemRender,
+ };
+ }
+
+ // 根据 location 生成 面包屑
+ // Generate breadcrumbs based on location
+ if (location && location.pathname) {
+ return {
+ routes: conversionFromLocation(location, breadcrumbNameMap, props),
+ itemRender,
+ };
+ }
+ return {
+ routes: [],
+ };
+};
diff --git a/src/components/PageHeaderWrapper/index.js b/src/components/PageHeaderWrapper/index.js
deleted file mode 100644
index 7a766834c4ac39cd3628409d45fe3cd09bff1fe7..0000000000000000000000000000000000000000
--- a/src/components/PageHeaderWrapper/index.js
+++ /dev/null
@@ -1,104 +0,0 @@
-import React from 'react';
-import { FormattedMessage } from 'umi-plugin-react/locale';
-import Link from 'umi/link';
-import { PageHeader, Tabs, Typography } from 'antd';
-import { connect } from 'dva';
-import classNames from 'classnames';
-import GridContent from './GridContent';
-import styles from './index.less';
-import MenuContext from '@/layouts/MenuContext';
-import { conversionBreadcrumbList } from './breadcrumb';
-
-const { Title } = Typography;
-
-/**
- * render Footer tabList
- * In order to be compatible with the old version of the PageHeader
- * basically all the functions are implemented.
- */
-const renderFooter = ({ tabList, activeKeyProps, onTabChange, tabBarExtraContent }) => {
- return tabList && tabList.length ? (
- {
- if (onTabChange) {
- onTabChange(key);
- }
- }}
- tabBarExtraContent={tabBarExtraContent}
- >
- {tabList.map(item => (
-
- ))}
-
- ) : null;
-};
-
-const PageHeaderWrapper = ({
- children,
- contentWidth,
- wrapperClassName,
- top,
- title,
- content,
- logo,
- extraContent,
- ...restProps
-}) => {
- return (
-
- {top}
- {title && content && (
-
- {value => {
- return (
-
- {title}
-
- }
- key="pageheader"
- {...restProps}
- breadcrumb={conversionBreadcrumbList({
- ...value,
- ...restProps,
- home: ,
- })}
- className={styles.pageHeader}
- linkElement={Link}
- footer={renderFooter(restProps)}
- >
-
- {logo &&
{logo}
}
-
-
- {content &&
{content}
}
- {extraContent &&
{extraContent}
}
-
-
-
-
- );
- }}
-
- )}
- {children ? (
-
- {children}
-
- ) : null}
-
- );
-};
-
-export default connect(({ setting }) => ({
- contentWidth: setting.contentWidth,
-}))(PageHeaderWrapper);
diff --git a/src/components/PageHeaderWrapper/index.tsx b/src/components/PageHeaderWrapper/index.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..40b9c88f68953d4de4a4a1f18b310f466d6dee01
--- /dev/null
+++ b/src/components/PageHeaderWrapper/index.tsx
@@ -0,0 +1,137 @@
+import React from 'react';
+import { FormattedMessage } from 'umi-plugin-react/locale';
+import { PageHeader, Tabs, Typography } from 'antd';
+import { connect } from 'dva';
+import classNames from 'classnames';
+import GridContent from './GridContent';
+import ConnectState from '@/models/connect';
+import { ContentWidth } from 'config/defaultSettings';
+import styles from './index.less';
+import { conversionBreadcrumbList } from './breadcrumb';
+import { MenuDataItem } from '../SiderMenu';
+import * as H from 'history';
+
+const { Title } = Typography;
+
+/**
+ * render Footer tabList
+ * In order to be compatible with the old version of the PageHeader
+ * basically all the functions are implemented.
+ */
+const renderFooter = ({
+ tabList,
+ onTabChange,
+ tabBarExtraContent,
+}: Partial) => {
+ return tabList && tabList.length ? (
+ {
+ if (onTabChange) {
+ onTabChange(key);
+ }
+ }}
+ tabBarExtraContent={tabBarExtraContent}
+ >
+ {tabList.map(item => (
+
+ ))}
+
+ ) : null;
+};
+
+export interface PageHeaderWrapperProps {
+ title?: React.ReactNode | string | number;
+ logo?: React.ReactNode | string;
+ action?: React.ReactNode | string;
+ content?: React.ReactNode;
+ extraContent?: React.ReactNode;
+ breadcrumbList?: Array<{ title: string | number; href: string }>;
+ tabList?: Array<{ key: string; tab: React.ReactNode }>;
+ tabActiveKey?: string;
+ onTabChange?: (key: string) => void;
+ tabBarExtraContent?: React.ReactNode;
+ style?: React.CSSProperties;
+ home?: React.ReactNode;
+ wide?: boolean;
+ contentWidth?: ContentWidth;
+ className?: string;
+ children?: React.ReactNode;
+ wrapperClassName?: string;
+ top?: React.ReactNode;
+ location?: H.Location;
+ breadcrumbNameMap?: { [path: string]: MenuDataItem };
+}
+
+class PageHeaderWrapper extends React.Component {
+ mergePropsAndChildren = (): PageHeaderWrapperProps => {
+ return {
+ ...this.props,
+ };
+ };
+ renderPageHeader = () => {
+ const {
+ children,
+ contentWidth,
+ wrapperClassName,
+ top,
+ title,
+ content,
+ logo,
+ extraContent,
+ ...restProps
+ } = this.mergePropsAndChildren();
+ if (!title && !content) {
+ return;
+ }
+ return (
+
+ {title}
+
+ }
+ {...restProps}
+ breadcrumb={conversionBreadcrumbList({
+ ...restProps,
+ home: ,
+ })}
+ className={styles.pageHeader}
+ footer={renderFooter(restProps)}
+ >
+
+ {logo &&
{logo}
}
+
+
+ {content &&
{content}
}
+ {extraContent &&
{extraContent}
}
+
+
+
+
+ );
+ };
+ render() {
+ const { children, top } = this.mergePropsAndChildren();
+ return (
+
+ {top}
+ {this.renderPageHeader()}
+ {children ? (
+
+ {children}
+
+ ) : null}
+
+ );
+ }
+}
+
+export default connect(({ setting }: ConnectState) => ({
+ contentWidth: setting.contentWidth,
+}))(PageHeaderWrapper);
diff --git a/src/layouts/BasicLayout.tsx b/src/layouts/BasicLayout.tsx
index 9bbf49e8bd57344648cc1fe7c94d9c087d2df8dd..3b1d9a40a1a95c02ed094d7f1eef094deb4b6239 100644
--- a/src/layouts/BasicLayout.tsx
+++ b/src/layouts/BasicLayout.tsx
@@ -12,7 +12,7 @@ import logo from '../assets/logo.svg';
import styles from './BasicLayout.less';
import Footer from './Footer';
import Header, { HeaderViewProps } from './Header';
-import Context from './MenuContext';
+import PageHeaderWrapper from '@/components/PageHeaderWrapper';
// lazy load SettingDrawer
const SettingDrawer = React.lazy(() => import('@/components/SettingDrawer'));
@@ -90,7 +90,6 @@ const BasicLayout: React.FC = props => {
// unless it is deployed in preview.pro.ant.design as demo
const renderSettingDrawer = () =>
!(process.env.NODE_ENV === 'production' && APP_TYPE !== 'site') && ;
-
const layout = (
{PropsLayout === 'topmenu' && !isMobile ? null : (
@@ -117,7 +116,9 @@ const BasicLayout: React.FC = props => {
{...props}
/>
- {children}
+
+ {children}
+
@@ -127,11 +128,7 @@ const BasicLayout: React.FC = props => {
- {params => (
-
- {layout}
-
- )}
+ {params => {layout}
}
{renderSettingDrawer()}
diff --git a/src/layouts/MenuContext.tsx b/src/layouts/MenuContext.tsx
deleted file mode 100644
index 7c0127fbd6af7f5f721af63bbaa399601119f7bb..0000000000000000000000000000000000000000
--- a/src/layouts/MenuContext.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { createContext } from 'react';
-
-export default createContext({});
diff --git a/src/pages/Welcome.tsx b/src/pages/Welcome.tsx
index 1f78bed0fda63b325a19ff1d092e034e24970532..c9787fa25b2284e18d04085fb3d96f672a9326b3 100644
--- a/src/pages/Welcome.tsx
+++ b/src/pages/Welcome.tsx
@@ -1,6 +1,6 @@
import React from 'react';
-export default () => (
+const Welcome = () => (
想要添加更多页面?请参考{' '}
@@ -9,3 +9,5 @@ export default () => (
。
);
+Welcome.title = '欢迎使用';
+export default Welcome;