初始化 antd-pro
This commit is contained in:
25
admin-web/src/components/SettingDrawer/BlockCheckbox.js
Normal file
25
admin-web/src/components/SettingDrawer/BlockCheckbox.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { Tooltip, Icon } from 'antd';
|
||||
import style from './index.less';
|
||||
|
||||
const BlockChecbox = ({ value, onChange, list }) => (
|
||||
<div className={style.blockChecbox} key={value}>
|
||||
{list.map(item => (
|
||||
<Tooltip title={item.title} key={item.key}>
|
||||
<div className={style.item} onClick={() => onChange(item.key)}>
|
||||
<img src={item.url} alt={item.key} />
|
||||
<div
|
||||
className={style.selectIcon}
|
||||
style={{
|
||||
display: value === item.key ? 'block' : 'none',
|
||||
}}
|
||||
>
|
||||
<Icon type="check" />
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default BlockChecbox;
|
||||
74
admin-web/src/components/SettingDrawer/ThemeColor.js
Normal file
74
admin-web/src/components/SettingDrawer/ThemeColor.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import React from 'react';
|
||||
import { Tooltip, Icon } from 'antd';
|
||||
import { formatMessage } from 'umi/locale';
|
||||
import styles from './ThemeColor.less';
|
||||
|
||||
const Tag = ({ color, check, ...rest }) => (
|
||||
<div
|
||||
{...rest}
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
}}
|
||||
>
|
||||
{check ? <Icon type="check" /> : ''}
|
||||
</div>
|
||||
);
|
||||
|
||||
const ThemeColor = ({ colors, title, value, onChange }) => {
|
||||
let colorList = colors;
|
||||
if (!colors) {
|
||||
colorList = [
|
||||
{
|
||||
key: 'dust',
|
||||
color: '#F5222D',
|
||||
},
|
||||
{
|
||||
key: 'volcano',
|
||||
color: '#FA541C',
|
||||
},
|
||||
{
|
||||
key: 'sunset',
|
||||
color: '#FAAD14',
|
||||
},
|
||||
{
|
||||
key: 'cyan',
|
||||
color: '#13C2C2',
|
||||
},
|
||||
{
|
||||
key: 'green',
|
||||
color: '#52C41A',
|
||||
},
|
||||
{
|
||||
key: 'daybreak',
|
||||
color: '#1890FF',
|
||||
},
|
||||
{
|
||||
key: 'geekblue',
|
||||
color: '#2F54EB',
|
||||
},
|
||||
{
|
||||
key: 'purple',
|
||||
color: '#722ED1',
|
||||
},
|
||||
];
|
||||
}
|
||||
return (
|
||||
<div className={styles.themeColor}>
|
||||
<h3 className={styles.title}>{title}</h3>
|
||||
<div className={styles.content}>
|
||||
{colorList.map(({ key, color }) => (
|
||||
<Tooltip key={color} title={formatMessage({ id: `app.setting.themecolor.${key}` })}>
|
||||
<Tag
|
||||
className={styles.colorBlock}
|
||||
color={color}
|
||||
check={value === color}
|
||||
onClick={() => onChange && onChange(color)}
|
||||
/>
|
||||
</Tooltip>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeColor;
|
||||
21
admin-web/src/components/SettingDrawer/ThemeColor.less
Normal file
21
admin-web/src/components/SettingDrawer/ThemeColor.less
Normal file
@@ -0,0 +1,21 @@
|
||||
.themeColor {
|
||||
margin-top: 24px;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
margin-bottom: 12px;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.colorBlock {
|
||||
float: left;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 8px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
253
admin-web/src/components/SettingDrawer/index.js
Normal file
253
admin-web/src/components/SettingDrawer/index.js
Normal file
@@ -0,0 +1,253 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Select, message, Drawer, List, Switch, Divider, Icon, Button, Alert, Tooltip } from 'antd';
|
||||
import { formatMessage } from 'umi/locale';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
import { connect } from 'dva';
|
||||
import omit from 'omit.js';
|
||||
import styles from './index.less';
|
||||
import ThemeColor from './ThemeColor';
|
||||
import BlockCheckbox from './BlockCheckbox';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
const Body = ({ children, title, style }) => (
|
||||
<div
|
||||
style={{
|
||||
...style,
|
||||
marginBottom: 24,
|
||||
}}
|
||||
>
|
||||
<h3 className={styles.title}>{title}</h3>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
@connect(({ setting }) => ({ setting }))
|
||||
class SettingDrawer extends PureComponent {
|
||||
state = {
|
||||
collapse: false,
|
||||
};
|
||||
|
||||
getLayoutSetting = () => {
|
||||
const {
|
||||
setting: { contentWidth, fixedHeader, layout, autoHideHeader, fixSiderbar },
|
||||
} = this.props;
|
||||
return [
|
||||
{
|
||||
title: formatMessage({ id: 'app.setting.content-width' }),
|
||||
action: (
|
||||
<Select
|
||||
value={contentWidth}
|
||||
size="small"
|
||||
onSelect={value => this.changeSetting('contentWidth', value)}
|
||||
style={{ width: 80 }}
|
||||
>
|
||||
{layout === 'sidemenu' ? null : (
|
||||
<Option value="Fixed">
|
||||
{formatMessage({ id: 'app.setting.content-width.fixed' })}
|
||||
</Option>
|
||||
)}
|
||||
<Option value="Fluid">
|
||||
{formatMessage({ id: 'app.setting.content-width.fluid' })}
|
||||
</Option>
|
||||
</Select>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: formatMessage({ id: 'app.setting.fixedheader' }),
|
||||
action: (
|
||||
<Switch
|
||||
size="small"
|
||||
checked={!!fixedHeader}
|
||||
onChange={checked => this.changeSetting('fixedHeader', checked)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: formatMessage({ id: 'app.setting.hideheader' }),
|
||||
disabled: !fixedHeader,
|
||||
disabledReason: formatMessage({ id: 'app.setting.hideheader.hint' }),
|
||||
action: (
|
||||
<Switch
|
||||
size="small"
|
||||
checked={!!autoHideHeader}
|
||||
onChange={checked => this.changeSetting('autoHideHeader', checked)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: formatMessage({ id: 'app.setting.fixedsidebar' }),
|
||||
disabled: layout === 'topmenu',
|
||||
disabledReason: formatMessage({ id: 'app.setting.fixedsidebar.hint' }),
|
||||
action: (
|
||||
<Switch
|
||||
size="small"
|
||||
checked={!!fixSiderbar}
|
||||
onChange={checked => this.changeSetting('fixSiderbar', checked)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
changeSetting = (key, value) => {
|
||||
const { setting } = this.props;
|
||||
const nextState = { ...setting };
|
||||
nextState[key] = value;
|
||||
if (key === 'layout') {
|
||||
nextState.contentWidth = value === 'topmenu' ? 'Fixed' : 'Fluid';
|
||||
} else if (key === 'fixedHeader' && !value) {
|
||||
nextState.autoHideHeader = false;
|
||||
}
|
||||
this.setState(nextState, () => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: 'setting/changeSetting',
|
||||
payload: this.state,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
togglerContent = () => {
|
||||
const { collapse } = this.state;
|
||||
this.setState({ collapse: !collapse });
|
||||
};
|
||||
|
||||
renderLayoutSettingItem = item => {
|
||||
const action = React.cloneElement(item.action, {
|
||||
disabled: item.disabled,
|
||||
});
|
||||
return (
|
||||
<Tooltip title={item.disabled ? item.disabledReason : ''} placement="left">
|
||||
<List.Item actions={[action]}>
|
||||
<span style={{ opacity: item.disabled ? '0.5' : '' }}>{item.title}</span>
|
||||
</List.Item>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { setting } = this.props;
|
||||
const { navTheme, primaryColor, layout, colorWeak } = setting;
|
||||
const { collapse } = this.state;
|
||||
return (
|
||||
<Drawer
|
||||
visible={collapse}
|
||||
width={300}
|
||||
onClose={this.togglerContent}
|
||||
placement="right"
|
||||
handler={
|
||||
<div className={styles.handle} onClick={this.togglerContent}>
|
||||
<Icon
|
||||
type={collapse ? 'close' : 'setting'}
|
||||
style={{
|
||||
color: '#fff',
|
||||
fontSize: 20,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
style={{
|
||||
zIndex: 999,
|
||||
}}
|
||||
>
|
||||
<div className={styles.content}>
|
||||
<Body title={formatMessage({ id: 'app.setting.pagestyle' })}>
|
||||
<BlockCheckbox
|
||||
list={[
|
||||
{
|
||||
key: 'dark',
|
||||
url: 'https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg',
|
||||
title: formatMessage({ id: 'app.setting.pagestyle.dark' }),
|
||||
},
|
||||
{
|
||||
key: 'light',
|
||||
url: 'https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg',
|
||||
title: formatMessage({ id: 'app.setting.pagestyle.light' }),
|
||||
},
|
||||
]}
|
||||
value={navTheme}
|
||||
onChange={value => this.changeSetting('navTheme', value)}
|
||||
/>
|
||||
</Body>
|
||||
|
||||
<ThemeColor
|
||||
title={formatMessage({ id: 'app.setting.themecolor' })}
|
||||
value={primaryColor}
|
||||
onChange={color => this.changeSetting('primaryColor', color)}
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Body title={formatMessage({ id: 'app.setting.navigationmode' })}>
|
||||
<BlockCheckbox
|
||||
list={[
|
||||
{
|
||||
key: 'sidemenu',
|
||||
url: 'https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg',
|
||||
title: formatMessage({ id: 'app.setting.sidemenu' }),
|
||||
},
|
||||
{
|
||||
key: 'topmenu',
|
||||
url: 'https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg',
|
||||
title: formatMessage({ id: 'app.setting.topmenu' }),
|
||||
},
|
||||
]}
|
||||
value={layout}
|
||||
onChange={value => this.changeSetting('layout', value)}
|
||||
/>
|
||||
</Body>
|
||||
|
||||
<List
|
||||
split={false}
|
||||
dataSource={this.getLayoutSetting()}
|
||||
renderItem={this.renderLayoutSettingItem}
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Body title={formatMessage({ id: 'app.setting.othersettings' })}>
|
||||
<List.Item
|
||||
actions={[
|
||||
<Switch
|
||||
size="small"
|
||||
checked={!!colorWeak}
|
||||
onChange={checked => this.changeSetting('colorWeak', checked)}
|
||||
/>,
|
||||
]}
|
||||
>
|
||||
{formatMessage({ id: 'app.setting.weakmode' })}
|
||||
</List.Item>
|
||||
</Body>
|
||||
<Divider />
|
||||
<CopyToClipboard
|
||||
text={JSON.stringify(omit(setting, ['colorWeak']), null, 2)}
|
||||
onCopy={() => message.success(formatMessage({ id: 'app.setting.copyinfo' }))}
|
||||
>
|
||||
<Button block icon="copy">
|
||||
{formatMessage({ id: 'app.setting.copy' })}
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
<Alert
|
||||
type="warning"
|
||||
className={styles.productionHint}
|
||||
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>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SettingDrawer;
|
||||
74
admin-web/src/components/SettingDrawer/index.less
Normal file
74
admin-web/src/components/SettingDrawer/index.less
Normal file
@@ -0,0 +1,74 @@
|
||||
@import '~antd/lib/style/themes/default.less';
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.blockChecbox {
|
||||
display: flex;
|
||||
.item {
|
||||
position: relative;
|
||||
margin-right: 16px;
|
||||
// box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
||||
border-radius: @border-radius-base;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 48px;
|
||||
}
|
||||
}
|
||||
.selectIcon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 15px;
|
||||
padding-left: 24px;
|
||||
color: @primary-color;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.color_block {
|
||||
display: inline-block;
|
||||
width: 38px;
|
||||
height: 22px;
|
||||
margin: 4px;
|
||||
margin-right: 12px;
|
||||
vertical-align: middle;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 12px;
|
||||
color: @heading-color;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.handle {
|
||||
position: absolute;
|
||||
top: 240px;
|
||||
right: 300px;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
background: @primary-color;
|
||||
border-radius: 4px 0 0 4px;
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.productionHint {
|
||||
margin-top: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
Reference in New Issue
Block a user