mirror of
https://github.com/zuiidea/antd-admin
synced 2026-11-03 16:46:12 +00:00
✨ Upgrading components to typescript
This commit is contained in:
+4
-7
@@ -6,6 +6,9 @@ import routes from './routes'
|
||||
import proxy from './proxy'
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV === 'development'
|
||||
const theme = lessToJs(
|
||||
fs.readFileSync(path.join(__dirname, '../src/themes/default.less'), 'utf8')
|
||||
)
|
||||
|
||||
const config: IConfig = {
|
||||
// IMPORTANT! change next line to yours or delete. And hide in dev
|
||||
@@ -14,20 +17,14 @@ const config: IConfig = {
|
||||
ignoreMomentLocale: true,
|
||||
targets: { ie: 9 },
|
||||
dynamicImport: {},
|
||||
theme,
|
||||
proxy,
|
||||
routes,
|
||||
// a lower cost way to genereate sourcemap, default is cheap-module-source-map, could save 60% time in dev hotload
|
||||
devtool: 'eval',
|
||||
// umi3 comple node_modules by default, could be disable
|
||||
nodeModulesTransform: {
|
||||
type: 'none',
|
||||
exclude: [],
|
||||
},
|
||||
// Theme for antd
|
||||
// https://ant.design/docs/react/customize-theme
|
||||
theme: lessToJs(
|
||||
fs.readFileSync(path.join(__dirname, '../src/themes/default.less'), 'utf8')
|
||||
),
|
||||
extraBabelPresets: ['@lingui/babel-preset-react'],
|
||||
extraBabelPlugins: [
|
||||
'macros',
|
||||
|
||||
+8
-6
@@ -1,10 +1,12 @@
|
||||
import type { IRoute } from 'umi'
|
||||
|
||||
const routes: IRoute[] = [{
|
||||
exact: false, path: '/', component: '@/layouts/index',
|
||||
routes: [
|
||||
{ exact: true, path: '/login', component: '@/pages/login' },
|
||||
],
|
||||
}]
|
||||
const routes: IRoute[] = [
|
||||
{
|
||||
exact: false,
|
||||
path: '/',
|
||||
component: '@/layouts',
|
||||
routes: [{ exact: true, path: '/login', component: '@/pages/login' }],
|
||||
},
|
||||
]
|
||||
|
||||
export default routes
|
||||
|
||||
+13
-14
@@ -39,6 +39,8 @@
|
||||
"@lingui/cli": "^3.8.2",
|
||||
"@lingui/loader": "^3.8.2",
|
||||
"@lingui/macro": "^3.8.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.20.0",
|
||||
"@typescript-eslint/parser": "^4.20.0",
|
||||
"@umijs/preset-react": "^1.8.0",
|
||||
"babel-eslint": "^10.0.0",
|
||||
"babel-plugin-dev-expression": "^0.2.1",
|
||||
@@ -71,15 +73,13 @@
|
||||
"node": ">= 10.0.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.js": [
|
||||
"eslint --ext .js --fix",
|
||||
"npm run prettier",
|
||||
"git add"
|
||||
"*.{ts,tsx,js,jsx}": [
|
||||
"npm run eslint",
|
||||
"npm run prettier"
|
||||
],
|
||||
"**/*.less": [
|
||||
"stylelint --syntax less",
|
||||
"npm run prettier",
|
||||
"git add"
|
||||
"*.less": [
|
||||
"npm run stylelint",
|
||||
"npm run prettier"
|
||||
]
|
||||
},
|
||||
"lingui": {
|
||||
@@ -110,14 +110,13 @@
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"analyze": "cross-env ANALYZE=1 umi build",
|
||||
"start": "umi dev",
|
||||
"build": "umi build",
|
||||
"check:model": "umi dva list model",
|
||||
"lint:js": "eslint --ext .js src",
|
||||
"lint:style": "stylelint \"src/**/*.less\" --syntax less",
|
||||
"start": "cross-env umi dev",
|
||||
"test": "cross-env BABELRC=none umi test",
|
||||
"prettier": "prettier --write 'src/**/*.{js,less}'",
|
||||
"analyze": "cross-env ANALYZE=1 umi build",
|
||||
"eslint": "eslint --fix 'src/**/*.{ts,tsx,js.jsx}'",
|
||||
"stylelint": "stylelint src/**/*.less --syntax less",
|
||||
"prettier": "prettier --write 'src/**/*.{ts,tsx,js.jsx,less}'",
|
||||
"precommit": "lint-staged",
|
||||
"add-locale": "lingui add-locale",
|
||||
"extract": "lingui extract",
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { BarsOutlined, DownOutlined } from '@ant-design/icons'
|
||||
import { Dropdown, Button, Menu } from 'antd'
|
||||
|
||||
const DropOption = ({
|
||||
onMenuClick,
|
||||
menuOptions = [],
|
||||
buttonStyle,
|
||||
dropdownProps,
|
||||
}) => {
|
||||
const menu = menuOptions.map(item => (
|
||||
<Menu.Item key={item.key}>{item.name}</Menu.Item>
|
||||
))
|
||||
return (
|
||||
<Dropdown
|
||||
overlay={<Menu onClick={onMenuClick}>{menu}</Menu>}
|
||||
{...dropdownProps}
|
||||
>
|
||||
<Button style={{ border: 'none', ...buttonStyle }}>
|
||||
<BarsOutlined style={{ marginRight: 2 }} />
|
||||
<DownOutlined />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
|
||||
DropOption.propTypes = {
|
||||
onMenuClick: PropTypes.func,
|
||||
menuOptions: PropTypes.array.isRequired,
|
||||
buttonStyle: PropTypes.object,
|
||||
dropdownProps: PropTypes.object,
|
||||
}
|
||||
|
||||
export default DropOption
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "DropOption",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"main": "./DropOption.js"
|
||||
}
|
||||
Vendored
+12
-12
@@ -1,21 +1,21 @@
|
||||
import React from 'react';
|
||||
import { TooltipProps } from 'antd/lib/tooltip';
|
||||
import React from 'react'
|
||||
import { TooltipProps } from 'antd/lib/tooltip'
|
||||
|
||||
export interface EllipsisTooltipProps extends TooltipProps {
|
||||
title?: undefined;
|
||||
overlayStyle?: undefined;
|
||||
title?: undefined
|
||||
overlayStyle?: undefined
|
||||
}
|
||||
|
||||
export interface EllipsisProps {
|
||||
tooltip?: boolean | EllipsisTooltipProps;
|
||||
length?: number;
|
||||
lines?: number;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
fullWidthRecognition?: boolean;
|
||||
tooltip?: boolean | EllipsisTooltipProps
|
||||
length?: number
|
||||
lines?: number
|
||||
style?: React.CSSProperties
|
||||
className?: string
|
||||
fullWidthRecognition?: boolean
|
||||
}
|
||||
|
||||
export function getStrFullLength(str: string): number;
|
||||
export function cutStrByFullLength(str: string, maxLength: number): string;
|
||||
export function getStrFullLength(str: string): number
|
||||
export function cutStrByFullLength(str: string, maxLength: number): string
|
||||
|
||||
export default class Ellipsis extends React.Component<EllipsisProps, any> {}
|
||||
|
||||
@@ -1,68 +1,79 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Tooltip } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import styles from './index.less';
|
||||
import React, { Component } from 'react'
|
||||
import { Tooltip } from 'antd'
|
||||
import classNames from 'classnames'
|
||||
import styles from './index.less'
|
||||
|
||||
/* eslint react/no-did-mount-set-state: 0 */
|
||||
/* eslint no-param-reassign: 0 */
|
||||
|
||||
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
|
||||
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined
|
||||
|
||||
const TooltipOverlayStyle = {
|
||||
overflowWrap: 'break-word',
|
||||
wordWrap: 'break-word',
|
||||
};
|
||||
}
|
||||
|
||||
export const getStrFullLength = (str = '') =>
|
||||
str.split('').reduce((pre, cur) => {
|
||||
const charCode = cur.charCodeAt(0);
|
||||
const charCode = cur.charCodeAt(0)
|
||||
if (charCode >= 0 && charCode <= 128) {
|
||||
return pre + 1;
|
||||
return pre + 1
|
||||
}
|
||||
return pre + 2;
|
||||
}, 0);
|
||||
return pre + 2
|
||||
}, 0)
|
||||
|
||||
export const cutStrByFullLength = (str = '', maxLength) => {
|
||||
let showLength = 0;
|
||||
let showLength = 0
|
||||
return str.split('').reduce((pre, cur) => {
|
||||
const charCode = cur.charCodeAt(0);
|
||||
const charCode = cur.charCodeAt(0)
|
||||
if (charCode >= 0 && charCode <= 128) {
|
||||
showLength += 1;
|
||||
showLength += 1
|
||||
} else {
|
||||
showLength += 2;
|
||||
showLength += 2
|
||||
}
|
||||
if (showLength <= maxLength) {
|
||||
return pre + cur;
|
||||
return pre + cur
|
||||
}
|
||||
return pre;
|
||||
}, '');
|
||||
};
|
||||
return pre
|
||||
}, '')
|
||||
}
|
||||
|
||||
const getTooltip = ({ tooltip, overlayStyle, title, children }) => {
|
||||
if (tooltip) {
|
||||
const props = tooltip === true ? { overlayStyle, title } : { ...tooltip, overlayStyle, title };
|
||||
return <Tooltip {...props}>{children}</Tooltip>;
|
||||
const props =
|
||||
tooltip === true
|
||||
? { overlayStyle, title }
|
||||
: { ...tooltip, overlayStyle, title }
|
||||
return <Tooltip {...props}>{children}</Tooltip>
|
||||
}
|
||||
return children;
|
||||
};
|
||||
return children
|
||||
}
|
||||
|
||||
const EllipsisText = ({ text, length, tooltip, fullWidthRecognition, ...other }) => {
|
||||
const EllipsisText = ({
|
||||
text,
|
||||
length,
|
||||
tooltip,
|
||||
fullWidthRecognition,
|
||||
...other
|
||||
}) => {
|
||||
if (typeof text !== 'string') {
|
||||
throw new Error('Ellipsis children must be string.');
|
||||
throw new Error('Ellipsis children must be string.')
|
||||
}
|
||||
const textLength = fullWidthRecognition ? getStrFullLength(text) : text.length;
|
||||
const textLength = fullWidthRecognition ? getStrFullLength(text) : text.length
|
||||
if (textLength <= length || length < 0) {
|
||||
return <span {...other}>{text}</span>;
|
||||
return <span {...other}>{text}</span>
|
||||
}
|
||||
const tail = '...';
|
||||
let displayText;
|
||||
const tail = '...'
|
||||
let displayText
|
||||
if (length - tail.length <= 0) {
|
||||
displayText = '';
|
||||
displayText = ''
|
||||
} else {
|
||||
displayText = fullWidthRecognition ? cutStrByFullLength(text, length) : text.slice(0, length);
|
||||
displayText = fullWidthRecognition
|
||||
? cutStrByFullLength(text, length)
|
||||
: text.slice(0, length)
|
||||
}
|
||||
|
||||
const spanAttrs = tooltip ? {} : { ...other };
|
||||
const spanAttrs = tooltip ? {} : { ...other }
|
||||
return getTooltip({
|
||||
tooltip,
|
||||
overlayStyle: TooltipOverlayStyle,
|
||||
@@ -73,116 +84,117 @@ const EllipsisText = ({ text, length, tooltip, fullWidthRecognition, ...other })
|
||||
{tail}
|
||||
</span>
|
||||
),
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
export default class Ellipsis extends Component {
|
||||
state = {
|
||||
text: '',
|
||||
targetCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.node) {
|
||||
this.computeLine();
|
||||
this.computeLine()
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(perProps) {
|
||||
const { lines } = this.props;
|
||||
const { lines } = this.props
|
||||
if (lines !== perProps.lines) {
|
||||
this.computeLine();
|
||||
this.computeLine()
|
||||
}
|
||||
}
|
||||
|
||||
computeLine = () => {
|
||||
const { lines } = this.props;
|
||||
const { lines } = this.props
|
||||
if (lines && !isSupportLineClamp) {
|
||||
const text = this.shadowChildren.innerText || this.shadowChildren.textContent;
|
||||
const lineHeight = parseInt(getComputedStyle(this.root).lineHeight, 10);
|
||||
const targetHeight = lines * lineHeight;
|
||||
this.content.style.height = `${targetHeight}px`;
|
||||
const totalHeight = this.shadowChildren.offsetHeight;
|
||||
const shadowNode = this.shadow.firstChild;
|
||||
const text =
|
||||
this.shadowChildren.innerText || this.shadowChildren.textContent
|
||||
const lineHeight = parseInt(getComputedStyle(this.root).lineHeight, 10)
|
||||
const targetHeight = lines * lineHeight
|
||||
this.content.style.height = `${targetHeight}px`
|
||||
const totalHeight = this.shadowChildren.offsetHeight
|
||||
const shadowNode = this.shadow.firstChild
|
||||
|
||||
if (totalHeight <= targetHeight) {
|
||||
this.setState({
|
||||
text,
|
||||
targetCount: text.length,
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// bisection
|
||||
const len = text.length;
|
||||
const mid = Math.ceil(len / 2);
|
||||
const len = text.length
|
||||
const mid = Math.ceil(len / 2)
|
||||
|
||||
const count = this.bisection(targetHeight, mid, 0, len, text, shadowNode);
|
||||
const count = this.bisection(targetHeight, mid, 0, len, text, shadowNode)
|
||||
|
||||
this.setState({
|
||||
text,
|
||||
targetCount: count,
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
bisection = (th, m, b, e, text, shadowNode) => {
|
||||
const suffix = '...';
|
||||
let mid = m;
|
||||
let end = e;
|
||||
let begin = b;
|
||||
shadowNode.innerHTML = text.substring(0, mid) + suffix;
|
||||
let sh = shadowNode.offsetHeight;
|
||||
const suffix = '...'
|
||||
let mid = m
|
||||
let end = e
|
||||
let begin = b
|
||||
shadowNode.innerHTML = text.substring(0, mid) + suffix
|
||||
let sh = shadowNode.offsetHeight
|
||||
|
||||
if (sh <= th) {
|
||||
shadowNode.innerHTML = text.substring(0, mid + 1) + suffix;
|
||||
sh = shadowNode.offsetHeight;
|
||||
shadowNode.innerHTML = text.substring(0, mid + 1) + suffix
|
||||
sh = shadowNode.offsetHeight
|
||||
if (sh > th || mid === begin) {
|
||||
return mid;
|
||||
return mid
|
||||
}
|
||||
begin = mid;
|
||||
begin = mid
|
||||
if (end - begin === 1) {
|
||||
mid = 1 + begin;
|
||||
mid = 1 + begin
|
||||
} else {
|
||||
mid = Math.floor((end - begin) / 2) + begin;
|
||||
mid = Math.floor((end - begin) / 2) + begin
|
||||
}
|
||||
return this.bisection(th, mid, begin, end, text, shadowNode);
|
||||
return this.bisection(th, mid, begin, end, text, shadowNode)
|
||||
}
|
||||
if (mid - 1 < 0) {
|
||||
return mid;
|
||||
return mid
|
||||
}
|
||||
shadowNode.innerHTML = text.substring(0, mid - 1) + suffix;
|
||||
sh = shadowNode.offsetHeight;
|
||||
shadowNode.innerHTML = text.substring(0, mid - 1) + suffix
|
||||
sh = shadowNode.offsetHeight
|
||||
if (sh <= th) {
|
||||
return mid - 1;
|
||||
return mid - 1
|
||||
}
|
||||
end = mid;
|
||||
mid = Math.floor((end - begin) / 2) + begin;
|
||||
return this.bisection(th, mid, begin, end, text, shadowNode);
|
||||
};
|
||||
end = mid
|
||||
mid = Math.floor((end - begin) / 2) + begin
|
||||
return this.bisection(th, mid, begin, end, text, shadowNode)
|
||||
}
|
||||
|
||||
handleRoot = n => {
|
||||
this.root = n;
|
||||
};
|
||||
handleRoot = (n) => {
|
||||
this.root = n
|
||||
}
|
||||
|
||||
handleContent = n => {
|
||||
this.content = n;
|
||||
};
|
||||
handleContent = (n) => {
|
||||
this.content = n
|
||||
}
|
||||
|
||||
handleNode = n => {
|
||||
this.node = n;
|
||||
};
|
||||
handleNode = (n) => {
|
||||
this.node = n
|
||||
}
|
||||
|
||||
handleShadow = n => {
|
||||
this.shadow = n;
|
||||
};
|
||||
handleShadow = (n) => {
|
||||
this.shadow = n
|
||||
}
|
||||
|
||||
handleShadowChildren = n => {
|
||||
this.shadowChildren = n;
|
||||
};
|
||||
handleShadowChildren = (n) => {
|
||||
this.shadowChildren = n
|
||||
}
|
||||
|
||||
render() {
|
||||
const { text, targetCount } = this.state;
|
||||
const { text, targetCount } = this.state
|
||||
const {
|
||||
children,
|
||||
lines,
|
||||
@@ -191,19 +203,19 @@ export default class Ellipsis extends Component {
|
||||
tooltip,
|
||||
fullWidthRecognition,
|
||||
...restProps
|
||||
} = this.props;
|
||||
} = this.props
|
||||
|
||||
const cls = classNames(styles.ellipsis, className, {
|
||||
[styles.lines]: lines && !isSupportLineClamp,
|
||||
[styles.lineClamp]: lines && isSupportLineClamp,
|
||||
});
|
||||
})
|
||||
|
||||
if (!lines && !length) {
|
||||
return (
|
||||
<span className={cls} {...restProps}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
// length
|
||||
@@ -217,28 +229,30 @@ export default class Ellipsis extends Component {
|
||||
fullWidthRecognition={fullWidthRecognition}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const id = `antd-pro-ellipsis-${`${new Date().getTime()}${Math.floor(Math.random() * 100)}`}`;
|
||||
const id = `antd-pro-ellipsis-${`${new Date().getTime()}${Math.floor(
|
||||
Math.random() * 100
|
||||
)}`}`
|
||||
|
||||
// support document.body.style.webkitLineClamp
|
||||
if (isSupportLineClamp) {
|
||||
const style = `#${id}{-webkit-line-clamp:${lines};-webkit-box-orient: vertical;}`;
|
||||
const style = `#${id}{-webkit-line-clamp:${lines};-webkit-box-orient: vertical;}`
|
||||
|
||||
const node = (
|
||||
<div id={id} className={cls} {...restProps}>
|
||||
<style>{style}</style>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
|
||||
return getTooltip({
|
||||
tooltip,
|
||||
overlayStyle: TooltipOverlayStyle,
|
||||
title: children,
|
||||
children: node,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
const childNode = (
|
||||
@@ -246,7 +260,7 @@ export default class Ellipsis extends Component {
|
||||
{targetCount > 0 && text.substring(0, targetCount)}
|
||||
{targetCount > 0 && targetCount < text.length && '...'}
|
||||
</span>
|
||||
);
|
||||
)
|
||||
|
||||
return (
|
||||
<div {...restProps} ref={this.handleRoot} className={cls}>
|
||||
@@ -265,6 +279,6 @@ export default class Ellipsis extends Component {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { getStrFullLength, cutStrByFullLength } from './index';
|
||||
import { getStrFullLength, cutStrByFullLength } from './index'
|
||||
|
||||
describe('test calculateShowLength', () => {
|
||||
it('get full length', () => {
|
||||
expect(getStrFullLength('一二,a,')).toEqual(8);
|
||||
});
|
||||
expect(getStrFullLength('一二,a,')).toEqual(8)
|
||||
})
|
||||
it('cut str by full length', () => {
|
||||
expect(cutStrByFullLength('一二,a,', 7)).toEqual('一二,a');
|
||||
});
|
||||
expect(cutStrByFullLength('一二,a,', 7)).toEqual('一二,a')
|
||||
})
|
||||
it('cut str when length small', () => {
|
||||
expect(cutStrByFullLength('一22三', 5)).toEqual('一22');
|
||||
});
|
||||
});
|
||||
expect(cutStrByFullLength('一22三', 5)).toEqual('一22')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import styles from './FilterItem.less'
|
||||
import styles from './index.less'
|
||||
|
||||
const FilterItem = ({ label = '', children }) => {
|
||||
interface FilterItemProps {
|
||||
label: string
|
||||
}
|
||||
const FilterItem: React.FC<FilterItemProps> = ({ label = '', children }) => {
|
||||
const labelArray = label.split('')
|
||||
return (
|
||||
<div className={styles.filterItem}>
|
||||
@@ -20,9 +22,4 @@ const FilterItem = ({ label = '', children }) => {
|
||||
)
|
||||
}
|
||||
|
||||
FilterItem.propTypes = {
|
||||
label: PropTypes.string,
|
||||
children: PropTypes.element.isRequired,
|
||||
}
|
||||
|
||||
export default FilterItem
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "FilterItem",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"main": "./FilterItem.js"
|
||||
}
|
||||
@@ -26,6 +26,7 @@ const GlobalFooter: React.FC<GlobalFooterProps> = ({
|
||||
title={link.key}
|
||||
target={link.blankTarget ? '_blank' : '_self'}
|
||||
href={link.href}
|
||||
rel="noreferrer"
|
||||
>
|
||||
{link.title}
|
||||
</a>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
MenuFoldOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { getLocale, setLocale } from 'utils'
|
||||
import moment from 'moment'
|
||||
import classnames from 'classnames'
|
||||
@@ -18,7 +18,7 @@ import styles from './Header.less'
|
||||
const { SubMenu } = Menu
|
||||
|
||||
class Header extends PureComponent {
|
||||
handleClickMenu = e => {
|
||||
handleClickMenu = (e) => {
|
||||
e.key === 'SignOut' && this.props.onSignOut()
|
||||
}
|
||||
render() {
|
||||
@@ -55,21 +55,19 @@ class Header extends PureComponent {
|
||||
if (config.i18n) {
|
||||
const { languages } = config.i18n
|
||||
const language = getLocale()
|
||||
const currentLanguage = languages.find(
|
||||
item => item.key === language
|
||||
)
|
||||
const currentLanguage = languages.find((item) => item.key === language)
|
||||
|
||||
rightContent.unshift(
|
||||
<Menu
|
||||
key="language"
|
||||
selectedKeys={[currentLanguage.key]}
|
||||
onClick={data => {
|
||||
onClick={(data) => {
|
||||
setLocale(data.key)
|
||||
}}
|
||||
mode="horizontal"
|
||||
>
|
||||
<SubMenu title={<Avatar size="small" src={currentLanguage.flag} />}>
|
||||
{languages.map(item => (
|
||||
{languages.map((item) => (
|
||||
<Menu.Item key={item.key}>
|
||||
<Avatar
|
||||
size="small"
|
||||
@@ -99,7 +97,7 @@ class Header extends PureComponent {
|
||||
locale={{
|
||||
emptyText: <Trans>You have viewed all notifications.</Trans>,
|
||||
}}
|
||||
renderItem={item => (
|
||||
renderItem={(item) => (
|
||||
<List.Item className={styles.notificationItem}>
|
||||
<List.Item.Meta
|
||||
title={
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Switch, Layout } from 'antd'
|
||||
import { t } from "@lingui/macro"
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { t } from '@lingui/macro'
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { BulbOutlined } from '@ant-design/icons'
|
||||
import ScrollBar from '../ScrollBar'
|
||||
import { config } from 'utils'
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
.loader {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
|
||||
&.fullScreen {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.warpper {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.inner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 0 auto;
|
||||
text-indent: -12345px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.7);
|
||||
border-radius: 50%;
|
||||
z-index: 100001;
|
||||
|
||||
:local {
|
||||
animation: spinner 600ms infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
letter-spacing: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
transition: opacity 1s ease 0.5s, z-index 0.1s ease 1.5s;
|
||||
}
|
||||
}
|
||||
@keyframes spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.loader {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
|
||||
&.fullScreen {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.warpper {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.inner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 0 auto;
|
||||
text-indent: -12345px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.7);
|
||||
border-radius: 50%;
|
||||
z-index: 100001;
|
||||
|
||||
:local {
|
||||
animation: spinner 600ms infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 100px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
letter-spacing: 4px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
transition: opacity 1s ease 0.5s, z-index 0.1s ease 1.5s;
|
||||
}
|
||||
}
|
||||
@keyframes spinner {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classNames from 'classnames'
|
||||
import styles from './Loader.less'
|
||||
import styles from './index.less'
|
||||
|
||||
const Loader = ({ spinning = false, fullScreen }) => {
|
||||
interface LoaderProps {
|
||||
spinning?: boolean
|
||||
fullScreen?: boolean
|
||||
}
|
||||
|
||||
const Loader: React.FC<LoaderProps> = ({ spinning = false, fullScreen }) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames(styles.loader, {
|
||||
@@ -19,9 +23,4 @@ const Loader = ({ spinning = false, fullScreen }) => {
|
||||
)
|
||||
}
|
||||
|
||||
Loader.propTypes = {
|
||||
spinning: PropTypes.bool,
|
||||
fullScreen: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default Loader
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "Loader",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"main": "./Loader.js"
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
import FilterItem from './FilterItem'
|
||||
import DropOption from './DropOption'
|
||||
import Loader from './Loader'
|
||||
import ScrollBar from './ScrollBar'
|
||||
import GlobalFooter from './GlobalFooter'
|
||||
import Ellipsis from './Ellipsis'
|
||||
|
||||
export { GlobalFooter, Ellipsis, FilterItem, DropOption, Loader, ScrollBar }
|
||||
export { GlobalFooter, Ellipsis, FilterItem, Loader, ScrollBar }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IConfig, ISupportedLocales } from '@/typings'
|
||||
import { LOCALE_LANGUAGE } from '@/configs'
|
||||
import { LOCALE_LANGUAGE } from '@/configs/constants'
|
||||
import checkLanguage from '@/utils/checkLanguage'
|
||||
import {
|
||||
detect,
|
||||
|
||||
@@ -1,10 +1,34 @@
|
||||
import React from 'react'
|
||||
import { HomeOutlined, AppstoreOutlined } from '@ant-design/icons'
|
||||
import {
|
||||
PayCircleOutlined,
|
||||
ShoppingCartOutlined,
|
||||
MessageOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
DashboardOutlined,
|
||||
ApiOutlined,
|
||||
CameraOutlined,
|
||||
EditOutlined,
|
||||
CodeOutlined,
|
||||
LineOutlined,
|
||||
BarChartOutlined,
|
||||
AreaChartOutlined,
|
||||
} from '@ant-design/icons'
|
||||
import { IMenuIcon } from '@/typings'
|
||||
|
||||
const menuIcon: IMenuIcon = {
|
||||
home: <HomeOutlined />,
|
||||
other: <AppstoreOutlined />,
|
||||
'pay-circle-o': <PayCircleOutlined />,
|
||||
'shopping-cart': <ShoppingCartOutlined />,
|
||||
'camera-o': <CameraOutlined />,
|
||||
'line-chart': <LineOutlined />,
|
||||
'code-o': <CodeOutlined />,
|
||||
'area-chart': <AreaChartOutlined />,
|
||||
'bar-chart': <BarChartOutlined />,
|
||||
message: <MessageOutlined />,
|
||||
team: <TeamOutlined />,
|
||||
dashboard: <DashboardOutlined />,
|
||||
user: <UserOutlined />,
|
||||
api: <ApiOutlined />,
|
||||
edit: <EditOutlined />,
|
||||
}
|
||||
|
||||
export default menuIcon
|
||||
|
||||
@@ -9,35 +9,8 @@ import { t } from '@lingui/macro'
|
||||
const menus = [
|
||||
{
|
||||
path: '/',
|
||||
name: t`主页`,
|
||||
icon: 'home',
|
||||
},
|
||||
{
|
||||
name: t`其他`,
|
||||
key: '/other',
|
||||
icon: 'other',
|
||||
children: [
|
||||
{
|
||||
path: '/hello',
|
||||
name: t`你好 (useRedux)`,
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
name: t`用户 (useRequest)`,
|
||||
},
|
||||
{
|
||||
path: '/i18n',
|
||||
name: t`国际化 (useLingui)`,
|
||||
},
|
||||
{
|
||||
path: '/simple',
|
||||
name: t`国际化 (Elint插件)`,
|
||||
},
|
||||
{
|
||||
path: '/simple2',
|
||||
name: t`未定义页面`,
|
||||
},
|
||||
],
|
||||
name: t`Dashboard`,
|
||||
icon: 'dashboard',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('Login', () => {
|
||||
afterEach(() => page.close())
|
||||
|
||||
it('should login with failure', async () => {
|
||||
await page.waitFor(selector => !!document.querySelector('#username'), {
|
||||
await page.waitFor((selector) => !!document.querySelector('#username'), {
|
||||
timeout: 3000,
|
||||
})
|
||||
await page.type('#username', 'wrong_user')
|
||||
|
||||
@@ -12,7 +12,7 @@ const useIntlProvider = () => {
|
||||
|
||||
useEffect(() => {
|
||||
const path = antdI18nMap[language]
|
||||
import(`antd/lib/locale/${path}.js`).then(data => {
|
||||
import(`antd/lib/locale/${path}.js`).then((data) => {
|
||||
setLocale(data.default)
|
||||
})
|
||||
localStorage.setItem(LOCALE_LANGUAGE, language)
|
||||
|
||||
@@ -11,7 +11,7 @@ const LayoutMap = {
|
||||
public: PublicLayout,
|
||||
}
|
||||
|
||||
const BaseLayout: React.FC = props => {
|
||||
const BaseLayout: React.FC = (props) => {
|
||||
const location = useLocation()
|
||||
const Container = LayoutMap[queryLayout(config.layouts, location.pathname)]
|
||||
return <Container>{props.children}</Container>
|
||||
|
||||
@@ -11,12 +11,13 @@ import ProBasicLayout, {
|
||||
SettingDrawerProps,
|
||||
} from '@ant-design/pro-layout'
|
||||
import { Link } from 'umi'
|
||||
import { Dropdown, Menu } from 'antd'
|
||||
import { Dropdown, Menu, Avatar } from 'antd'
|
||||
import { useLocation } from '@/hooks'
|
||||
import { ConfigContext } from '@/utils/context'
|
||||
import { menus, menuIcon, language, languages, config } from '@/configs'
|
||||
import defaultSettings from '@/defaultSettings'
|
||||
import type { MenuProps } from 'antd/es/menu';
|
||||
import { ISupportedLocales } from '@/typings'
|
||||
import type { MenuProps } from 'antd/es/menu'
|
||||
import styles from './index.less'
|
||||
|
||||
const renderMenuItem = (menus: MenuDataItem[]): MenuDataItem[] =>
|
||||
@@ -26,7 +27,7 @@ const renderMenuItem = (menus: MenuDataItem[]): MenuDataItem[] =>
|
||||
children: children && renderMenuItem(children),
|
||||
}))
|
||||
|
||||
const PrimaryLayout: React.FC = props => {
|
||||
const PrimaryLayout: React.FC = (props) => {
|
||||
const location = useLocation()
|
||||
const [settings] = useState<SettingDrawerProps['settings']>(defaultSettings)
|
||||
const [openKeys, setOpenKeys] = useState<string[]>([])
|
||||
@@ -54,7 +55,7 @@ const PrimaryLayout: React.FC = props => {
|
||||
}, [])
|
||||
|
||||
const handleOnOpenChange = useCallback(
|
||||
keys => setOpenKeys(keys as string[]),
|
||||
(keys) => setOpenKeys(keys as string[]),
|
||||
[]
|
||||
)
|
||||
|
||||
@@ -70,10 +71,15 @@ const PrimaryLayout: React.FC = props => {
|
||||
const rightContentRender = () => (
|
||||
<Dropdown
|
||||
overlay={
|
||||
<Menu>
|
||||
{languages.map(item => (
|
||||
<Menu.Item key={item.key} onClick={() => setLanguage(item.key)}>
|
||||
<span className={styles.headerFlag}>{item.flag}</span>
|
||||
<Menu
|
||||
selectedKeys={[currentLanguage.value]}
|
||||
onClick={(data) => {
|
||||
setLanguage(data.key as ISupportedLocales)
|
||||
}}
|
||||
>
|
||||
{languages.map((item) => (
|
||||
<Menu.Item key={item.key}>
|
||||
<Avatar size="small" style={{ marginRight: 8 }} src={item.flag} />
|
||||
{item.value}
|
||||
</Menu.Item>
|
||||
))}
|
||||
@@ -81,8 +87,7 @@ const PrimaryLayout: React.FC = props => {
|
||||
}
|
||||
>
|
||||
<div className={styles.headerButton}>
|
||||
<span className={styles.headerFlag}>{currentLanguage.flag}</span>
|
||||
{currentLanguage.value}
|
||||
<Avatar size="small" src={currentLanguage.flag} />
|
||||
</div>
|
||||
</Dropdown>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
|
||||
const PublicLayout: React.FC = props => {
|
||||
const PublicLayout: React.FC = (props) => {
|
||||
return <>{props.children}</>
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,8 @@ import { I18nProvider } from '@lingui/react'
|
||||
import { useIntlProvider } from '@/hooks'
|
||||
import { ConfigContext } from '@/utils/context'
|
||||
import BaseLayout from './BaseLayout'
|
||||
import PrimaryLayout from './PrimaryLayout'
|
||||
|
||||
const Layout: React.FC = props => {
|
||||
const Layout: React.FC = (props) => {
|
||||
const { language, setLanguage, i18n, locale } = useIntlProvider()
|
||||
const globalConfig = {
|
||||
language,
|
||||
|
||||
+6
-9
@@ -1,15 +1,12 @@
|
||||
import React from 'react'
|
||||
import { FrownOutlined } from '@ant-design/icons'
|
||||
import { Page } from 'components'
|
||||
import styles from './404.less'
|
||||
|
||||
const Error = () => (
|
||||
<Page inner>
|
||||
<div className={styles.error}>
|
||||
<FrownOutlined />
|
||||
<h1>404 Not Found</h1>
|
||||
</div>
|
||||
</Page>
|
||||
const NotFoundPage: React.FC = () => (
|
||||
<div className={styles.error}>
|
||||
<FrownOutlined />
|
||||
<h1>404 Not Found</h1>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default Error
|
||||
export default NotFoundPage
|
||||
|
||||
@@ -23,6 +23,7 @@ const Login: React.FC = () => {
|
||||
]
|
||||
|
||||
const handleFinish = (values) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(values)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { message } from 'antd'
|
||||
|
||||
export default {
|
||||
onError(e, a) {
|
||||
e.preventDefault()
|
||||
if (e.message) {
|
||||
message.error(e.message)
|
||||
} else {
|
||||
/* eslint-disable */
|
||||
console.error(e)
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { apiPrefix } from 'utils/config'
|
||||
|
||||
import api from './api'
|
||||
|
||||
const gen = params => {
|
||||
const gen = (params) => {
|
||||
let url = apiPrefix + params
|
||||
let method = 'GET'
|
||||
|
||||
@@ -13,7 +13,7 @@ const gen = params => {
|
||||
url = apiPrefix + paramsArray[1]
|
||||
}
|
||||
|
||||
return function(data) {
|
||||
return function (data) {
|
||||
return request({
|
||||
url,
|
||||
data,
|
||||
@@ -27,7 +27,7 @@ for (const key in api) {
|
||||
APIFunction[key] = gen(api[key])
|
||||
}
|
||||
|
||||
APIFunction.queryWeather = params => {
|
||||
APIFunction.queryWeather = (params) => {
|
||||
params.key = 'i7sau1babuzwhycn'
|
||||
return request({
|
||||
url: `${apiPrefix}/weather/now.json`,
|
||||
@@ -35,8 +35,4 @@ APIFunction.queryWeather = params => {
|
||||
})
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
// module.exports = APIFunction
|
||||
=======
|
||||
export default APIFunction
|
||||
>>>>>>> master
|
||||
|
||||
+15
-16
@@ -1,16 +1,15 @@
|
||||
// 本文件是对 ant-design:
|
||||
// https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
|
||||
// 相应变量值的覆盖
|
||||
// 注意:只需写出要覆盖的变量即可(不需要覆盖的变量不要写)
|
||||
|
||||
@import '../../node_modules/antd/lib/style/themes/default.less';
|
||||
|
||||
@border-radius-base: 3px;
|
||||
@border-radius-sm: 2px;
|
||||
@shadow-color: rgba(0, 0, 0, 0.05);
|
||||
@shadow-1-down: 4px 4px 40px @shadow-color;
|
||||
@border-color-split: #f4f4f4;
|
||||
@border-color-base: #e5e5e5;
|
||||
@font-size-base: 13px;
|
||||
@text-color: #666;
|
||||
@hover-color: #f9f9fc;
|
||||
/**
|
||||
* Customize Ant Design theme, Ant design less variables could be found in:
|
||||
* https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
|
||||
*/
|
||||
@import '../../node_modules/antd/lib/style/themes/default.less';
|
||||
|
||||
@border-radius-base: 3px;
|
||||
@border-radius-sm: 2px;
|
||||
@shadow-color: rgba(0, 0, 0, 0.05);
|
||||
@shadow-1-down: 4px 4px 40px @shadow-color;
|
||||
@border-color-split: #f4f4f4;
|
||||
@border-color-base: #e5e5e5;
|
||||
@font-size-base: 13px;
|
||||
@text-color: #666;
|
||||
@hover-color: #f9f9fc;
|
||||
|
||||
@@ -56,8 +56,8 @@ body {
|
||||
}
|
||||
|
||||
.ant-table-pagination {
|
||||
display: table;
|
||||
float: none !important;
|
||||
display: table;
|
||||
margin: 16px auto !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@import '~@/themes/default';
|
||||
|
||||
@dark-half #494949;
|
||||
@purple #d897eb;
|
||||
@shadow-1 4px 4px 20px 0 rgba(0, 0, 0, 0.01);
|
||||
@shadow-2 4px 4px 40px 0 rgba(0, 0, 0, 0.05);
|
||||
@transition-ease-in all 0.3s ease-out;
|
||||
@transition-ease-out all 0.3s ease-out;
|
||||
@ease-in ease-in;
|
||||
@dark-half: #494949;
|
||||
@purple: #d897eb;
|
||||
@shadow-1: 4px 4px 20px 0 rgba(0, 0, 0, 0.01);
|
||||
@shadow-2: 4px 4px 40px 0 rgba(0, 0, 0, 0.05);
|
||||
@transition-ease-in: all 0.3s ease-out;
|
||||
@transition-ease-out: all 0.3s ease-out;
|
||||
@ease-in: ease-in;
|
||||
|
||||
.text-overflow {
|
||||
overflow: hidden;
|
||||
@@ -28,7 +28,6 @@
|
||||
}
|
||||
|
||||
.background-hover {
|
||||
// transition: @transition-ease-in;
|
||||
&:hover {
|
||||
background-color: @hover-color;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
export type ISupportedLocales = 'en' | 'zh'
|
||||
|
||||
export interface IConfigContext {
|
||||
language: ISupportedLocales
|
||||
setLanguage: (language: ISupportedLocales) => void
|
||||
}
|
||||
|
||||
export interface ILanguageItem {
|
||||
flag: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface ILanguage {
|
||||
[key: string]: ILanguageItem
|
||||
}
|
||||
|
||||
export interface ILanguages {
|
||||
key: string
|
||||
flag: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface IAntdI18nMap {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
export interface ILayouItem {
|
||||
name: string
|
||||
include?: any[]
|
||||
exlude?: any[]
|
||||
}
|
||||
|
||||
export interface IConfig {
|
||||
language: ISupportedLocales
|
||||
title: string
|
||||
logo: string
|
||||
copyright: string
|
||||
layouts: ILayouItem[]
|
||||
}
|
||||
+15
-1
@@ -1,2 +1,16 @@
|
||||
export * from './common'
|
||||
import { ISupportedLocales } from '@/typings'
|
||||
export * from './language'
|
||||
export * from './menu'
|
||||
export interface ILayouItem {
|
||||
name: string
|
||||
include?: any[]
|
||||
exlude?: any[]
|
||||
}
|
||||
|
||||
export interface IConfig {
|
||||
language: ISupportedLocales
|
||||
title: string
|
||||
logo: string
|
||||
copyright: string
|
||||
layouts: ILayouItem[]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export type ISupportedLocales = 'en' | 'zh' | 'pt-br'
|
||||
|
||||
export interface ILanguageItem {
|
||||
flag: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface ILanguage {
|
||||
[key: string]: ILanguageItem
|
||||
}
|
||||
|
||||
export interface ILanguages {
|
||||
key: ISupportedLocales
|
||||
flag: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface IAntdI18nMap {
|
||||
[key: string]: string
|
||||
}
|
||||
+4
-4
@@ -4020,11 +4020,11 @@ let DICT = {
|
||||
990100: '海外',
|
||||
}
|
||||
|
||||
const tree = list => {
|
||||
const tree = (list) => {
|
||||
let hashTable = Object.create(null)
|
||||
list.forEach(aData => (hashTable[aData.id] = { ...aData, children: [] }))
|
||||
list.forEach((aData) => (hashTable[aData.id] = { ...aData, children: [] }))
|
||||
let dataTree = []
|
||||
list.forEach(aData => {
|
||||
list.forEach((aData) => {
|
||||
if (aData.pid) {
|
||||
if (hashTable[aData.pid])
|
||||
hashTable[aData.pid].children.push(hashTable[aData.id])
|
||||
@@ -4033,7 +4033,7 @@ const tree = list => {
|
||||
return dataTree
|
||||
}
|
||||
|
||||
let DICT_FIXED = (function() {
|
||||
let DICT_FIXED = (function () {
|
||||
let fixed = []
|
||||
for (let id in DICT) {
|
||||
if ({}.hasOwnProperty.call(DICT, id)) {
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import React from 'react'
|
||||
import { config } from '@/configs'
|
||||
import { IConfigContext } from '@/typings'
|
||||
import { ISupportedLocales } from '@/typings'
|
||||
|
||||
interface IConfigContext {
|
||||
language: ISupportedLocales
|
||||
setLanguage: (language: ISupportedLocales) => void
|
||||
}
|
||||
|
||||
export const ConfigContext = React.createContext<IConfigContext>({
|
||||
language: config.language,
|
||||
setLanguage: language => null,
|
||||
setLanguage: (language) => null,
|
||||
})
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import {
|
||||
PayCircleOutlined,
|
||||
ShoppingCartOutlined,
|
||||
MessageOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
DashboardOutlined,
|
||||
ApiOutlined,
|
||||
CameraOutlined,
|
||||
EditOutlined,
|
||||
CodeOutlined,
|
||||
LineOutlined,
|
||||
BarChartOutlined,
|
||||
AreaChartOutlined,
|
||||
} from '@ant-design/icons'
|
||||
|
||||
export default {
|
||||
'pay-circle-o': <PayCircleOutlined />,
|
||||
'shopping-cart': <ShoppingCartOutlined />,
|
||||
'camera-o': <CameraOutlined />,
|
||||
'line-chart': <LineOutlined />,
|
||||
'code-o': <CodeOutlined />,
|
||||
'area-chart': <AreaChartOutlined />,
|
||||
'bar-chart': <BarChartOutlined />,
|
||||
message: <MessageOutlined />,
|
||||
team: <TeamOutlined />,
|
||||
dashboard: <DashboardOutlined />,
|
||||
user: <UserOutlined />,
|
||||
api: <ApiOutlined />,
|
||||
edit: <EditOutlined />,
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import axios from 'axios'
|
||||
import { cloneDeep } from 'lodash'
|
||||
const { parse, compile } = require('path-to-regexp')
|
||||
import { message } from 'antd'
|
||||
import { CANCEL_REQUEST_MESSAGE } from '@/utils/constant'
|
||||
const { parse, compile } = require('path-to-regexp')
|
||||
|
||||
const { CancelToken } = axios
|
||||
window.cancelRequest = new Map()
|
||||
|
||||
Reference in New Issue
Block a user