index.tsx 3.73 KB
Newer Older
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 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<PageHeaderWrapperProps>) => {
  return tabList && tabList.length ? (
    <Tabs
      className={styles.tabs}
      onChange={key => {
        if (onTabChange) {
          onTabChange(key);
        }
      }}
      tabBarExtraContent={tabBarExtraContent}
    >
      {tabList.map(item => (
        <Tabs.TabPane tab={item.tab} key={item.key} />
      ))}
    </Tabs>
  ) : 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<PageHeaderWrapperProps> {
  mergePropsAndChildren = (): PageHeaderWrapperProps => {
    return {
      ...this.props,
    };
  };
  renderPageHeader = () => {
    const {
      children,
      contentWidth,
      wrapperClassName,
      top,
      title,
      content,
      logo,
      extraContent,
      ...restProps
    } = this.mergePropsAndChildren();
    if (!title && !content) {
      return;
    }
    return (
      <PageHeader
        title={
          <Title
            level={4}
            style={{
              marginBottom: 0,
            }}
          >
            {title}
          </Title>
        }
        {...restProps}
        breadcrumb={conversionBreadcrumbList({
          ...restProps,
          home: <FormattedMessage id="menu.home" defaultMessage="Home" />,
        })}
        className={styles.pageHeader}
        footer={renderFooter(restProps)}
      >
        <div className={styles.detail}>
          {logo && <div className={styles.logo}>{logo}</div>}
          <div className={styles.main}>
            <div className={styles.row}>
              {content && <div className={styles.content}>{content}</div>}
              {extraContent && <div className={styles.extraContent}>{extraContent}</div>}
            </div>
          </div>
        </div>
      </PageHeader>
    );
  };
  render() {
    const { children, top } = this.mergePropsAndChildren();
    return (
      <div style={{ margin: '-24px -24px 0' }} className={classNames(classNames, styles.main)}>
        {top}
        {this.renderPageHeader()}
        {children ? (
          <div className={styles['children-content']}>
            <GridContent>{children}</GridContent>
          </div>
        ) : null}
      </div>
    );
  }
}

export default connect(({ setting }: ConnectState) => ({
  contentWidth: setting.contentWidth,
}))(PageHeaderWrapper);