Commit de7f6505 authored by 陈帅's avatar 陈帅

AdvancedProfile finish

parent 1d0def2a
...@@ -99,7 +99,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro ...@@ -99,7 +99,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro
content={errorList} content={errorList}
overlayClassName={styles.errorPopover} overlayClassName={styles.errorPopover}
trigger="click" trigger="click"
getPopupContainer={trigger => trigger.parentNode} getPopupContainer={trigger => trigger && trigger.parentNode}
> >
<Icon type="exclamation-circle" /> <Icon type="exclamation-circle" />
</Popover> </Popover>
...@@ -269,7 +269,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro ...@@ -269,7 +269,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro
<TimePicker <TimePicker
placeholder="提醒时间" placeholder="提醒时间"
style={{ width: '100%' }} style={{ width: '100%' }}
getPopupContainer={trigger => trigger.parentNode} getPopupContainer={trigger => trigger.ParentNode}
/> />
)} )}
</Form.Item> </Form.Item>
......
export default {
plugins: [
['umi-plugin-block-dev', {
layout: 'ant-design-pro',
}],
['umi-plugin-react', {
dva: true,
locale: true,
antd: true,
}]
],
}
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedprofile" "url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedprofile"
}, },
"dependencies": { "dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9", "antd": "^3.10.9",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"dva": "^2.4.0", "dva": "^2.4.0",
......
import React from 'react';
import { Col } from 'antd';
import styles from './index.less';
import responsive from './responsive';
import { ColProps } from 'antd/es/col';
export interface DescriptionProps extends ColProps {
column?: number;
key?: string | number;
style?: React.CSSProperties;
term?: React.ReactNode;
}
const Description: React.SFC<DescriptionProps> = props => {
const { term, column = 3, children, ...restProps } = props;
return (
<Col {...responsive[column]} {...restProps}>
{term && <div className={styles.term}>{term}</div>}
{children !== null && children !== undefined && (
<div className={styles.detail}>{children}</div>
)}
</Col>
);
};
export default Description;
import React from 'react';
import classNames from 'classnames';
import { Row } from 'antd';
import styles from './index.less';
import Description, { DescriptionProps } from './Description';
export interface DescriptionListProps {
className?: string;
col?: number;
description?: DescriptionProps[];
gutter?: number;
layout?: 'horizontal' | 'vertical';
size?: 'large' | 'small';
style?: React.CSSProperties;
title?: React.ReactNode;
}
const DescriptionList: React.SFC<DescriptionListProps> & {
Description: typeof Description;
} = ({
className,
title,
col = 3,
layout = 'horizontal',
gutter = 32,
children,
size,
...restProps
}) => {
const clsString = classNames(styles.descriptionList, styles[layout], className, {
[styles.small]: size === 'small',
[styles.large]: size === 'large',
});
const column = col > 4 ? 4 : col;
return (
<div className={clsString} {...restProps}>
{title ? <div className={styles.title}>{title}</div> : null}
<Row gutter={gutter}>
{React.Children.map(children, (child: any) =>
child ? React.cloneElement(child, { column }) : child
)}
</Row>
</div>
);
};
DescriptionList.Description = Description;
export default DescriptionList;
@import '~antd/lib/style/themes/default.less';
.descriptionList {
// offset the padding-bottom of last row
:global {
.ant-row {
margin-bottom: -16px;
overflow: hidden;
}
}
// fix margin top error of following descriptionList
& + & {
:global {
.ant-row {
margin-top: 16px;
}
}
}
.title {
margin-bottom: 16px;
color: @heading-color;
font-weight: 500;
font-size: 14px;
}
.term {
display: table-cell;
padding-bottom: 16px;
color: @heading-color;
// Line-height is 22px IE dom height will calculate error
line-height: 20px;
white-space: nowrap;
&::after {
position: relative;
top: -0.5px;
margin: 0 8px 0 2px;
content: ':';
}
}
.detail {
display: table-cell;
width: 100%;
padding-bottom: 16px;
color: @text-color;
line-height: 20px;
}
&.small {
// offset the padding-bottom of last row
:global {
.ant-row {
margin-bottom: -8px;
}
}
// fix margin top error of following descriptionList
& + .descriptionList {
:global {
.ant-row {
margin-top: 8px;
}
}
}
.title {
margin-bottom: 12px;
color: @text-color;
}
.term,
.detail {
padding-bottom: 8px;
}
}
&.large {
.title {
font-size: 16px;
}
}
&.vertical {
.term {
display: block;
padding-bottom: 8px;
}
.detail {
display: block;
}
}
}
import DescriptionList from './DescriptionList';
export default DescriptionList;
export default {
1: { xs: 24 },
2: { xs: 24, sm: 12 },
3: { xs: 24, sm: 12, md: 8 },
4: { xs: 24, sm: 12, md: 6 },
};
import React from 'react';
import { FormattedMessage } from 'umi-plugin-react/locale';
import Link from 'umi/link';
import { PageHeader } from 'ant-design-pro';
import styles from './index.less';
const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, top, ...restProps }) => (
<div style={{ margin: '-24px -24px 0' }} className={wrapperClassName}>
<PageHeader
wide={contentWidth === 'Fixed'}
home={<FormattedMessage id="BLOCK_NAME.menu.home" defaultMessage="Home" />}
key="pageheader"
{...restProps}
linkElement={Link}
itemRender={item => {
if (item.locale) {
return <FormattedMessage id={item.locale} defaultMessage={item.title} />;
}
return item.title;
}}
/>
{children ? <div className={styles.content}>{children}</div> : null}
</div>
);
export default PageHeaderWrapper;
@import '~antd/lib/style/themes/default.less';
.content {
margin: 24px 24px 0;
}
@media screen and (max-width: @screen-sm) {
.content {
margin: 24px 0 0;
}
}
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import Debounce from 'lodash-decorators/debounce'; import { Dispatch } from 'redux';
import Bind from 'lodash-decorators/bind'; import { RouteContext, GridContent } from '@ant-design/pro-layout';
import { connect } from 'dva'; import { connect } from 'dva';
import { import {
Button, Button,
...@@ -12,14 +12,17 @@ import { ...@@ -12,14 +12,17 @@ import {
Steps, Steps,
Card, Card,
Popover, Popover,
PageHeader,
Badge, Badge,
Table, Table,
Tooltip, Tooltip,
Divider, Divider,
Typography,
Tabs,
} from 'antd'; } from 'antd';
import { TabsProps } from 'antd/lib/tabs';
import classNames from 'classnames'; import classNames from 'classnames';
import { DescriptionList } from 'ant-design-pro'; import DescriptionList from './DescriptionList';
import PageHeaderWrapper from './components/PageHeaderWrapper';
import styles from './style.less'; import styles from './style.less';
const { Step } = Steps; const { Step } = Steps;
...@@ -52,7 +55,11 @@ const action = ( ...@@ -52,7 +55,11 @@ const action = (
); );
const extra = ( const extra = (
<Row> <Row
style={{
minWidth: 400,
}}
>
<Col xs={24} sm={12}> <Col xs={24} sm={12}>
<div className={styles.textSecondary}>状态</div> <div className={styles.textSecondary}>状态</div>
<div className={styles.heading}>待审批</div> <div className={styles.heading}>待审批</div>
...@@ -65,7 +72,7 @@ const extra = ( ...@@ -65,7 +72,7 @@ const extra = (
); );
const description = ( const description = (
<DescriptionList className={styles.headerList} size="small" col="2"> <DescriptionList className={styles.headerList} size="small" col={2}>
<Description term="创建人">曲丽丽</Description> <Description term="创建人">曲丽丽</Description>
<Description term="订购产品">XX 服务</Description> <Description term="订购产品">XX 服务</Description>
<Description term="创建时间">2017-07-07</Description> <Description term="创建时间">2017-07-07</Description>
...@@ -88,6 +95,43 @@ const tabList = [ ...@@ -88,6 +95,43 @@ const tabList = [
}, },
]; ];
/**
* render Footer tabList
* In order to be compatible with the old version of the PageHeader
* basically all the functions are implemented.
*/
const RenderFooter = ({
tabList,
tabActiveKey,
onTabChange,
tabBarExtraContent,
}: {
tabList: Array<{
tab: string;
key: string;
}>;
tabActiveKey?: string;
onTabChange?: (key: string) => void;
tabBarExtraContent?: TabsProps['tabBarExtraContent'];
}) => {
return tabList && tabList.length ? (
<Tabs
className={styles.tabs}
activeKey={tabActiveKey}
onChange={key => {
if (onTabChange) {
onTabChange(key);
}
}}
tabBarExtraContent={tabBarExtraContent}
>
{tabList.map(item => (
<Tabs.TabPane tab={item.tab} key={item.key} />
))}
</Tabs>
) : null;
};
const desc1 = ( const desc1 = (
<div className={classNames(styles.textSecondary, styles.stepDescription)}> <div className={classNames(styles.textSecondary, styles.stepDescription)}>
<Fragment> <Fragment>
...@@ -122,7 +166,14 @@ const popoverContent = ( ...@@ -122,7 +166,14 @@ const popoverContent = (
</div> </div>
); );
const customDot = (dot, { status }) => const customDot = (
dot: React.ReactNode,
{
status,
}: {
status: string;
}
) =>
status === 'process' ? ( status === 'process' ? (
<Popover placement="topLeft" arrowPointAtCenter content={popoverContent}> <Popover placement="topLeft" arrowPointAtCenter content={popoverContent}>
{dot} {dot}
...@@ -161,7 +212,7 @@ const columns = [ ...@@ -161,7 +212,7 @@ const columns = [
title: '执行结果', title: '执行结果',
dataIndex: 'status', dataIndex: 'status',
key: 'status', key: 'status',
render: text => render: (text: string) =>
text === 'agree' ? ( text === 'agree' ? (
<Badge status="success" text="成功" /> <Badge status="success" text="成功" />
) : ( ) : (
...@@ -179,19 +230,71 @@ const columns = [ ...@@ -179,19 +230,71 @@ const columns = [
key: 'memo', key: 'memo',
}, },
]; ];
export interface AdvancedOperation1 {
key: string;
type: string;
name: string;
status: string;
updatedAt: string;
memo: string;
}
@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ export interface AdvancedOperation2 {
BLOCK_NAME_CAMEL_CASE, key: string;
loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchAdvanced'], type: string;
})) name: string;
class PAGE_NAME_UPPER_CAMEL_CASE extends Component { status: string;
state = { updatedAt: string;
operationkey: 'tab1', memo: string;
}
export interface AdvancedOperation3 {
key: string;
type: string;
name: string;
status: string;
updatedAt: string;
memo: string;
}
export interface RootDataObject {
advancedOperation1: AdvancedOperation1[];
advancedOperation2: AdvancedOperation2[];
advancedOperation3: AdvancedOperation3[];
}
@connect(
({
BLOCK_NAME_CAMEL_CASE,
loading,
}: {
BLOCK_NAME_CAMEL_CASE: RootDataObject;
loading: {
effects: { [key: string]: boolean };
};
}) => ({
BLOCK_NAME_CAMEL_CASE,
loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchAdvanced'],
})
)
class PAGE_NAME_UPPER_CAMEL_CASE extends Component<
{ loading: boolean; BLOCK_NAME_CAMEL_CASE: RootDataObject; dispatch: Dispatch },
{
operationKey: string;
stepDirection: 'horizontal' | 'vertical';
}
> {
public state: {
operationKey: string;
stepDirection: 'horizontal' | 'vertical';
} = {
operationKey: 'tab1',
stepDirection: 'horizontal', stepDirection: 'horizontal',
}; };
componentDidMount() { componentDidMount() {
const { dispatch } = this.props; const { dispatch, BLOCK_NAME_CAMEL_CASE } = this.props;
console.log(BLOCK_NAME_CAMEL_CASE);
dispatch({ dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/fetchAdvanced', type: 'BLOCK_NAME_CAMEL_CASE/fetchAdvanced',
}); });
...@@ -202,16 +305,12 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component { ...@@ -202,16 +305,12 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component {
componentWillUnmount() { componentWillUnmount() {
window.removeEventListener('resize', this.setStepDirection); window.removeEventListener('resize', this.setStepDirection);
this.setStepDirection.cancel();
} }
onOperationTabChange = key => { onOperationTabChange = (key: string) => {
this.setState({ operationkey: key }); this.setState({ operationKey: key });
}; };
setStepDirection = () => {
@Bind()
@Debounce(200)
setStepDirection() {
const { stepDirection } = this.state; const { stepDirection } = this.state;
const w = getWindowWidth(); const w = getWindowWidth();
if (stepDirection !== 'vertical' && w <= 576) { if (stepDirection !== 'vertical' && w <= 576) {
...@@ -223,10 +322,10 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component { ...@@ -223,10 +322,10 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component {
stepDirection: 'horizontal', stepDirection: 'horizontal',
}); });
} }
} };
render() { render() {
const { stepDirection, operationkey } = this.state; const { stepDirection, operationKey } = this.state;
const { BLOCK_NAME_CAMEL_CASE, loading } = this.props; const { BLOCK_NAME_CAMEL_CASE, loading } = this.props;
const { advancedOperation1, advancedOperation2, advancedOperation3 } = BLOCK_NAME_CAMEL_CASE; const { advancedOperation1, advancedOperation2, advancedOperation3 } = BLOCK_NAME_CAMEL_CASE;
const contentList = { const contentList = {
...@@ -255,97 +354,134 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component { ...@@ -255,97 +354,134 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component {
/> />
), ),
}; };
return ( return (
<PageHeaderWrapper <RouteContext.Consumer>
title="单号:234231029431" {value => {
logo={ return (
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png" /> <>
} <PageHeader
action={action} {...value}
content={description} title={
extraContent={extra} <Typography.Title
tabList={tabList} level={4}
> style={{
<Card title="流程进度" style={{ marginBottom: 24 }} bordered={false}> margin: 0,
<Steps direction={stepDirection} progressDot={customDot} current={1}> }}
<Step title="创建项目" description={desc1} /> >
<Step title="部门初审" description={desc2} /> 单号:234231029431
<Step title="财务复核" /> </Typography.Title>
<Step title="完成" /> }
</Steps> style={{
</Card> margin: -24,
<Card title="用户信息" style={{ marginBottom: 24 }} bordered={false}> }}
<DescriptionList style={{ marginBottom: 24 }}> extra={action}
<Description term="用户姓名">付小小</Description> footer={<RenderFooter tabList={tabList} />}
<Description term="会员卡号">32943898021309809423</Description> >
<Description term="身份证">3321944288191034921</Description> <div
<Description term="联系方式">18112345678</Description> style={{
<Description term="联系地址"> display: 'flex',
曲丽丽 18100000000 浙江省杭州市西湖区黄姑山路工专路交叉路口 }}
</Description> >
</DescriptionList> {description}
<DescriptionList style={{ marginBottom: 24 }} title="信息组"> {extra}
<Description term="某某数据">725</Description> </div>
<Description term="该数据更新时间">2017-08-08</Description> </PageHeader>
<Description>&nbsp;</Description> <div
<Description style={{
term={ margin: 24,
<span> marginTop: 48,
某某数据 }}
<Tooltip title="数据说明"> >
<Icon <GridContent>
style={{ color: 'rgba(0, 0, 0, 0.43)', marginLeft: 4 }} <Card title="流程进度" style={{ marginBottom: 24 }} bordered={false}>
type="info-circle-o" <Steps direction={stepDirection} progressDot={customDot} current={1}>
/> <Step title="创建项目" description={desc1} />
</Tooltip> <Step title="部门初审" description={desc2} />
</span> <Step title="财务复核" />
} <Step title="完成" />
> </Steps>
725 </Card>
</Description> <Card title="用户信息" style={{ marginBottom: 24 }} bordered={false}>
<Description term="该数据更新时间">2017-08-08</Description> <DescriptionList style={{ marginBottom: 24 }}>
</DescriptionList> <Description term="用户姓名">付小小</Description>
<h4 style={{ marginBottom: 16 }}>信息组</h4> <Description term="会员卡号">32943898021309809423</Description>
<Card type="inner" title="多层级信息组"> <Description term="身份证">3321944288191034921</Description>
<DescriptionList size="small" style={{ marginBottom: 16 }} title="组名称"> <Description term="联系方式">18112345678</Description>
<Description term="负责人">林东东</Description> <Description term="联系地址">
<Description term="角色码">1234567</Description> 曲丽丽 18100000000 浙江省杭州市西湖区黄姑山路工专路交叉路口
<Description term="所属部门">XX公司 - YY部</Description> </Description>
<Description term="过期时间">2017-08-08</Description> </DescriptionList>
<Description term="描述"> <DescriptionList style={{ marginBottom: 24 }} title="信息组">
这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长... <Description term="某某数据">725</Description>
</Description> <Description term="该数据更新时间">2017-08-08</Description>
</DescriptionList> <Description>&nbsp;</Description>
<Divider style={{ margin: '16px 0' }} /> <Description
<DescriptionList size="small" style={{ marginBottom: 16 }} title="组名称" col="1"> term={
<Description term="学名"> <span>
Citrullus lanatus (Thunb.) Matsum. et 某某数据
Nakai一年生蔓生藤本枝粗壮具明显的棱卷须较粗.. <Tooltip title="数据说明">
</Description> <Icon
</DescriptionList> style={{ color: 'rgba(0, 0, 0, 0.43)', marginLeft: 4 }}
<Divider style={{ margin: '16px 0' }} /> type="info-circle-o"
<DescriptionList size="small" title="组名称"> />
<Description term="负责人">付小小</Description> </Tooltip>
<Description term="角色码">1234568</Description> </span>
</DescriptionList> }
</Card> >
</Card> 725
<Card title="用户近半年来电记录" style={{ marginBottom: 24 }} bordered={false}> </Description>
<div className={styles.noData}> <Description term="该数据更新时间">2017-08-08</Description>
<Icon type="frown-o" /> </DescriptionList>
暂无数据 <h4 style={{ marginBottom: 16 }}>信息组</h4>
</div> <Card type="inner" title="多层级信息组">
</Card> <DescriptionList size="small" style={{ marginBottom: 16 }} title="组名称">
<Card <Description term="负责人">林东东</Description>
className={styles.tabsCard} <Description term="角色码">1234567</Description>
bordered={false} <Description term="所属部门">XX公司 - YY部</Description>
tabList={operationTabList} <Description term="过期时间">2017-08-08</Description>
onTabChange={this.onOperationTabChange} <Description term="描述">
> 这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...
{contentList[operationkey]} </Description>
</Card> </DescriptionList>
</PageHeaderWrapper> <Divider style={{ margin: '16px 0' }} />
<DescriptionList
size="small"
style={{ marginBottom: 16 }}
title="组名称"
col={1}
>
<Description term="学名">
Citrullus lanatus (Thunb.) Matsum. et
Nakai一年生蔓生藤本;茎、枝粗壮,具明显的棱。卷须较粗..
</Description>
</DescriptionList>
<Divider style={{ margin: '16px 0' }} />
<DescriptionList size="small" title="组名称">
<Description term="负责人">付小小</Description>
<Description term="角色码">1234568</Description>
</DescriptionList>
</Card>
</Card>
<Card title="用户近半年来电记录" style={{ marginBottom: 24 }} bordered={false}>
<div className={styles.noData}>
<Icon type="frown-o" />
暂无数据
</div>
</Card>
<Card
className={styles.tabsCard}
bordered={false}
tabList={operationTabList}
onTabChange={this.onOperationTabChange}
>
{contentList[operationKey]}
</Card>
</GridContent>
</div>
</>
);
}}
</RouteContext.Consumer>
); );
} }
} }
......
{ {
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "PAGES_PATH='AdvancedForm/src' umi dev", "dev": "cross-env PAGES_PATH='AdvancedProfile/src' umi dev",
"lint:style": "stylelint \"src/**/*.less\" --syntax less", "lint:style": "stylelint \"src/**/*.less\" --syntax less",
"lint": "eslint --ext .js src mock tests && npm run lint:style", "lint": "eslint --ext .js src mock tests && npm run lint:style",
"lint:fix": "eslint --fix --ext .js src mock tests && npm run lint:style", "lint:fix": "eslint --fix --ext .js src mock tests && npm run lint:style",
...@@ -45,5 +45,9 @@ ...@@ -45,5 +45,9 @@
"hooks": { "hooks": {
"pre-commit": "npm run lint-staged" "pre-commit": "npm run lint-staged"
} }
},
"dependencies": {
"@ant-design/pro-layout": "^4.0.5",
"cross-env": "^5.2.0"
} }
} }
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