Commit ded1590a authored by 陈帅's avatar 陈帅

fix some warning

parent 190aec4c
This diff is collapsed.
......@@ -4,6 +4,8 @@ module.exports = {
...fabric.default,
rules: {
...fabric.default.rules,
'@typescript-eslint/camelcase': 0,
'@typescript-eslint/class-name-casing': 0,
},
globals: {
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,
......
......@@ -11,16 +11,21 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/accountcenter"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"antd": "^3.16.3",
"classnames": "^2.2.6",
"dva": "^2.4.0",
"moment": "^2.24.0",
"numeral": "^2.0.6",
"react": "^16.6.3",
"react-router": "^5.0.1",
"redux": "^4.0.1",
"umi-request": "^1.0.0"
},
"devDependencies": {
"umi": "^2.6.9",
"umi-plugin-react": "^1.7.2",
"umi-plugin-block-dev": "^1.0.0"
"umi-plugin-block-dev": "^1.0.0",
"umi-plugin-react": "^1.7.2"
},
"license": "ISC",
"blockConfig": {
......
......@@ -3,7 +3,7 @@ import React, { Component } from 'react';
import { connect } from 'dva';
import ArticleListContent from '../ArticleListContent';
import { ListItemDataType } from '../../data';
import { ListItemDataType } from '../../data.d';
import { ModalState } from '../../model';
import styles from './index.less';
......
......@@ -23,7 +23,7 @@ export interface AvatarListProps {
children: React.ReactElement<AvatarItemProps> | React.ReactElement<AvatarItemProps>[];
}
const avatarSizeToClassName = (size?: SizeType) =>
const avatarSizeToClassName = (size?: SizeType | 'mini') =>
classNames(styles.avatarItem, {
[styles.avatarItemLarge]: size === 'large',
[styles.avatarItemSmall]: size === 'small',
......
export interface ITag {
export interface TagType {
key: string;
label: string;
}
export interface IProvince {
export interface ProvinceType {
label: string;
key: string;
}
export interface ICity {
export interface CityType {
label: string;
key: string;
}
export interface IGeographic {
province: IProvince;
city: ICity;
export interface GeographicType {
province: ProvinceType;
city: CityType;
}
export interface INotice {
export interface NoticeType {
id: string;
title: string;
logo: string;
......@@ -33,16 +33,16 @@ export interface CurrentUser {
name: string;
avatar: string;
userid: string;
notice: INotice[];
notice: NoticeType[];
email: string;
signature: string;
title: string;
group: string;
tags: ITag[];
tags: TagType[];
notifyCount: number;
unreadCount: number;
country: string;
geographic: IGeographic;
geographic: GeographicType;
address: string;
phone: string;
}
......
......@@ -10,7 +10,7 @@ import { ModalState } from './model';
import Projects from './components/Projects';
import Articles from './components/Articles';
import Applications from './components/Applications';
import { CurrentUser, ITag } from './data';
import { CurrentUser, TagType } from './data.d';
import styles from './Center.less';
const operationTabList = [
......@@ -46,7 +46,7 @@ interface BLOCK_NAME_CAMEL_CASEProps extends RouteChildrenProps {
currentUserLoading: boolean;
}
interface BLOCK_NAME_CAMEL_CASEState {
newTags: ITag[];
newTags: TagType[];
tabKey: 'articles' | 'applications' | 'projects';
inputVisible: boolean;
inputValue: string;
......@@ -57,7 +57,7 @@ interface BLOCK_NAME_CAMEL_CASEState {
loading,
BLOCK_NAME_CAMEL_CASE,
}: {
loading: { effects: any };
loading: { effects: { [key: string]: boolean } };
BLOCK_NAME_CAMEL_CASE: ModalState;
}) => ({
currentUser: BLOCK_NAME_CAMEL_CASE.currentUser,
......@@ -93,8 +93,6 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent<
tabKey: 'articles',
};
input: Input | null | undefined;
componentDidMount() {
const { dispatch } = this.props;
dispatch({
......@@ -140,6 +138,8 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent<
});
};
public input: Input | null | undefined;
renderChildrenByTabKey = (tabKey: BLOCK_NAME_CAMEL_CASEState['tabKey']) => {
if (tabKey === 'projects') {
return <Projects />;
......
import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { CurrentUser, ListItemDataType } from './data';
import { CurrentUser, ListItemDataType } from './data.d';
import { queryCurrent, queryFakeList } from './service';
export interface ModalState {
......@@ -54,13 +54,13 @@ const Model: ModelType = {
reducers: {
saveCurrentUser(state, action) {
return {
...state!,
...(state as ModalState),
currentUser: action.payload || {},
};
},
queryList(state, action) {
return {
...state!,
...(state as ModalState),
list: action.payload,
};
},
......
......@@ -12,15 +12,18 @@
"dev": "umi dev"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"umi-request": "^1.0.0"
"redux": "^4.0.1",
"umi-request": "^1.0.0",
"umi-plugin-react": "^1.8.4",
"umi": "^2.6.9"
},
"devDependencies": {
"umi": "^2.6.9",
"umi-plugin-block-dev": "^1.0.0",
"umi-plugin-react": "^1.3.0-beta.1"
"umi-plugin-block-dev": "^1.0.0"
},
"blockConfig": {
"specVersion": "0.1"
......
......@@ -3,7 +3,7 @@ import { Select, Spin } from 'antd';
import { Dispatch } from 'redux';
import { connect } from 'dva';
import { CityData, ProvinceData } from '../data';
import { CityType, ProvinceType } from '../data.d';
import styles from './GeographicView.less';
const { Option } = Select;
......@@ -12,15 +12,15 @@ interface SelectItem {
label: string;
key: string;
}
const nullSlectItem: SelectItem = {
const nullSelectItem: SelectItem = {
label: '',
key: '',
};
interface GeographicViewProps {
dispatch?: Dispatch<any>;
province?: ProvinceData[];
city?: CityData[];
province?: ProvinceType[];
city?: CityType[];
value?: {
province: SelectItem;
city: SelectItem;
......@@ -35,8 +35,8 @@ interface GeographicViewProps {
loading,
}: {
BLOCK_NAME_CAMEL_CASE: {
province: ProvinceData[];
city: CityData[];
province: ProvinceType[];
city: CityType[];
};
loading: any;
}) => {
......@@ -87,7 +87,7 @@ class GeographicView extends Component<GeographicViewProps> {
return [];
};
getOption = (list: CityData[] | ProvinceData[]) => {
getOption = (list: CityType[] | ProvinceType[]) => {
if (!list || list.length < 1) {
return (
<Option key={0} value={0}>
......@@ -95,9 +95,9 @@ class GeographicView extends Component<GeographicViewProps> {
</Option>
);
}
return (list as CityData[]).map(item => (
<Option key={item.id} value={item.id}>
{item.name}
return (list as CityType[]).map(item => (
<Option key={item.key} value={item.key}>
{item.label}
</Option>
));
};
......@@ -114,7 +114,7 @@ class GeographicView extends Component<GeographicViewProps> {
if (onChange) {
onChange({
province: item,
city: nullSlectItem,
city: nullSelectItem,
});
}
};
......@@ -133,14 +133,14 @@ class GeographicView extends Component<GeographicViewProps> {
const { value } = this.props;
if (!value) {
return {
province: nullSlectItem,
city: nullSlectItem,
province: nullSelectItem,
city: nullSelectItem,
};
}
const { province, city } = value;
return {
province: province || nullSlectItem,
city: city || nullSlectItem,
province: province || nullSelectItem,
city: city || nullSelectItem,
};
}
......
......@@ -21,15 +21,17 @@ class PhoneView extends PureComponent<PhoneViewProps> {
className={styles.area_code}
value={values[0]}
onChange={e => {
// tslint:disable-next-line: no-unused-expression
onChange && onChange(`${e.target.value}-${values[1]}`);
if (onChange) {
onChange(`${e.target.value}-${values[1]}`);
}
}}
/>
<Input
className={styles.phone_number}
onChange={e => {
// tslint:disable-next-line: no-unused-expression
onChange && onChange(`${values[0]}-${e.target.value}`);
if (onChange) {
onChange(`${values[0]}-${e.target.value}`);
}
}}
value={values[1]}
/>
......
......@@ -4,7 +4,7 @@ import React, { Component, Fragment } from 'react';
import { FormComponentProps } from 'antd/es/form';
import { connect } from 'dva';
import { CurrentUser } from '../data';
import { CurrentUser } from '../data.d';
import GeographicView from './GeographicView';
import PhoneView from './PhoneView';
import styles from './BaseView.less';
......@@ -72,8 +72,6 @@ interface BaseViewProps extends FormComponentProps {
currentUser: BLOCK_NAME_CAMEL_CASE.currentUser,
}))
class BaseView extends Component<BaseViewProps> {
view: HTMLDivElement | undefined;
componentDidMount() {
this.setBaseInfo();
}
......@@ -105,16 +103,18 @@ class BaseView extends Component<BaseViewProps> {
this.view = ref;
};
handlerSubmit = (event: Event) => {
handlerSubmit = (event: React.MouseEvent) => {
event.preventDefault();
const { form } = this.props;
form.validateFields((err, values) => {
form.validateFields(err => {
if (!err) {
message.success(formatMessage({ id: 'BLOCK_NAME.basic.update.success' }));
}
});
};
view: HTMLDivElement | undefined;
render() {
const {
form: { getFieldDecorator },
......
export interface ITag {
export interface TagType {
key: string;
label: string;
}
export interface IProvince {
export interface ProvinceType {
label: string;
key: string;
}
export interface ICity {
export interface CityType {
label: string;
key: string;
}
export interface IGeographic {
province: IProvince;
city: ICity;
export interface GeographicType {
province: ProvinceType;
city: CityType;
}
export interface INotice {
export interface NoticeType {
id: string;
title: string;
logo: string;
......@@ -33,16 +33,16 @@ export interface CurrentUser {
name: string;
avatar: string;
userid: string;
notice: INotice[];
notice: NoticeType[];
email: string;
signature: string;
title: string;
group: string;
tags: ITag[];
tags: TagType[];
notifyCount: number;
unreadCount: number;
country: string;
geographic: IGeographic;
geographic: GeographicType;
address: string;
phone: string;
}
......@@ -7,7 +7,7 @@ import { Menu } from 'antd';
import { connect } from 'dva';
import BaseView from './components/base';
import BindingView from './components/binding';
import { CurrentUser } from './data';
import { CurrentUser } from './data.d';
import NotificationView from './components/notification';
import SecurityView from './components/security';
import styles from './style.less';
......@@ -34,8 +34,6 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<
PAGE_NAME_UPPER_CAMEL_CASEProps,
PAGE_NAME_UPPER_CAMEL_CASEState
> {
main: HTMLDivElement | undefined;
constructor(props: PAGE_NAME_UPPER_CAMEL_CASEProps) {
super(props);
const menuMap = {
......@@ -111,6 +109,8 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<
});
};
main: HTMLDivElement | undefined;
renderChildren = () => {
const { selectKey } = this.state;
switch (selectKey) {
......
......@@ -13,21 +13,25 @@
"dependencies": {
"@ant-design/pro-layout": "^4.5.2",
"@antv/data-set": "^0.10.2",
"@types/lodash.debounce": "^4.0.6",
"antd": "^3.16.3",
"bizcharts": "^3.5.3-beta.0",
"bizcharts-plugin-slider": "^2.1.1-beta.1",
"classnames": "^2.2.6",
"dva": "^2.4.0",
"lodash.debounce": "^4.0.8",
"numeral": "^2.0.6",
"react": "^16.8.6",
"react-fittext": "^1.0.0",
"redux": "^4.0.1",
"umi": "^2.6.9",
"umi-plugin-block-dev": "^1.0.0",
"umi-plugin-react": "^1.7.2",
"umi-request": "^1.0.0"
},
"devDependencies": {
"@types/numeral": "^0.0.25",
"mockjs": "^1.0.1-beta3",
"umi": "^2.6.9",
"umi-plugin-block-dev": "^1.0.0",
"umi-plugin-react": "^1.7.2"
"mockjs": "^1.0.1-beta3"
},
"license": "ISC",
"blockConfig": {
......
import React, { Component } from 'react';
import { Statistic } from 'antd';
import Charts from '../Charts';
import { MiniArea } from '../Charts';
import styles from './index.less';
const { MiniArea } = Charts;
function fixedZero(val: number) {
return val * 1 < 10 ? `0${val}` : val;
}
......@@ -26,10 +24,6 @@ export default class ActiveChart extends Component {
activeData: getActiveData(),
};
timer: number | undefined;
requestRef: number | undefined;
componentDidMount() {
this.loopData();
}
......@@ -56,6 +50,10 @@ export default class ActiveChart extends Component {
});
};
timer: number | undefined;
requestRef: number | undefined;
render() {
const { activeData = [] } = this.state;
......
......@@ -5,7 +5,7 @@ import autoHeight from '../autoHeight';
const { Arc, Html, Line } = Guide;
export interface IGaugeProps {
export interface GaugeProps {
title: React.ReactNode;
color?: string;
height?: number;
......@@ -31,148 +31,149 @@ const defaultFormatter = (val: string): string => {
}
};
Shape.registerShape!('point', 'pointer', {
drawShape(cfg: any, group: any) {
let point = cfg.points[0];
point = (this as any).parsePoint(point);
const center = (this as any).parsePoint({
x: 0,
y: 0,
});
group.addShape('line', {
attrs: {
x1: center.x,
y1: center.y,
x2: point.x,
y2: point.y,
stroke: cfg.color,
lineWidth: 2,
lineCap: 'round',
},
});
return group.addShape('circle', {
attrs: {
x: center.x,
y: center.y,
r: 6,
stroke: cfg.color,
lineWidth: 3,
fill: '#fff',
},
});
},
});
if (Shape.registerShape) {
Shape.registerShape('point', 'pointer', {
drawShape(cfg: any, group: any) {
let point = cfg.points[0];
point = (this as any).parsePoint(point);
const center = (this as any).parsePoint({
x: 0,
y: 0,
});
group.addShape('line', {
attrs: {
x1: center.x,
y1: center.y,
x2: point.x,
y2: point.y,
stroke: cfg.color,
lineWidth: 2,
lineCap: 'round',
},
});
return group.addShape('circle', {
attrs: {
x: center.x,
y: center.y,
r: 6,
stroke: cfg.color,
lineWidth: 3,
fill: '#fff',
},
});
},
});
}
const Gauge: React.FC<GaugeProps> = props => {
const {
title,
height = 1,
percent,
forceFit = true,
formatter = defaultFormatter,
color = '#2F9CFF',
bgColor = '#F0F2F5',
} = props;
const cols = {
value: {
type: 'linear',
min: 0,
max: 10,
tickCount: 6,
nice: true,
},
};
const data = [{ value: percent / 10 }];
class Gauge extends React.Component<IGaugeProps> {
render() {
const {
title,
height = 1,
percent,
forceFit = true,
formatter = defaultFormatter,
color = '#2F9CFF',
bgColor = '#F0F2F5',
} = this.props;
const cols = {
value: {
type: 'linear',
min: 0,
max: 10,
tickCount: 6,
nice: true,
},
};
const renderHtml = () => `
const renderHtml = () => `
<div style="width: 300px;text-align: center;font-size: 12px!important;">
<p style="font-size: 14px; color: rgba(0,0,0,0.43);margin: 0;">${title}</p>
<p style="font-size: 24px;color: rgba(0,0,0,0.85);margin: 0;">
${(data[0].value * 10).toFixed(2)}%
</p>
</div>`;
const data = [{ value: percent / 10 }];
const textStyle: {
fontSize: number;
fill: string;
textAlign: 'center';
} = {
fontSize: 12,
fill: 'rgba(0, 0, 0, 0.65)',
textAlign: 'center',
};
return (
<Chart height={height} data={data} scale={cols} padding={[-16, 0, 16, 0]} forceFit={forceFit}>
<Coord type="polar" startAngle={-1.25 * Math.PI} endAngle={0.25 * Math.PI} radius={0.8} />
<Axis name="1" line={undefined} />
<Axis
line={undefined}
tickLine={undefined}
subTickLine={undefined}
name="value"
zIndex={2}
label={{
offset: -12,
formatter,
textStyle,
const textStyle: {
fontSize: number;
fill: string;
textAlign: 'center';
} = {
fontSize: 12,
fill: 'rgba(0, 0, 0, 0.65)',
textAlign: 'center',
};
return (
<Chart height={height} data={data} scale={cols} padding={[-16, 0, 16, 0]} forceFit={forceFit}>
<Coord type="polar" startAngle={-1.25 * Math.PI} endAngle={0.25 * Math.PI} radius={0.8} />
<Axis name="1" line={undefined} />
<Axis
line={undefined}
tickLine={undefined}
subTickLine={undefined}
name="value"
zIndex={2}
label={{
offset: -12,
formatter,
textStyle,
}}
/>
<Guide>
<Line
start={[3, 0.905]}
end={[3, 0.85]}
lineStyle={{
stroke: color,
lineDash: undefined,
lineWidth: 2,
}}
/>
<Guide>
<Line
start={[3, 0.905]}
end={[3, 0.85]}
lineStyle={{
stroke: color,
lineDash: undefined,
lineWidth: 2,
}}
/>
<Line
start={[5, 0.905]}
end={[5, 0.85]}
lineStyle={{
stroke: color,
lineDash: undefined,
lineWidth: 3,
}}
/>
<Line
start={[7, 0.905]}
end={[7, 0.85]}
lineStyle={{
stroke: color,
lineDash: undefined,
lineWidth: 3,
}}
/>
<Arc
start={[0, 0.965]}
end={[10, 0.965]}
style={{
stroke: bgColor,
lineWidth: 10,
}}
/>
<Arc
start={[0, 0.965]}
end={[data[0].value, 0.965]}
style={{
stroke: color,
lineWidth: 10,
}}
/>
<Html position={['50%', '95%']} html={renderHtml()} />
</Guide>
<Geom
line={false}
type="point"
position="value*1"
shape="pointer"
color={color}
active={false}
<Line
start={[5, 0.905]}
end={[5, 0.85]}
lineStyle={{
stroke: color,
lineDash: undefined,
lineWidth: 3,
}}
/>
</Chart>
);
}
}
<Line
start={[7, 0.905]}
end={[7, 0.85]}
lineStyle={{
stroke: color,
lineDash: undefined,
lineWidth: 3,
}}
/>
<Arc
start={[0, 0.965]}
end={[10, 0.965]}
style={{
stroke: bgColor,
lineWidth: 10,
}}
/>
<Arc
start={[0, 0.965]}
end={[data[0].value, 0.965]}
style={{
stroke: color,
lineWidth: 10,
}}
/>
<Html position={['50%', '95%']} html={renderHtml()} />
</Guide>
<Geom
line={false}
type="point"
position="value*1"
shape="pointer"
color={color}
active={false}
/>
</Chart>
);
};
export default autoHeight()(Gauge);
import { Axis, Chart, Geom, Tooltip } from 'bizcharts';
import { Axis, AxisProps, Chart, Geom, Tooltip } from 'bizcharts';
import React from 'react';
import autoHeight from '../autoHeight';
import styles from '../index.less';
export interface IAxis {
title: any;
line: any;
gridAlign: any;
labels: any;
tickLine: any;
grid: any;
label: any;
}
export interface IMiniAreaProps {
export interface MiniAreaProps {
color?: string;
height?: number;
borderColor?: string;
line?: boolean;
animate?: boolean;
xAxis?: IAxis;
xAxis?: AxisProps;
forceFit?: boolean;
scale?: { x?: any; y?: any };
yAxis?: Partial<IAxis>;
scale?: {
x?: {
tickCount: number;
};
y?: {
tickCount: number;
};
};
yAxis?: Partial<AxisProps>;
borderWidth?: number;
data: {
x: number | string;
......@@ -31,105 +28,105 @@ export interface IMiniAreaProps {
}[];
}
class MiniArea extends React.Component<IMiniAreaProps> {
render() {
const {
height = 1,
data = [],
forceFit = true,
color = 'rgba(24, 144, 255, 0.2)',
borderColor = '#1089ff',
scale = { x: {}, y: {} },
borderWidth = 2,
line,
xAxis,
yAxis,
animate = true,
} = this.props;
const MiniArea: React.FC<MiniAreaProps> = props => {
const {
height = 1,
data = [],
forceFit = true,
color = 'rgba(24, 144, 255, 0.2)',
borderColor = '#1089ff',
scale = { x: {}, y: {} },
borderWidth = 2,
line,
xAxis,
yAxis,
animate = true,
} = props;
const padding: [number, number, number, number] = [36, 5, 30, 5];
console.log(props);
const scaleProps = {
x: {
type: 'cat',
range: [0, 1],
...scale!.x,
},
y: {
min: 0,
...scale!.y,
},
};
const padding: [number, number, number, number] = [36, 5, 30, 5];
const tooltip: [string, (...args: any[]) => { name?: string; value: string }] = [
'x*y',
(x: string, y: string) => ({
name: x,
value: y,
}),
];
const scaleProps = {
x: {
type: 'cat',
range: [0, 1],
...scale.x,
},
y: {
min: 0,
...scale.y,
},
};
const chartHeight = height + 54;
const tooltip: [string, (...args: any[]) => { name?: string; value: string }] = [
'x*y',
(x: string, y: string) => ({
name: x,
value: y,
}),
];
return (
<div className={styles.miniChart} style={{ height }}>
<div className={styles.chartContent}>
{height > 0 && (
<Chart
animate={animate}
scale={scaleProps}
height={chartHeight}
forceFit={forceFit}
data={data}
padding={padding}
>
<Axis
key="axis-x"
name="x"
label={false}
line={false}
tickLine={false}
grid={false}
{...xAxis}
/>
<Axis
key="axis-y"
name="y"
label={false}
line={false}
tickLine={false}
grid={false}
{...yAxis}
/>
<Tooltip showTitle={false} crosshairs={false} />
const chartHeight = height + 54;
return (
<div className={styles.miniChart} style={{ height }}>
<div className={styles.chartContent}>
{height > 0 && (
<Chart
animate={animate}
scale={scaleProps}
height={chartHeight}
forceFit={forceFit}
data={data}
padding={padding}
>
<Axis
key="axis-x"
name="x"
label={null}
line={null}
tickLine={null}
grid={null}
{...xAxis}
/>
<Axis
key="axis-y"
name="y"
label={null}
line={null}
tickLine={null}
grid={null}
{...yAxis}
/>
<Tooltip showTitle={false} crosshairs={false} />
<Geom
type="area"
position="x*y"
color={color}
tooltip={tooltip}
shape="smooth"
style={{
fillOpacity: 1,
}}
/>
{line ? (
<Geom
type="area"
type="line"
position="x*y"
color={color}
tooltip={tooltip}
shape="smooth"
style={{
fillOpacity: 1,
}}
color={borderColor}
size={borderWidth}
tooltip={false}
/>
{line ? (
<Geom
type="line"
position="x*y"
shape="smooth"
color={borderColor}
size={borderWidth}
tooltip={false}
/>
) : (
<span style={{ display: 'none' }} />
)}
</Chart>
)}
</div>
) : (
<span style={{ display: 'none' }} />
)}
</Chart>
)}
</div>
);
}
}
</div>
);
};
export default autoHeight()(MiniArea);
import { Chart, Coord, Geom, Tooltip } from 'bizcharts';
import React, { Component } from 'react';
import Bind from 'lodash-decorators/bind';
import { DataView } from '@antv/data-set';
import Debounce from 'lodash-decorators/debounce';
import Debounce from 'lodash.debounce';
import { Divider } from 'antd';
import ReactFitText from 'react-fittext';
import classNames from 'classnames';
import autoHeight from '../autoHeight';
import styles from './index.less';
export interface IPieProps {
export interface PieProps {
animate?: boolean;
color?: string;
colors?: string[];
......@@ -35,21 +34,40 @@ export interface IPieProps {
valueFormat?: (value: string) => string | React.ReactNode;
subTitle?: React.ReactNode;
}
interface IPieState {
interface PieState {
legendData: { checked: boolean; x: string; color: string; percent: number; y: string }[];
legendBlock: boolean;
}
class Pie extends Component<IPieProps, IPieState> {
state: IPieState = {
class Pie extends Component<PieProps, PieState> {
state: PieState = {
legendData: [],
legendBlock: false,
};
requestRef: number | undefined;
root!: HTMLDivElement;
chart: G2.Chart | undefined;
// for window resize auto responsive legend
resize = Debounce(() => {
const { hasLegend } = this.props;
const { legendBlock } = this.state;
if (!hasLegend || !this.root) {
window.removeEventListener('resize', this.resize);
return;
}
if (
this.root &&
this.root.parentNode &&
(this.root.parentNode as HTMLElement).clientWidth <= 380
) {
if (!legendBlock) {
this.setState({
legendBlock: true,
});
}
} else if (legendBlock) {
this.setState({
legendBlock: false,
});
}
}, 300);
componentDidMount() {
window.addEventListener(
......@@ -61,7 +79,7 @@ class Pie extends Component<IPieProps, IPieState> {
);
}
componentDidUpdate(preProps: IPieProps) {
componentDidUpdate(preProps: PieProps) {
const { data } = this.props;
if (data !== preProps.data) {
// because of charts data create when rendered
......@@ -93,7 +111,8 @@ class Pie extends Component<IPieProps, IPieState> {
if (!this.chart) return;
const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形
if (!geom) return;
const items = geom.get('dataArray') || []; // 获取图形对应的
// g2 的类型有问题
const items = (geom as any).get('dataArray') || []; // 获取图形对应的
const legendData = items.map((item: { color: any; _origin: any }[]) => {
/* eslint no-underscore-dangle:0 */
......@@ -112,7 +131,7 @@ class Pie extends Component<IPieProps, IPieState> {
this.root = n;
};
handleLegendClick = (item: any, i: string | number) => {
handleLegendClick = (item: { checked: boolean }, i: string | number) => {
const newItem = item;
newItem.checked = !newItem.checked;
......@@ -130,32 +149,11 @@ class Pie extends Component<IPieProps, IPieState> {
});
};
// for window resize auto responsive legend
@Bind()
@Debounce(300)
resize() {
const { hasLegend } = this.props;
const { legendBlock } = this.state;
if (!hasLegend || !this.root) {
window.removeEventListener('resize', this.resize);
return;
}
if (
this.root &&
this.root.parentNode &&
(this.root.parentNode as HTMLElement).clientWidth <= 380
) {
if (!legendBlock) {
this.setState({
legendBlock: true,
});
}
} else if (legendBlock) {
this.setState({
legendBlock: false,
});
}
}
root!: HTMLDivElement;
chart: G2.Chart | undefined;
requestRef: number | undefined;
render() {
const {
......
import { Chart, Coord, Geom, Shape, Tooltip } from 'bizcharts';
import React, { Component } from 'react';
import Bind from 'lodash-decorators/bind';
import DataSet from '@antv/data-set';
import Debounce from 'lodash-decorators/debounce';
import Debounce from 'lodash.debounce';
import classNames from 'classnames';
import autoHeight from '../autoHeight';
import styles from './index.less';
......@@ -13,7 +12,7 @@ import styles from './index.less';
const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png';
export interface ITagCloudProps {
export interface TagCloudProps {
data: {
name: string;
value: string;
......@@ -23,27 +22,19 @@ export interface ITagCloudProps {
style?: React.CSSProperties;
}
interface ITagCloudState {
interface TagCloudState {
dv: any;
height?: number;
width: number;
}
class TagCloud extends Component<ITagCloudProps, ITagCloudState> {
class TagCloud extends Component<TagCloudProps, TagCloudState> {
state = {
dv: null,
height: 0,
width: 0,
};
isUnmount!: boolean;
requestRef!: number;
root: HTMLDivElement | undefined;
imageMask: HTMLImageElement | undefined;
componentDidMount() {
requestAnimationFrame(() => {
this.initTagCloud();
......@@ -52,7 +43,7 @@ class TagCloud extends Component<ITagCloudProps, ITagCloudState> {
window.addEventListener('resize', this.resize, { passive: true });
}
componentDidUpdate(preProps?: ITagCloudProps) {
componentDidUpdate(preProps?: TagCloudProps) {
const { data } = this.props;
if (preProps && JSON.stringify(preProps.data) !== JSON.stringify(data)) {
this.renderChart(this.props);
......@@ -112,9 +103,15 @@ class TagCloud extends Component<ITagCloudProps, ITagCloudState> {
});
};
@Bind()
@Debounce(500)
renderChart(nextProps: ITagCloudProps) {
isUnmount!: boolean;
requestRef!: number;
root: HTMLDivElement | undefined;
imageMask: HTMLImageElement | undefined;
renderChart = Debounce((nextProps: TagCloudProps) => {
// const colors = ['#1890FF', '#41D9C7', '#2FC25B', '#FACC14', '#9AE65C'];
const { data, height } = nextProps || this.props;
if (data.length < 1 || !this.root) {
......@@ -140,8 +137,8 @@ class TagCloud extends Component<ITagCloudProps, ITagCloudState> {
return 0;
},
fontSize(d: { value: number }) {
// eslint-disable-next-line
return Math.pow((d.value - min) / (max - min), 2) * (17.5 - 5) + 5;
const size = ((d.value - min) / (max - min)) ** 2;
return size * (17.5 - 5) + 5;
},
});
......@@ -165,7 +162,7 @@ class TagCloud extends Component<ITagCloudProps, ITagCloudState> {
} else {
onload();
}
}
}, 200);
render() {
const { className, height } = this.props;
......
......@@ -7,7 +7,7 @@ import styles from './index.less';
/* eslint no-mixed-operators: 0 */
// riddle: https://riddle.alibaba-inc.com/riddles/2d9a4b90
export interface IWaterWaveProps {
export interface WaterWaveProps {
title: React.ReactNode;
color?: string;
height?: number;
......@@ -15,16 +15,16 @@ export interface IWaterWaveProps {
style?: React.CSSProperties;
}
class WaterWave extends Component<IWaterWaveProps> {
class WaterWave extends Component<WaterWaveProps> {
state = {
radio: 1,
};
timer: number = 0;
root: HTMLDivElement | undefined | null;
root: HTMLDivElement | undefined | null = null;
node: HTMLCanvasElement | undefined | null;
node: HTMLCanvasElement | undefined | null = null;
componentDidMount() {
this.renderChart();
......@@ -38,7 +38,7 @@ class WaterWave extends Component<IWaterWaveProps> {
);
}
componentDidUpdate(props: IWaterWaveProps) {
componentDidUpdate(props: WaterWaveProps) {
const { percent } = this.props;
if (props.percent !== percent) {
// 不加这个会造成绘制缓慢
......
......@@ -6,7 +6,8 @@ export type IReactComponent<P = any> =
| React.ClassicComponentClass<P>;
function computeHeight(node: HTMLDivElement) {
node.style.height = '100%';
const { style } = node;
style.height = '100%';
const totalHeight = parseInt(`${getComputedStyle(node).height}`, 10);
const padding =
parseInt(`${getComputedStyle(node).paddingTop}`, 10) +
......@@ -30,24 +31,24 @@ function getAutoHeight(n: HTMLDivElement) {
return height;
}
interface IAutoHeightProps {
interface AutoHeightProps {
height?: number;
}
function autoHeight() {
return function<P extends IAutoHeightProps> (
return <P extends AutoHeightProps>(
WrappedComponent: React.ComponentClass<P> | React.SFC<P>,
): React.ComponentClass<P> {
class AutoHeightComponent extends React.Component<P & IAutoHeightProps> {
): React.ComponentClass<P> => {
class AutoHeightComponent extends React.Component<P & AutoHeightProps> {
state = {
computedHeight: 0,
};
root!: HTMLDivElement;
root: HTMLDivElement | null = null;
componentDidMount() {
const { height } = this.props;
if (!height) {
if (!height && this.root) {
let h = getAutoHeight(this.root);
this.setState({ computedHeight: h });
if (h < 1) {
......
export interface ITag {
export interface TagType {
name: string;
value: string;
type: string;
......
......@@ -6,19 +6,17 @@ import { Dispatch } from 'redux';
import { GridContent } from '@ant-design/pro-layout';
import { connect } from 'dva';
import numeral from 'numeral';
import { IStateType } from './model';
import Charts from './components/Charts';
import { StateType } from './model';
import { Pie, WaterWave, Gauge, TagCloud } from './components/Charts';
import ActiveChart from './components/ActiveChart';
import styles from './style.less';
const { Countdown } = Statistic;
const { Pie, WaterWave, Gauge, TagCloud } = Charts;
const targetTime = new Date().getTime() + 3900000;
interface PAGE_NAME_UPPER_CAMEL_CASEProps {
BLOCK_NAME_CAMEL_CASE: IStateType;
BLOCK_NAME_CAMEL_CASE: StateType;
dispatch: Dispatch<any>;
loading: boolean;
}
......@@ -28,7 +26,7 @@ interface PAGE_NAME_UPPER_CAMEL_CASEProps {
BLOCK_NAME_CAMEL_CASE,
loading,
}: {
BLOCK_NAME_CAMEL_CASE: IStateType;
BLOCK_NAME_CAMEL_CASE: StateType;
loading: {
models: { [key: string]: boolean };
};
......
import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { ITag } from './data';
import { TagType } from './data.d';
import { queryTags } from './service';
export interface IStateType {
tags: ITag[];
export interface StateType {
tags: TagType[];
}
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap & { select: <T>(func: (state: IStateType) => T) => T },
effects: EffectsCommandMap & { select: <T>(func: (state: StateType) => T) => T },
) => void;
export interface ModelType {
namespace: string;
state: IStateType;
state: StateType;
effects: {
fetchTags: Effect;
};
reducers: {
saveTags: Reducer<IStateType>;
saveTags: Reducer<StateType>;
};
}
......
......@@ -11,13 +11,15 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/workplace"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"antd": "^3.16.3",
"bizcharts": "^3.5.3-beta.0",
"dva": "^2.4.0",
"moment": "^2.22.2",
"prop-types": "^15.5.10",
"react": "^16.6.3",
"umi-request": "^1.0.0",
"bizcharts": "^3.5.3-beta.0"
"redux": "^4.0.1",
"umi-request": "^1.0.0"
},
"devDependencies": {
"umi": "^2.6.9",
......
......@@ -6,7 +6,8 @@ export type IReactComponent<P = any> =
| React.ClassicComponentClass<P>;
function computeHeight(node: HTMLDivElement) {
node.style.height = '100%';
const { style } = node;
style.height = '100%';
const totalHeight = parseInt(`${getComputedStyle(node).height}`, 10);
const padding =
parseInt(`${getComputedStyle(node).paddingTop}`, 10) +
......@@ -30,26 +31,23 @@ function getAutoHeight(n: HTMLDivElement) {
return height;
}
interface IAutoHeightProps {
interface AutoHeightProps {
height?: number;
}
function autoHeight() {
return function<P extends IAutoHeightProps> (
return <P extends AutoHeightProps>(
WrappedComponent: React.ComponentClass<P> | React.SFC<P>,
): React.ComponentClass<P> {
class AutoHeightComponent extends React.Component<P & IAutoHeightProps> {
): React.ComponentClass<P> => {
class AutoHeightComponent extends React.Component<P & AutoHeightProps> {
state = {
computedHeight: 0,
};
root!: HTMLDivElement;
componentDidMount() {
const { height } = this.props;
if (!height) {
let h = getAutoHeight(this.root);
// eslint-disable-next-line
this.setState({ computedHeight: h });
if (h < 1) {
h = getAutoHeight(this.root);
......@@ -62,6 +60,8 @@ function autoHeight() {
this.root = node;
};
root!: HTMLDivElement;
render() {
const { height } = this.props;
const { computedHeight } = this.state;
......
export interface ITag {
export interface TagType {
key: string;
label: string;
}
export interface IProvince {
export interface ProvinceType {
label: string;
key: string;
}
export interface ICity {
export interface CityType {
label: string;
key: string;
}
export interface IGeographic {
province: IProvince;
city: ICity;
export interface GeographicType {
province: ProvinceType;
city: CityType;
}
export interface INotice {
export interface NoticeType {
id: string;
title: string;
logo: string;
......@@ -29,30 +29,30 @@ export interface INotice {
memberLink: string;
}
export interface ICurrentUser {
export interface CurrentUser {
name: string;
avatar: string;
userid: string;
notice: INotice[];
notice: NoticeType[];
email: string;
signature: string;
title: string;
group: string;
tags: ITag[];
tags: TagType[];
notifyCount: number;
unreadCount: number;
country: string;
geographic: IGeographic;
geographic: GeographicType;
address: string;
phone: string;
}
export interface IMember {
export interface Member {
avatar: string;
name: string;
id: string;
}
export interface IActivities {
export interface ActivitiesType {
id: string;
updatedAt: string;
user: {
......@@ -71,7 +71,7 @@ export interface IActivities {
template: string;
}
export interface IRadarData {
export interface RadarDataType {
label: string;
name: string;
value: number;
......
......@@ -9,8 +9,8 @@ import moment from 'moment';
import Radar from './components/Radar';
import { ModalState } from './model';
import EditableLinkGroup from './components/EditableLinkGroup';
import { IActivities, ICurrentUser, INotice, IRadarData } from './data';
import styles from './style.less';
import { ActivitiesType, CurrentUser, NoticeType, RadarDataType } from './data.d';
const links = [
{
......@@ -40,10 +40,10 @@ const links = [
];
interface BLOCK_NAME_CAMEL_CASEProps {
currentUser: ICurrentUser;
projectNotice: INotice[];
activities: IActivities[];
radarData: IRadarData[];
currentUser: CurrentUser;
projectNotice: NoticeType[];
activities: ActivitiesType[];
radarData: RadarDataType[];
dispatch: Dispatch<any>;
currentUserLoading: boolean;
projectLoading: boolean;
......@@ -82,7 +82,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent<BLOCK_NAME_CAMEL_CASEProp
});
}
renderActivities(item: IActivities) {
renderActivities = (item: ActivitiesType) => {
const events = item.template.split(/@\{([^{}]*)\}/gi).map(key => {
if (item[key]) {
return (
......@@ -112,7 +112,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent<BLOCK_NAME_CAMEL_CASEProp
/>
</List.Item>
);
}
};
render() {
const {
......@@ -206,7 +206,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent<BLOCK_NAME_CAMEL_CASEProp
title="动态"
loading={activitiesLoading}
>
<List<IActivities>
<List<ActivitiesType>
loading={activitiesLoading}
renderItem={item => this.renderActivities(item)}
dataSource={activities}
......
import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { Activeties, CurrentUser, Notice, RadarData } from './data';
import { Activeties, CurrentUser, Notice, RadarData } from './data.d';
import { fakeChartData, queryActivities, queryCurrent, queryProjectNotice } from './service';
export interface ModalState {
......
......@@ -12,6 +12,7 @@
"dev": "umi dev"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"@antv/data-set": "^0.10.2",
"antd": "^3.16.3",
"bizcharts": "^3.5.3-beta.0",
......@@ -22,13 +23,13 @@
"numeral": "^2.0.6",
"react": "^16.6.3",
"react-fittext": "^1.0.0",
"umi": "^2.6.9",
"umi-plugin-react": "^1.7.2",
"umi-request": "^1.0.0"
},
"devDependencies": {
"umi": "^2.6.9",
"umi-plugin-block-dev": "^1.1.0",
"umi-plugin-react": "^1.7.2",
"@types/numeral": "^0.0.25"
"@types/numeral": "^0.0.25",
"umi-plugin-block-dev": "^1.1.0"
},
"blockConfig": {
"specVersion": "0.1"
......
......@@ -12,6 +12,7 @@
"dev": "umi dev"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"@antv/data-set": "^0.10.2",
"antd": "^3.16.3",
"bizcharts": "^3.5.3-beta.0",
......@@ -22,13 +23,14 @@
"numeral": "^2.0.6",
"react": "^16.6.3",
"react-fittext": "^1.0.0",
"umi-request": "^1.0.0"
"umi-request": "^1.0.0",
"umi-plugin-react": "^1.7.2",
"umi-plugin-block-dev": "^1.1.0"
},
"devDependencies": {
"umi": "^2.6.9",
"umi-plugin-block-dev": "^1.1.0",
"umi-plugin-react": "^1.7.2",
"@types/numeral": "^0.0.25"
"@types/numeral": "^0.0.25",
"umi": "^2.6.9"
},
"blockConfig": {
"specVersion": "0.1"
......
......@@ -12,6 +12,7 @@
"dev": "umi dev"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"@antv/data-set": "^0.10.2",
"antd": "^3.16.3",
"bizcharts": "^3.5.3-beta.0",
......@@ -22,13 +23,13 @@
"numeral": "^2.0.6",
"react": "^16.6.3",
"react-fittext": "^1.0.0",
"umi-plugin-react": "^1.7.2",
"umi-request": "^1.0.0"
},
"devDependencies": {
"@types/numeral": "^0.0.25",
"umi": "^2.6.9",
"umi-plugin-block-dev": "^1.1.0",
"umi-plugin-react": "^1.7.2",
"@types/numeral": "^0.0.25"
"umi-plugin-block-dev": "^1.1.0"
},
"blockConfig": {
"specVersion": "0.1"
......
......@@ -12,10 +12,14 @@
"dev": "umi dev"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"@types/lodash": "^4.14.134",
"antd": "^3.16.3",
"classnames": "^2.2.6",
"dva": "^2.4.0",
"lodash": "^4.17.10",
"react": "^16.6.3",
"redux": "^4.0.1",
"umi-request": "^1.0.0"
},
"devDependencies": {
......
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import styles from './index.less';
......@@ -11,10 +10,6 @@ export interface FooterToolbarProps {
}
export default class FooterToolbar extends Component<FooterToolbarProps> {
static contextTypes = {
isMobile: PropTypes.bool,
};
state = {
width: undefined,
};
......
......@@ -4,8 +4,27 @@ import React, { Fragment, PureComponent } from 'react';
import { isEqual } from 'lodash';
import styles from '../style.less';
class TableForm extends PureComponent {
static getDerivedStateFromProps(nextProps, preState) {
interface TableFormDateType {
key: string;
workId?: string;
name?: string;
department?: string;
isNew?: boolean;
editable?: boolean;
}
interface TableFormProps {
loading?: boolean;
value?: TableFormDateType[];
onChange?: (value: TableFormDateType[]) => void;
}
interface TableFormState {
loading?: boolean;
value?: TableFormDateType[];
data?: TableFormDateType[];
}
class TableForm extends PureComponent<TableFormProps, TableFormState> {
static getDerivedStateFromProps(nextProps: TableFormProps, preState: TableFormState) {
if (isEqual(nextProps.value, preState.value)) {
return null;
}
......@@ -15,6 +34,8 @@ class TableForm extends PureComponent {
};
}
clickedCancel: boolean = false;
index = 0;
cacheOriginData = {};
......@@ -25,7 +46,7 @@ class TableForm extends PureComponent {
dataIndex: 'name',
key: 'name',
width: '20%',
render: (text, record) => {
render: (text: string, record: TableFormDateType) => {
if (record.editable) {
return (
<Input
......@@ -45,7 +66,7 @@ class TableForm extends PureComponent {
dataIndex: 'workId',
key: 'workId',
width: '20%',
render: (text, record) => {
render: (text: string, record: TableFormDateType) => {
if (record.editable) {
return (
<Input
......@@ -64,7 +85,7 @@ class TableForm extends PureComponent {
dataIndex: 'department',
key: 'department',
width: '40%',
render: (text, record) => {
render: (text: string, record: TableFormDateType) => {
if (record.editable) {
return (
<Input
......@@ -81,7 +102,7 @@ class TableForm extends PureComponent {
{
title: '操作',
key: 'action',
render: (text, record) => {
render: (text: string, record: TableFormDateType) => {
const { loading } = this.state;
if (!!record.editable && loading) {
return null;
......@@ -119,25 +140,23 @@ class TableForm extends PureComponent {
},
];
constructor(props) {
constructor(props: TableFormProps) {
super(props);
this.state = {
data: props.value,
loading: false,
/* eslint-disable-next-line react/no-unused-state */
value: props.value,
};
}
getRowByKey(key, newData) {
const { data } = this.state;
getRowByKey(key: string, newData?: TableFormDateType[]) {
const { data = [] } = this.state;
return (newData || data).filter(item => item.key === key)[0];
}
toggleEditable = (e, key) => {
toggleEditable = (e: React.MouseEvent | React.KeyboardEvent, key: string) => {
e.preventDefault();
const { data } = this.state;
const { data = [] } = this.state;
const newData = data.map(item => ({ ...item }));
const target = this.getRowByKey(key, newData);
if (target) {
......@@ -151,7 +170,7 @@ class TableForm extends PureComponent {
};
newMember = () => {
const { data } = this.state;
const { data = [] } = this.state;
const newData = data.map(item => ({ ...item }));
newData.push({
key: `NEW_TEMP_ID_${this.index}`,
......@@ -165,22 +184,24 @@ class TableForm extends PureComponent {
this.setState({ data: newData });
};
remove(key) {
const { data } = this.state;
remove(key: string) {
const { data = [] } = this.state;
const { onChange } = this.props;
const newData = data.filter(item => item.key !== key);
this.setState({ data: newData });
onChange(newData);
if (onChange) {
onChange(newData);
}
}
handleKeyPress(e, key) {
handleKeyPress(e: React.KeyboardEvent, key: string) {
if (e.key === 'Enter') {
this.saveRow(e, key);
}
}
handleFieldChange(e, fieldName, key) {
const { data } = this.state;
handleFieldChange(e: React.ChangeEvent<HTMLInputElement>, fieldName: string, key: string) {
const { data = [] } = this.state;
const newData = data.map(item => ({ ...item }));
const target = this.getRowByKey(key, newData);
if (target) {
......@@ -189,7 +210,7 @@ class TableForm extends PureComponent {
}
}
saveRow(e, key) {
saveRow(e: React.MouseEvent | React.KeyboardEvent, key: string) {
e.persist();
this.setState({
loading: true,
......@@ -202,7 +223,7 @@ class TableForm extends PureComponent {
const target = this.getRowByKey(key) || {};
if (!target.workId || !target.name || !target.department) {
message.error('请填写完整成员信息。');
e.target.focus();
(e.target as HTMLInputElement).focus();
this.setState({
loading: false,
});
......@@ -210,19 +231,21 @@ class TableForm extends PureComponent {
}
delete target.isNew;
this.toggleEditable(e, key);
const { data } = this.state;
const { data = [] } = this.state;
const { onChange } = this.props;
onChange(data);
if (onChange) {
onChange(data);
}
this.setState({
loading: false,
});
}, 500);
}
cancel(e, key) {
cancel(e: React.MouseEvent, key: string) {
this.clickedCancel = true;
e.preventDefault();
const { data } = this.state;
const { data = [] } = this.state;
const newData = data.map(item => ({ ...item }));
const target = this.getRowByKey(key, newData);
if (this.cacheOriginData[key]) {
......@@ -239,7 +262,7 @@ class TableForm extends PureComponent {
return (
<Fragment>
<Table
<Table<TableFormDateType>
loading={loading}
columns={this.columns}
dataSource={data}
......
......@@ -11,15 +11,16 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/basicform"
},
"dependencies": {
"@ant-design/pro-layout": "^4.0.5",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"redux": "^4.0.1",
"umi-request": "^1.0.0",
"@ant-design/pro-layout": "^4.0.5"
"umi-plugin-react": "^1.7.2"
},
"devDependencies": {
"umi": "^2.6.9",
"umi-plugin-react": "^1.7.2",
"umi-plugin-block-dev": "^1.0.0"
},
"license": "ISC",
......
......@@ -11,16 +11,18 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/stepform"
},
"dependencies": {
"@ant-design/pro-layout": "^4.5.5",
"antd": "^3.16.3",
"dva": "^2.4.0",
"nzh": "^1.0.3",
"react": "^16.6.3",
"umi-request": "^1.0.0",
"nzh": "^1.0.3"
"redux": "^4.0.1",
"umi-request": "^1.0.0"
},
"devDependencies": {
"umi": "^2.6.9",
"umi-plugin-react": "^1.7.2",
"umi-plugin-block-dev": "^1.0.0"
"umi-plugin-block-dev": "^1.0.0",
"umi-plugin-react": "^1.7.2"
},
"license": "ISC",
"blockConfig": {
......
......@@ -4,7 +4,7 @@ import React, { Fragment } from 'react';
import { Dispatch } from 'redux';
import { FormComponentProps } from 'antd/es/form';
import { connect } from 'dva';
import { IStateType } from '../../model';
import { StateType } from '../../model';
import styles from './index.less';
const { Option } = Select;
......@@ -18,109 +18,107 @@ const formItemLayout = {
},
};
interface Step1Props extends FormComponentProps {
data?: IStateType['step'];
data?: StateType['step'];
dispatch?: Dispatch<any>;
}
class Step1 extends React.PureComponent<Step1Props> {
render() {
const { form, dispatch, data } = this.props;
if (!data) {
return;
}
const { getFieldDecorator, validateFields } = form;
const onValidateForm = () => {
validateFields((err, values) => {
if (!err && dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveStepFormData',
payload: values,
});
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep',
payload: 'confirm',
});
}
});
};
return (
<Fragment>
<Form layout="horizontal" className={styles.stepForm} hideRequiredMark>
<Form.Item {...formItemLayout} label="付款账户">
{getFieldDecorator('payAccount', {
initialValue: data.payAccount,
rules: [{ required: true, message: '请选择付款账户' }],
})(
<Select placeholder="test@example.com">
<Option value="ant-design@alipay.com">ant-design@alipay.com</Option>
</Select>,
)}
</Form.Item>
<Form.Item {...formItemLayout} label="收款账户">
<Input.Group compact>
<Select defaultValue="alipay" style={{ width: 100 }}>
<Option value="alipay">支付宝</Option>
<Option value="bank">银行账户</Option>
</Select>
{getFieldDecorator('receiverAccount', {
initialValue: data.receiverAccount,
rules: [
{ required: true, message: '请输入收款人账户' },
{ type: 'email', message: '账户名应为邮箱格式' },
],
})(<Input style={{ width: 'calc(100% - 100px)' }} placeholder="test@example.com" />)}
</Input.Group>
</Form.Item>
<Form.Item {...formItemLayout} label="收款人姓名">
{getFieldDecorator('receiverName', {
initialValue: data.receiverName,
rules: [{ required: true, message: '请输入收款人姓名' }],
})(<Input placeholder="请输入收款人姓名" />)}
</Form.Item>
<Form.Item {...formItemLayout} label="转账金额">
{getFieldDecorator('amount', {
initialValue: data.amount,
const Step1: React.FC<Step1Props> = props => {
const { form, dispatch, data } = props;
if (!data) {
return null;
}
const { getFieldDecorator, validateFields } = form;
const onValidateForm = () => {
validateFields((err: any, values: StateType['step']) => {
if (!err && dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveStepFormData',
payload: values,
});
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep',
payload: 'confirm',
});
}
});
};
return (
<Fragment>
<Form layout="horizontal" className={styles.stepForm} hideRequiredMark>
<Form.Item {...formItemLayout} label="付款账户">
{getFieldDecorator('payAccount', {
initialValue: data.payAccount,
rules: [{ required: true, message: '请选择付款账户' }],
})(
<Select placeholder="test@example.com">
<Option value="ant-design@alipay.com">ant-design@alipay.com</Option>
</Select>,
)}
</Form.Item>
<Form.Item {...formItemLayout} label="收款账户">
<Input.Group compact>
<Select defaultValue="alipay" style={{ width: 100 }}>
<Option value="alipay">支付宝</Option>
<Option value="bank">银行账户</Option>
</Select>
{getFieldDecorator('receiverAccount', {
initialValue: data.receiverAccount,
rules: [
{ required: true, message: '请输入转账金额' },
{
pattern: /^(\d+)((?:\.\d+)?)$/,
message: '请输入合法金额数字',
},
{ required: true, message: '请输入收款人账户' },
{ type: 'email', message: '账户名应为邮箱格式' },
],
})(<Input prefix="¥" placeholder="请输入金额" />)}
</Form.Item>
<Form.Item
wrapperCol={{
xs: { span: 24, offset: 0 },
sm: {
span: formItemLayout.wrapperCol.span,
offset: formItemLayout.labelCol.span,
})(<Input style={{ width: 'calc(100% - 100px)' }} placeholder="test@example.com" />)}
</Input.Group>
</Form.Item>
<Form.Item {...formItemLayout} label="收款人姓名">
{getFieldDecorator('receiverName', {
initialValue: data.receiverName,
rules: [{ required: true, message: '请输入收款人姓名' }],
})(<Input placeholder="请输入收款人姓名" />)}
</Form.Item>
<Form.Item {...formItemLayout} label="转账金额">
{getFieldDecorator('amount', {
initialValue: data.amount,
rules: [
{ required: true, message: '请输入转账金额' },
{
pattern: /^(\d+)((?:\.\d+)?)$/,
message: '请输入合法金额数字',
},
}}
label=""
>
<Button type="primary" onClick={onValidateForm}>
下一步
</Button>
</Form.Item>
</Form>
<Divider style={{ margin: '40px 0 24px' }} />
<div className={styles.desc}>
<h3>说明</h3>
<h4>转账到支付宝账户</h4>
<p>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</p>
<h4>转账到银行卡</h4>
<p>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</p>
</div>
</Fragment>
);
}
}
],
})(<Input prefix="¥" placeholder="请输入金额" />)}
</Form.Item>
<Form.Item
wrapperCol={{
xs: { span: 24, offset: 0 },
sm: {
span: formItemLayout.wrapperCol.span,
offset: formItemLayout.labelCol.span,
},
}}
label=""
>
<Button type="primary" onClick={onValidateForm}>
下一步
</Button>
</Form.Item>
</Form>
<Divider style={{ margin: '40px 0 24px' }} />
<div className={styles.desc}>
<h3>说明</h3>
<h4>转账到支付宝账户</h4>
<p>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</p>
<h4>转账到银行卡</h4>
<p>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</p>
</div>
</Fragment>
);
};
export default connect(({ BLOCK_NAME_CAMEL_CASE }: { BLOCK_NAME_CAMEL_CASE: IStateType }) => ({
export default connect(({ BLOCK_NAME_CAMEL_CASE }: { BLOCK_NAME_CAMEL_CASE: StateType }) => ({
data: BLOCK_NAME_CAMEL_CASE.step,
}))(Form.create<Step1Props>()(Step1));
......@@ -4,7 +4,7 @@ import { Dispatch } from 'redux';
import { FormComponentProps } from 'antd/es/form';
import React from 'react';
import { connect } from 'dva';
import { IStateType } from '../../model';
import { StateType } from '../../model';
import styles from './index.less';
const formItemLayout = {
......@@ -16,102 +16,100 @@ const formItemLayout = {
},
};
interface Step2Props extends FormComponentProps {
data?: IStateType['step'];
data?: StateType['step'];
dispatch?: Dispatch<any>;
submitting?: boolean;
}
class Step2 extends React.Component<Step2Props> {
render() {
const { form, data, dispatch, submitting } = this.props;
if (!data) {
return;
const Step2: React.FC<Step2Props> = props => {
const { form, data, dispatch, submitting } = props;
if (!data) {
return null;
}
const { getFieldDecorator, validateFields } = form;
const onPrev = () => {
if (dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep',
payload: 'info',
});
}
const { getFieldDecorator, validateFields } = form;
const onPrev = () => {
if (dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep',
payload: 'info',
});
}
};
const onValidateForm = (e: React.FormEvent) => {
e.preventDefault();
validateFields((err, values) => {
if (!err) {
if (dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/submitStepForm',
payload: {
...data,
...values,
},
});
}
};
const onValidateForm = (e: React.FormEvent) => {
e.preventDefault();
validateFields((err, values) => {
if (!err) {
if (dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/submitStepForm',
payload: {
...data,
...values,
},
});
}
});
};
return (
<Form layout="horizontal" className={styles.stepForm}>
<Alert
closable
showIcon
message="确认转账后,资金将直接打入对方账户,无法退回。"
style={{ marginBottom: 24 }}
/>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="付款账户">
{data.payAccount}
</Form.Item>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="收款账户">
{data.receiverAccount}
</Form.Item>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="收款人姓名">
{data.receiverName}
</Form.Item>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="转账金额">
<span className={styles.money}>{data.amount}</span>
</Form.Item>
<Divider style={{ margin: '24px 0' }} />
<Form.Item {...formItemLayout} label="支付密码" required={false}>
{getFieldDecorator('password', {
initialValue: '123456',
rules: [
{
required: true,
message: '需要支付密码才能进行支付',
},
],
})(<Input type="password" autoComplete="off" style={{ width: '80%' }} />)}
</Form.Item>
<Form.Item
style={{ marginBottom: 8 }}
wrapperCol={{
xs: { span: 24, offset: 0 },
sm: {
span: formItemLayout.wrapperCol.span,
offset: formItemLayout.labelCol.span,
}
});
};
return (
<Form layout="horizontal" className={styles.stepForm}>
<Alert
closable
showIcon
message="确认转账后,资金将直接打入对方账户,无法退回。"
style={{ marginBottom: 24 }}
/>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="付款账户">
{data.payAccount}
</Form.Item>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="收款账户">
{data.receiverAccount}
</Form.Item>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="收款人姓名">
{data.receiverName}
</Form.Item>
<Form.Item {...formItemLayout} className={styles.stepFormText} label="转账金额">
<span className={styles.money}>{data.amount}</span>
</Form.Item>
<Divider style={{ margin: '24px 0' }} />
<Form.Item {...formItemLayout} label="支付密码" required={false}>
{getFieldDecorator('password', {
initialValue: '123456',
rules: [
{
required: true,
message: '需要支付密码才能进行支付',
},
}}
label=""
>
<Button type="primary" onClick={onValidateForm} loading={submitting}>
提交
</Button>
<Button onClick={onPrev} style={{ marginLeft: 8 }}>
上一步
</Button>
</Form.Item>
</Form>
);
}
}
],
})(<Input type="password" autoComplete="off" style={{ width: '80%' }} />)}
</Form.Item>
<Form.Item
style={{ marginBottom: 8 }}
wrapperCol={{
xs: { span: 24, offset: 0 },
sm: {
span: formItemLayout.wrapperCol.span,
offset: formItemLayout.labelCol.span,
},
}}
label=""
>
<Button type="primary" onClick={onValidateForm} loading={submitting}>
提交
</Button>
<Button onClick={onPrev} style={{ marginLeft: 8 }}>
上一步
</Button>
</Form.Item>
</Form>
);
};
export default connect(
({
BLOCK_NAME_CAMEL_CASE,
loading,
}: {
BLOCK_NAME_CAMEL_CASE: IStateType;
BLOCK_NAME_CAMEL_CASE: StateType;
loading: {
effects: { [key: string]: boolean };
};
......
......@@ -2,97 +2,82 @@ import { Button, Col, Row } from 'antd';
import React, { Fragment } from 'react';
import { Dispatch } from 'redux';
import { connect } from 'dva';
import { IStateType } from '../../model';
import { StateType } from '../../model';
import Result from '../Result';
import styles from './index.less';
interface Step3Props {
data?: IStateType['step'];
data?: StateType['step'];
dispatch?: Dispatch<any>;
}
@connect(
({
BLOCK_NAME_CAMEL_CASE,
}: {
BLOCK_NAME_CAMEL_CASE: IStateType;
loading: {
effects: { [key: string]: boolean };
};
}) => ({
data: BLOCK_NAME_CAMEL_CASE.step,
}),
)
class Step3 extends React.Component<Step3Props> {
render() {
const { data, dispatch } = this.props;
if (!data) {
return;
}
const onFinish = () => {
if (dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep',
payload: 'info',
});
}
};
const information = (
<div className={styles.information}>
<Row>
<Col xs={24} sm={8} className={styles.label}>
付款账户:
</Col>
<Col xs={24} sm={16}>
{data.payAccount}
</Col>
</Row>
<Row>
<Col xs={24} sm={8} className={styles.label}>
收款账户:
</Col>
<Col xs={24} sm={16}>
{data.receiverAccount}
</Col>
</Row>
<Row>
<Col xs={24} sm={8} className={styles.label}>
收款人姓名:
</Col>
<Col xs={24} sm={16}>
{data.receiverName}
</Col>
</Row>
<Row>
<Col xs={24} sm={8} className={styles.label}>
转账金额:
</Col>
<Col xs={24} sm={16}>
<span className={styles.money}>{data.amount}</span>
</Col>
</Row>
</div>
);
const actions = (
<Fragment>
<Button type="primary" onClick={onFinish}>
再转一笔
</Button>
<Button>查看账单</Button>
</Fragment>
);
return (
<Result
type="success"
title="操作成功"
description="预计两小时内到账"
extra={information}
actions={actions}
className={styles.result}
/>
);
const Step3: React.FC<Step3Props> = props => {
const { data, dispatch } = props;
if (!data) {
return null;
}
}
const onFinish = () => {
if (dispatch) {
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep',
payload: 'info',
});
}
};
const information = (
<div className={styles.information}>
<Row>
<Col xs={24} sm={8} className={styles.label}>
付款账户:
</Col>
<Col xs={24} sm={16}>
{data.payAccount}
</Col>
</Row>
<Row>
<Col xs={24} sm={8} className={styles.label}>
收款账户:
</Col>
<Col xs={24} sm={16}>
{data.receiverAccount}
</Col>
</Row>
<Row>
<Col xs={24} sm={8} className={styles.label}>
收款人姓名:
</Col>
<Col xs={24} sm={16}>
{data.receiverName}
</Col>
</Row>
<Row>
<Col xs={24} sm={8} className={styles.label}>
转账金额:
</Col>
<Col xs={24} sm={16}>
<span className={styles.money}>{data.amount}</span>
</Col>
</Row>
</div>
);
const actions = (
<Fragment>
<Button type="primary" onClick={onFinish}>
再转一笔
</Button>
<Button>查看账单</Button>
</Fragment>
);
return (
<Result
type="success"
title="操作成功"
description="预计两小时内到账"
extra={information}
actions={actions}
className={styles.result}
/>
);
};
export default Step3;
......@@ -3,7 +3,7 @@ import React, { Component, Fragment } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { connect } from 'dva';
import { IStateType } from './model';
import { StateType } from './model';
import Step1 from './components/Step1';
import Step2 from './components/Step2';
import Step3 from './components/Step3';
......@@ -12,10 +12,10 @@ import styles from './style.less';
const { Step } = Steps;
interface PAGE_NAME_UPPER_CAMEL_CASEProps {
current: IStateType['current'];
current: StateType['current'];
}
@connect(({ BLOCK_NAME_CAMEL_CASE }: { BLOCK_NAME_CAMEL_CASE: IStateType }) => ({
@connect(({ BLOCK_NAME_CAMEL_CASE }: { BLOCK_NAME_CAMEL_CASE: StateType }) => ({
current: BLOCK_NAME_CAMEL_CASE.current,
}))
class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEProps> {
......
......@@ -3,7 +3,7 @@ import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { fakeSubmitForm } from './service';
export interface IStateType {
export interface StateType {
current?: string;
step?: {
payAccount: string;
......@@ -15,18 +15,18 @@ export interface IStateType {
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap & { select: <T>(func: (state: IStateType) => T) => T },
effects: EffectsCommandMap & { select: <T>(func: (state: StateType) => T) => T },
) => void;
export interface ModelType {
namespace: string;
state: IStateType;
state: StateType;
effects: {
submitStepForm: Effect;
};
reducers: {
saveStepFormData: Reducer<IStateType>;
saveCurrentStep: Reducer<IStateType>;
saveStepFormData: Reducer<StateType>;
saveCurrentStep: Reducer<StateType>;
};
}
......@@ -69,7 +69,7 @@ const Model: ModelType = {
return {
...state,
step: {
...state!.step,
...(state as StateType).step,
...payload,
},
};
......
......@@ -26,7 +26,7 @@ import { findDOMNode } from 'react-dom';
import moment from 'moment';
import Result from './Result';
import { IStateType } from './model';
import { BasicListItemDataType } from './data';
import { BasicListItemDataType } from './data.d';
import styles from './style.less';
const FormItem = Form.Item;
......
{
"private": true,
"scripts": {
"dev": "cross-env PAGES_PATH='ProfileAdvanced/src' umi dev",
"dev": "cross-env PAGES_PATH='DashboardMonitor/src' umi dev",
"start": "umi dev",
"lint-staged": "lint-staged",
"lint": "npm run lint:js && npm run lint:style && npm run lint:prettier",
......
defaultSeverity: error
extends:
- tslint-react
- tslint-eslint-rules
- tslint-config-prettier
jsRules:
rules:
class-name: false
eofline: true
forin: true
jsdoc-format: false
label-position: true
member-ordering:
- true
- order: statics-first
new-parens: true
no-arg: true
no-bitwise: true
no-conditional-assignment: true
no-consecutive-blank-lines: true
no-console:
- true
- debug
- info
- log
- time
- timeEnd
- trace
- warn
no-construct: true
no-debugger: true
no-duplicate-variable: true
no-eval: true
no-internal-module: true
no-multi-spaces: true
no-namespace: true
no-reference: true
no-shadowed-variable: true
no-string-literal: true
no-trailing-whitespace: true
no-unused-expression: true
no-var-keyword: true
one-variable-per-declaration:
- true
- ignore-for-loop
prefer-const:
- true
- destructuring: all
radix: true
space-in-parens: true
switch-default: true
trailing-comma:
- true
- singleline: never
multiline: always
esSpecCompliant: true
triple-equals:
- true
- allow-null-check
typedef-whitespace:
- true
- call-signature: nospace
index-signature: nospace
parameter: nospace
property-declaration: nospace
variable-declaration: nospace
- call-signature: onespace
index-signature: onespace
parameter: onespace
property-declaration: onespace
variable-declaration: onespace
use-isnan: true
variable-name:
- true
- allow-leading-underscore
- ban-keywords
- check-format
- allow-pascal-case
jsx-no-lambda: false
jsx-no-string-ref: false
jsx-boolean-value:
- true
- never
jsx-no-multiline-js: false
whitespace:
- true
- check-branch
- check-decl
- check-operator
- check-module
- check-separator
- check-rest-spread
- check-type
- check-type-operator
- check-preblock
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment