index.tsx 8.33 KB
Newer Older
何乐's avatar
何乐 committed
1
import { ConnectProps, ConnectState, SettingModelState } from '@/models/connect';
陈小聪's avatar
陈小聪 committed
2
import React, { Component } from 'react';
afc163's avatar
afc163 committed
3
import { Select, message, Drawer, List, Switch, Divider, Icon, Button, Alert, Tooltip } from 'antd';
陈小聪's avatar
陈小聪 committed
4
import { formatMessage } from 'umi-plugin-react/locale';
陈帅's avatar
陈帅 committed
5
import { CopyToClipboard } from 'react-copy-to-clipboard';
jim's avatar
jim committed
6
import { connect } from 'dva';
afc163's avatar
afc163 committed
7
import omit from 'omit.js';
jim's avatar
jim committed
8 9
import styles from './index.less';
import ThemeColor from './ThemeColor';
10
import BlockCheckbox from './BlockCheckbox';
jim's avatar
jim committed
11

afc163's avatar
afc163 committed
12
const { Option } = Select;
陈小聪's avatar
陈小聪 committed
13 14 15 16
interface BodyProps {
  title: string;
  style?: React.CSSProperties;
}
afc163's avatar
afc163 committed
17

何乐's avatar
何乐 committed
18 19
const Body: React.FC<BodyProps> = ({ children, title, style }) => (
  <div style={{ ...style, marginBottom: 24 }}>
jim's avatar
jim committed
20 21 22 23 24
    <h3 className={styles.title}>{title}</h3>
    {children}
  </div>
);

何乐's avatar
何乐 committed
25 26 27 28 29
interface SettingItemProps {
  title: React.ReactNode;
  action: React.ReactElement;
  disabled?: boolean;
  disabledReason?: React.ReactNode;
陈小聪's avatar
陈小聪 committed
30 31
}

何乐's avatar
何乐 committed
32 33 34 35 36 37 38 39 40
export interface SettingDrawerProps extends ConnectProps {
  setting?: SettingModelState;
}

export interface SettingDrawerState extends Partial<SettingModelState> {
  collapse: boolean;
}

@connect(({ setting }: ConnectState) => ({ setting }))
陈小聪's avatar
陈小聪 committed
41
class SettingDrawer extends Component<SettingDrawerProps, SettingDrawerState> {
何乐's avatar
何乐 committed
42
  state: SettingDrawerState = {
afc163's avatar
afc163 committed
43 44 45
    collapse: false,
  };

何乐's avatar
何乐 committed
46 47 48
  getLayoutSetting = (): SettingItemProps[] => {
    const { setting } = this.props;
    const { contentWidth, fixedHeader, layout, autoHideHeader, fixSiderbar } = setting!;
jim's avatar
jim committed
49 50
    return [
      {
afc163's avatar
afc163 committed
51
        title: formatMessage({ id: 'app.setting.content-width' }),
afc163's avatar
afc163 committed
52
        action: (
jim's avatar
jim committed
53
          <Select
afc163's avatar
afc163 committed
54
            value={contentWidth}
jim's avatar
jim committed
55
            size="small"
afc163's avatar
afc163 committed
56
            onSelect={value => this.changeSetting('contentWidth', value)}
jim's avatar
jim committed
57 58
            style={{ width: 80 }}
          >
afc163's avatar
afc163 committed
59 60 61 62 63 64
            {layout === 'sidemenu' ? null : (
              <Option value="Fixed">
                {formatMessage({ id: 'app.setting.content-width.fixed' })}
              </Option>
            )}
            <Option value="Fluid">
afc163's avatar
afc163 committed
65
              {formatMessage({ id: 'app.setting.content-width.fluid' })}
afc163's avatar
afc163 committed
66 67 68
            </Option>
          </Select>
        ),
jim's avatar
jim committed
69 70
      },
      {
陈帅's avatar
陈帅 committed
71
        title: formatMessage({ id: 'app.setting.fixedheader' }),
afc163's avatar
afc163 committed
72
        action: (
jim's avatar
jim committed
73 74 75 76
          <Switch
            size="small"
            checked={!!fixedHeader}
            onChange={checked => this.changeSetting('fixedHeader', checked)}
afc163's avatar
afc163 committed
77 78
          />
        ),
jim's avatar
jim committed
79 80
      },
      {
陈帅's avatar
陈帅 committed
81
        title: formatMessage({ id: 'app.setting.hideheader' }),
afc163's avatar
afc163 committed
82
        disabled: !fixedHeader,
afc163's avatar
locales  
afc163 committed
83
        disabledReason: formatMessage({ id: 'app.setting.hideheader.hint' }),
afc163's avatar
afc163 committed
84
        action: (
jim's avatar
jim committed
85 86 87 88
          <Switch
            size="small"
            checked={!!autoHideHeader}
            onChange={checked => this.changeSetting('autoHideHeader', checked)}
afc163's avatar
afc163 committed
89 90
          />
        ),
jim's avatar
jim committed
91 92
      },
      {
陈帅's avatar
陈帅 committed
93
        title: formatMessage({ id: 'app.setting.fixedsidebar' }),
afc163's avatar
afc163 committed
94
        disabled: layout === 'topmenu',
afc163's avatar
locales  
afc163 committed
95
        disabledReason: formatMessage({ id: 'app.setting.fixedsidebar.hint' }),
afc163's avatar
afc163 committed
96
        action: (
jim's avatar
jim committed
97 98 99 100
          <Switch
            size="small"
            checked={!!fixSiderbar}
            onChange={checked => this.changeSetting('fixSiderbar', checked)}
afc163's avatar
afc163 committed
101 102
          />
        ),
jim's avatar
jim committed
103
      },
afc163's avatar
afc163 committed
104
    ];
jim's avatar
jim committed
105
  };
陈帅's avatar
陈帅 committed
106

何乐's avatar
何乐 committed
107
  changeSetting = (key: string, value: any) => {
陈帅's avatar
陈帅 committed
108
    const { setting } = this.props;
何乐's avatar
何乐 committed
109
    const nextState = { ...setting! };
jim's avatar
jim committed
110 111
    nextState[key] = value;
    if (key === 'layout') {
afc163's avatar
afc163 committed
112
      nextState.contentWidth = value === 'topmenu' ? 'Fixed' : 'Fluid';
afc163's avatar
afc163 committed
113 114
    } else if (key === 'fixedHeader' && !value) {
      nextState.autoHideHeader = false;
jim's avatar
jim committed
115
    }
jim's avatar
jim committed
116
    this.setState(nextState, () => {
陈帅's avatar
陈帅 committed
117
      const { dispatch } = this.props;
何乐's avatar
何乐 committed
118
      dispatch!({
jim's avatar
jim committed
119 120 121 122 123
        type: 'setting/changeSetting',
        payload: this.state,
      });
    });
  };
陈帅's avatar
陈帅 committed
124

jim's avatar
jim committed
125
  togglerContent = () => {
afc163's avatar
afc163 committed
126 127
    const { collapse } = this.state;
    this.setState({ collapse: !collapse });
jim's avatar
jim committed
128
  };
陈帅's avatar
陈帅 committed
129

何乐's avatar
何乐 committed
130
  renderLayoutSettingItem = (item: SettingItemProps) => {
afc163's avatar
afc163 committed
131 132 133 134 135 136
    const action = React.cloneElement(item.action, {
      disabled: item.disabled,
    });
    return (
      <Tooltip title={item.disabled ? item.disabledReason : ''} placement="left">
        <List.Item actions={[action]}>
陈小聪's avatar
陈小聪 committed
137
          <span style={{ opacity: item.disabled ? 0.5 : 1 }}>{item.title}</span>
afc163's avatar
afc163 committed
138 139 140 141 142
        </List.Item>
      </Tooltip>
    );
  };

jim's avatar
jim committed
143
  render() {
陈帅's avatar
陈帅 committed
144
    const { setting } = this.props;
何乐's avatar
何乐 committed
145
    const { navTheme, primaryColor, layout, colorWeak } = setting!;
afc163's avatar
afc163 committed
146
    const { collapse } = this.state;
jim's avatar
jim committed
147
    return (
陈帅's avatar
陈帅 committed
148 149
      <Drawer
        visible={collapse}
150
        width={300}
陈帅's avatar
陈帅 committed
151
        onClose={this.togglerContent}
陈帅's avatar
陈帅 committed
152
        placement="right"
陈帅's avatar
陈帅 committed
153
        handler={
Yu's avatar
Yu committed
154
          <div className={styles.handle} onClick={this.togglerContent}>
afc163's avatar
afc163 committed
155 156 157 158 159 160 161
            <Icon
              type={collapse ? 'close' : 'setting'}
              style={{
                color: '#fff',
                fontSize: 20,
              }}
            />
陈帅's avatar
陈帅 committed
162 163
          </div>
        }
陈帅's avatar
陈帅 committed
164 165 166 167 168
        style={{
          zIndex: 999,
        }}
      >
        <div className={styles.content}>
陈帅's avatar
陈帅 committed
169
          <Body title={formatMessage({ id: 'app.setting.pagestyle' })}>
170
            <BlockCheckbox
陈帅's avatar
陈帅 committed
171 172 173 174
              list={[
                {
                  key: 'dark',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg',
afc163's avatar
afc163 committed
175
                  title: formatMessage({ id: 'app.setting.pagestyle.dark' }),
陈帅's avatar
陈帅 committed
176 177 178 179
                },
                {
                  key: 'light',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg',
afc163's avatar
afc163 committed
180
                  title: formatMessage({ id: 'app.setting.pagestyle.light' }),
陈帅's avatar
陈帅 committed
181 182
                },
              ]}
afc163's avatar
afc163 committed
183 184
              value={navTheme}
              onChange={value => this.changeSetting('navTheme', value)}
陈帅's avatar
陈帅 committed
185 186
            />
          </Body>
jim's avatar
jim committed
187

188
          <ThemeColor
陈帅's avatar
陈帅 committed
189
            title={formatMessage({ id: 'app.setting.themecolor' })}
afc163's avatar
afc163 committed
190 191
            value={primaryColor}
            onChange={color => this.changeSetting('primaryColor', color)}
192
          />
jim's avatar
jim committed
193

陈帅's avatar
陈帅 committed
194
          <Divider />
jim's avatar
jim committed
195

陈帅's avatar
陈帅 committed
196
          <Body title={formatMessage({ id: 'app.setting.navigationmode' })}>
197
            <BlockCheckbox
陈帅's avatar
陈帅 committed
198 199 200 201
              list={[
                {
                  key: 'sidemenu',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg',
afc163's avatar
afc163 committed
202
                  title: formatMessage({ id: 'app.setting.sidemenu' }),
陈帅's avatar
陈帅 committed
203 204 205 206
                },
                {
                  key: 'topmenu',
                  url: 'https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg',
afc163's avatar
afc163 committed
207
                  title: formatMessage({ id: 'app.setting.topmenu' }),
陈帅's avatar
陈帅 committed
208 209 210 211
                },
              ]}
              value={layout}
              onChange={value => this.changeSetting('layout', value)}
jim's avatar
jim committed
212
            />
陈帅's avatar
陈帅 committed
213
          </Body>
jim's avatar
jim committed
214

陈帅's avatar
陈帅 committed
215 216
          <List
            split={false}
afc163's avatar
afc163 committed
217
            dataSource={this.getLayoutSetting()}
afc163's avatar
afc163 committed
218
            renderItem={this.renderLayoutSettingItem}
陈帅's avatar
陈帅 committed
219
          />
jim's avatar
jim committed
220

陈帅's avatar
陈帅 committed
221 222
          <Divider />

陈帅's avatar
陈帅 committed
223
          <Body title={formatMessage({ id: 'app.setting.othersettings' })}>
224 225 226 227 228 229 230 231 232 233 234 235 236 237
            <List
              split={false}
              renderItem={this.renderLayoutSettingItem}
              dataSource={[
                {
                  title: formatMessage({ id: 'app.setting.weakmode' }),
                  action: (
                    <Switch
                      size="small"
                      checked={!!colorWeak}
                      onChange={checked => this.changeSetting('colorWeak', checked)}
                    />
                  ),
                },
陈帅's avatar
陈帅 committed
238
              ]}
239
            />
陈帅's avatar
陈帅 committed
240
          </Body>
陈帅's avatar
陈帅 committed
241 242
          <Divider />
          <CopyToClipboard
afc163's avatar
afc163 committed
243
            text={JSON.stringify(omit(setting, ['colorWeak']), null, 2)}
陈帅's avatar
陈帅 committed
244
            onCopy={() => message.success(formatMessage({ id: 'app.setting.copyinfo' }))}
陈帅's avatar
陈帅 committed
245
          >
afc163's avatar
afc163 committed
246
            <Button block icon="copy">
陈帅's avatar
陈帅 committed
247
              {formatMessage({ id: 'app.setting.copy' })}
陈帅's avatar
陈帅 committed
248 249
            </Button>
          </CopyToClipboard>
afc163's avatar
afc163 committed
250 251 252
          <Alert
            type="warning"
            className={styles.productionHint}
afc163's avatar
afc163 committed
253 254 255 256 257 258 259 260 261 262 263 264
            message={
              <div>
                {formatMessage({ id: 'app.setting.production.hint' })}{' '}
                <a
                  href="https://u.ant.design/pro-v2-default-settings"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  src/defaultSettings.js
                </a>
              </div>
            }
afc163's avatar
afc163 committed
265
          />
陈帅's avatar
陈帅 committed
266
        </div>
陈帅's avatar
陈帅 committed
267
      </Drawer>
jim's avatar
jim committed
268 269 270 271
    );
  }
}

272
export default SettingDrawer;