BasicLayout.tsx 3.46 KB
Newer Older
zombieJ's avatar
zombieJ committed
1 2 3 4 5
/**
 * Ant Design Pro v4 use `@ant-design/pro-layout` to handle Layout.
 * You can view component api by:
 * https://github.com/ant-design/ant-design-pro-layout
 */
6
import { ConnectProps, ConnectState } from '@/models/connect';
7
import ProLayout, {
8
  MenuDataItem,
9
  BasicLayoutProps as ProLayoutProps,
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
10
  Settings,
duanledexianxianxian's avatar
duanledexianxianxian committed
11
  SettingDrawer,
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
12
} from '@ant-design/pro-layout';
13 14
import React, { useState } from 'react';
import Authorized from '@/utils/Authorized';
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
15
import Link from 'umi/link';
16 17 18 19 20 21
import RightContent from '@/components/GlobalHeader/RightContent';
import { connect } from 'dva';
import { formatMessage } from 'umi-plugin-react/locale';
import { isAntDesignPro } from '@/utils/utils';
import logo from '../assets/logo.svg';

22
export interface BasicLayoutProps extends ProLayoutProps, ConnectProps {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
23 24 25
  breadcrumbNameMap: {
    [path: string]: MenuDataItem;
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
26
  settings: Settings;
27
}
28
export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
29 30 31
  breadcrumbNameMap: {
    [path: string]: MenuDataItem;
  };
32
};
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
33
/**
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
34
 * use Authorized check all menu item
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
35
 */
duanledexianxianxian's avatar
duanledexianxianxian committed
36

37 38
const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
  menuList.map(item => {
duanledexianxianxian's avatar
duanledexianxianxian committed
39
    const localItem = { ...item, children: item.children ? menuDataRender(item.children) : [] };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
40 41 42
    return Authorized.check(item.authority, localItem, null) as MenuDataItem;
  });

ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
43
const footerRender: BasicLayoutProps['footerRender'] = (_, defaultDom) => {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
44
  if (!isAntDesignPro()) {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
45 46
    return defaultDom;
  }
duanledexianxianxian's avatar
duanledexianxianxian committed
47

ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
48 49 50 51 52
  return (
    <>
      {defaultDom}
      <div
        style={{
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
53
          padding: '0px 24px 24px',
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
54
          textAlign: 'center',
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
55 56
        }}
      >
57
        <a href="https://www.netlify.com" target="_blank" rel="noopener noreferrer">
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
58
          <img
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
59
            src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg"
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
60
            width="82px"
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
61 62 63 64 65 66 67 68
            alt="netlify logo"
          />
        </a>
      </div>
    </>
  );
};

何乐's avatar
何乐 committed
69
const BasicLayout: React.FC<BasicLayoutProps> = props => {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
70
  const { dispatch, children, settings } = props;
何乐's avatar
何乐 committed
71 72 73
  /**
   * constructor
   */
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
74

75
  useState(() => {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
76 77 78 79 80 81 82 83
    if (dispatch) {
      dispatch({
        type: 'user/fetchCurrent',
      });
      dispatch({
        type: 'settings/getSetting',
      });
    }
84
  });
何乐's avatar
何乐 committed
85 86 87
  /**
   * init variables
   */
duanledexianxianxian's avatar
duanledexianxianxian committed
88

89
  const handleMenuCollapse = (payload: boolean): void =>
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
90 91
    dispatch &&
    dispatch({
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
92 93 94 95
      type: 'global/changeLayoutCollapsed',
      payload,
    });

96
  return (
duanledexianxianxian's avatar
duanledexianxianxian committed
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
    <>
      <ProLayout
        logo={logo}
        onCollapse={handleMenuCollapse}
        menuItemRender={(menuItemProps, defaultDom) => (
          <Link to={menuItemProps.path}>{defaultDom}</Link>
        )}
        breadcrumbRender={(routers = []) => [
          {
            path: '/',
            breadcrumbName: formatMessage({
              id: 'menu.home',
              defaultMessage: 'Home',
            }),
          },
          ...routers,
        ]}
        footerRender={footerRender}
        menuDataRender={menuDataRender}
        formatMessage={formatMessage}
        rightContentRender={rightProps => <RightContent {...rightProps} />}
        {...props}
        {...settings}
      >
        {children}
      </ProLayout>
      <SettingDrawer
        settings={settings}
        onSettingChange={config =>
          dispatch({
            type: 'settings/changeSetting',
            payload: config,
          })
        }
      />
    </>
133 134 135
  );
};

ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
136
export default connect(({ global, settings }: ConnectState) => ({
137
  collapsed: global.collapsed,
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
138
  settings,
139
}))(BasicLayout);