|
@@ -1,7 +1,8 @@
|
|
|
-import GlobalHeader from '@/components/GlobalHeader';
|
|
|
|
|
-import TopNavHeader from '@/components/TopNavHeader';
|
|
|
|
|
-import { DefaultSettings } from '../../config/defaultSettings';
|
|
|
|
|
|
|
+import GlobalHeader, { GlobalHeaderProps } from '@/components/GlobalHeader';
|
|
|
|
|
+import TopNavHeader, { TopNavHeaderProps } from '@/components/TopNavHeader';
|
|
|
|
|
+import { ConnectProps, ConnectState, SettingModelState } from '@/models/connect';
|
|
|
import { Layout, message } from 'antd';
|
|
import { Layout, message } from 'antd';
|
|
|
|
|
+import { ClickParam } from 'antd/es/menu';
|
|
|
import { connect } from 'dva';
|
|
import { connect } from 'dva';
|
|
|
import Animate from 'rc-animate';
|
|
import Animate from 'rc-animate';
|
|
|
import React, { Component } from 'react';
|
|
import React, { Component } from 'react';
|
|
@@ -11,15 +12,12 @@ import styles from './Header.less';
|
|
|
|
|
|
|
|
const { Header } = Layout;
|
|
const { Header } = Layout;
|
|
|
|
|
|
|
|
-export declare type SiderTheme = 'light' | 'dark';
|
|
|
|
|
-
|
|
|
|
|
-interface HeaderViewProps {
|
|
|
|
|
- isMobile: boolean;
|
|
|
|
|
- collapsed: boolean;
|
|
|
|
|
- setting: DefaultSettings;
|
|
|
|
|
- dispatch: (args: any) => void;
|
|
|
|
|
- autoHideHeader: boolean;
|
|
|
|
|
- handleMenuCollapse: (args: boolean) => void;
|
|
|
|
|
|
|
+export interface HeaderViewProps extends ConnectProps, TopNavHeaderProps, GlobalHeaderProps {
|
|
|
|
|
+ isMobile?: boolean;
|
|
|
|
|
+ collapsed?: boolean;
|
|
|
|
|
+ setting?: SettingModelState;
|
|
|
|
|
+ autoHideHeader?: boolean;
|
|
|
|
|
+ handleMenuCollapse?: (collapse: boolean) => void;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
interface HeaderViewState {
|
|
interface HeaderViewState {
|
|
@@ -27,6 +25,10 @@ interface HeaderViewState {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
|
|
|
+ static defaultProps: HeaderViewProps = {
|
|
|
|
|
+ handleMenuCollapse: () => void 0,
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
static getDerivedStateFromProps(props: HeaderViewProps, state: HeaderViewState) {
|
|
static getDerivedStateFromProps(props: HeaderViewProps, state: HeaderViewState) {
|
|
|
if (!props.autoHideHeader && !state.visible) {
|
|
if (!props.autoHideHeader && !state.visible) {
|
|
|
return {
|
|
return {
|
|
@@ -36,14 +38,12 @@ class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- state = {
|
|
|
|
|
|
|
+ ticking: boolean = false;
|
|
|
|
|
+ oldScrollTop: number = 0;
|
|
|
|
|
+ state: HeaderViewState = {
|
|
|
visible: true,
|
|
visible: true,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- ticking: boolean;
|
|
|
|
|
-
|
|
|
|
|
- oldScrollTop: number;
|
|
|
|
|
-
|
|
|
|
|
componentDidMount() {
|
|
componentDidMount() {
|
|
|
document.addEventListener('scroll', this.handScroll, { passive: true });
|
|
document.addEventListener('scroll', this.handScroll, { passive: true });
|
|
|
}
|
|
}
|
|
@@ -54,27 +54,27 @@ class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
|
|
|
|
|
|
getHeadWidth = () => {
|
|
getHeadWidth = () => {
|
|
|
const { isMobile, collapsed, setting } = this.props;
|
|
const { isMobile, collapsed, setting } = this.props;
|
|
|
- const { fixedHeader, layout } = setting;
|
|
|
|
|
|
|
+ const { fixedHeader, layout } = setting!;
|
|
|
if (isMobile || !fixedHeader || layout === 'topmenu') {
|
|
if (isMobile || !fixedHeader || layout === 'topmenu') {
|
|
|
return '100%';
|
|
return '100%';
|
|
|
}
|
|
}
|
|
|
return collapsed ? 'calc(100% - 80px)' : 'calc(100% - 256px)';
|
|
return collapsed ? 'calc(100% - 80px)' : 'calc(100% - 256px)';
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- handleNoticeClear = type => {
|
|
|
|
|
|
|
+ handleNoticeClear = (type: string) => {
|
|
|
|
|
+ const { dispatch } = this.props;
|
|
|
message.success(
|
|
message.success(
|
|
|
`${formatMessage({ id: 'component.noticeIcon.cleared' })} ${formatMessage({
|
|
`${formatMessage({ id: 'component.noticeIcon.cleared' })} ${formatMessage({
|
|
|
id: `component.globalHeader.${type}`,
|
|
id: `component.globalHeader.${type}`,
|
|
|
- })}`
|
|
|
|
|
|
|
+ })}`,
|
|
|
);
|
|
);
|
|
|
- const { dispatch } = this.props;
|
|
|
|
|
- dispatch({
|
|
|
|
|
|
|
+ dispatch!({
|
|
|
type: 'global/clearNotices',
|
|
type: 'global/clearNotices',
|
|
|
payload: type,
|
|
payload: type,
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- handleMenuClick = ({ key }) => {
|
|
|
|
|
|
|
+ handleMenuClick = ({ key }: ClickParam) => {
|
|
|
const { dispatch } = this.props;
|
|
const { dispatch } = this.props;
|
|
|
if (key === 'userCenter') {
|
|
if (key === 'userCenter') {
|
|
|
router.push('/account/center');
|
|
router.push('/account/center');
|
|
@@ -89,16 +89,16 @@ class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
if (key === 'logout') {
|
|
if (key === 'logout') {
|
|
|
- dispatch({
|
|
|
|
|
|
|
+ dispatch!({
|
|
|
type: 'login/logout',
|
|
type: 'login/logout',
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- handleNoticeVisibleChange = visible => {
|
|
|
|
|
|
|
+ handleNoticeVisibleChange = (visible: boolean) => {
|
|
|
if (visible) {
|
|
if (visible) {
|
|
|
const { dispatch } = this.props;
|
|
const { dispatch } = this.props;
|
|
|
- dispatch({
|
|
|
|
|
|
|
+ dispatch!({
|
|
|
type: 'global/fetchNotices',
|
|
type: 'global/fetchNotices',
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
@@ -135,7 +135,7 @@ class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
|
|
|
|
|
|
render() {
|
|
render() {
|
|
|
const { isMobile, handleMenuCollapse, setting } = this.props;
|
|
const { isMobile, handleMenuCollapse, setting } = this.props;
|
|
|
- const { navTheme, layout, fixedHeader } = setting;
|
|
|
|
|
|
|
+ const { navTheme, layout, fixedHeader } = setting!;
|
|
|
const { visible } = this.state;
|
|
const { visible } = this.state;
|
|
|
const isTop = layout === 'topmenu';
|
|
const isTop = layout === 'topmenu';
|
|
|
const width = this.getHeadWidth();
|
|
const width = this.getHeadWidth();
|
|
@@ -143,7 +143,7 @@ class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
|
<Header style={{ padding: 0, width }} className={fixedHeader ? styles.fixedHeader : ''}>
|
|
<Header style={{ padding: 0, width }} className={fixedHeader ? styles.fixedHeader : ''}>
|
|
|
{isTop && !isMobile ? (
|
|
{isTop && !isMobile ? (
|
|
|
<TopNavHeader
|
|
<TopNavHeader
|
|
|
- theme={navTheme as SiderTheme}
|
|
|
|
|
|
|
+ theme={navTheme}
|
|
|
mode="horizontal"
|
|
mode="horizontal"
|
|
|
onCollapse={handleMenuCollapse}
|
|
onCollapse={handleMenuCollapse}
|
|
|
onNoticeClear={this.handleNoticeClear}
|
|
onNoticeClear={this.handleNoticeClear}
|
|
@@ -170,7 +170,7 @@ class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export default connect(({ user, global, setting, loading }) => ({
|
|
|
|
|
|
|
+export default connect(({ user, global, setting, loading }: ConnectState) => ({
|
|
|
currentUser: user.currentUser,
|
|
currentUser: user.currentUser,
|
|
|
collapsed: global.collapsed,
|
|
collapsed: global.collapsed,
|
|
|
fetchingMoreNotices: loading.effects['global/fetchMoreNotices'],
|
|
fetchingMoreNotices: loading.effects['global/fetchMoreNotices'],
|