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
content={errorList}
overlayClassName={styles.errorPopover}
trigger="click"
getPopupContainer={trigger => trigger.parentNode}
getPopupContainer={trigger => trigger && trigger.parentNode}
>
<Icon type="exclamation-circle" />
</Popover>
......@@ -269,7 +269,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component<PAGE_NAME_UPPER_CAMEL_CASEPro
<TimePicker
placeholder="提醒时间"
style={{ width: '100%' }}
getPopupContainer={trigger => trigger.parentNode}
getPopupContainer={trigger => trigger.ParentNode}
/>
)}
</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 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedprofile"
},
"dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9",
"classnames": "^2.2.6",
"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 Debounce from 'lodash-decorators/debounce';
import Bind from 'lodash-decorators/bind';
import { Dispatch } from 'redux';
import { RouteContext, GridContent } from '@ant-design/pro-layout';
import { connect } from 'dva';
import {
Button,
......@@ -12,14 +12,17 @@ import {
Steps,
Card,
Popover,
PageHeader,
Badge,
Table,
Tooltip,
Divider,
Typography,
Tabs,
} from 'antd';
import { TabsProps } from 'antd/lib/tabs';
import classNames from 'classnames';
import { DescriptionList } from 'ant-design-pro';
import PageHeaderWrapper from './components/PageHeaderWrapper';
import DescriptionList from './DescriptionList';
import styles from './style.less';
const { Step } = Steps;
......@@ -52,7 +55,11 @@ const action = (
);
const extra = (
<Row>
<Row
style={{
minWidth: 400,
}}
>
<Col xs={24} sm={12}>
<div className={styles.textSecondary}>状态</div>
<div className={styles.heading}>待审批</div>
......@@ -65,7 +72,7 @@ const extra = (
);
const description = (
<DescriptionList className={styles.headerList} size="small" col="2">
<DescriptionList className={styles.headerList} size="small" col={2}>
<Description term="创建人">曲丽丽</Description>
<Description term="订购产品">XX 服务</Description>
<Description term="创建时间">2017-07-07</Description>
......@@ -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 = (
<div className={classNames(styles.textSecondary, styles.stepDescription)}>
<Fragment>
......@@ -122,7 +166,14 @@ const popoverContent = (
</div>
);
const customDot = (dot, { status }) =>
const customDot = (
dot: React.ReactNode,
{
status,
}: {
status: string;
}
) =>
status === 'process' ? (
<Popover placement="topLeft" arrowPointAtCenter content={popoverContent}>
{dot}
......@@ -161,7 +212,7 @@ const columns = [
title: '执行结果',
dataIndex: 'status',
key: 'status',
render: text =>
render: (text: string) =>
text === 'agree' ? (
<Badge status="success" text="成功" />
) : (
......@@ -179,19 +230,71 @@ const columns = [
key: 'memo',
},
];
export interface AdvancedOperation1 {
key: string;
type: string;
name: string;
status: string;
updatedAt: string;
memo: string;
}
@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({
BLOCK_NAME_CAMEL_CASE,
loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchAdvanced'],
}))
class PAGE_NAME_UPPER_CAMEL_CASE extends Component {
state = {
operationkey: 'tab1',
export interface AdvancedOperation2 {
key: string;
type: string;
name: string;
status: string;
updatedAt: string;
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',
};
componentDidMount() {
const { dispatch } = this.props;
const { dispatch, BLOCK_NAME_CAMEL_CASE } = this.props;
console.log(BLOCK_NAME_CAMEL_CASE);
dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/fetchAdvanced',
});
......@@ -202,16 +305,12 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component {
componentWillUnmount() {
window.removeEventListener('resize', this.setStepDirection);
this.setStepDirection.cancel();
}
onOperationTabChange = key => {
this.setState({ operationkey: key });
onOperationTabChange = (key: string) => {
this.setState({ operationKey: key });
};
@Bind()
@Debounce(200)
setStepDirection() {
setStepDirection = () => {
const { stepDirection } = this.state;
const w = getWindowWidth();
if (stepDirection !== 'vertical' && w <= 576) {
......@@ -223,10 +322,10 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component {
stepDirection: 'horizontal',
});
}
}
};
render() {
const { stepDirection, operationkey } = this.state;
const { stepDirection, operationKey } = this.state;
const { BLOCK_NAME_CAMEL_CASE, loading } = this.props;
const { advancedOperation1, advancedOperation2, advancedOperation3 } = BLOCK_NAME_CAMEL_CASE;
const contentList = {
......@@ -255,97 +354,134 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends Component {
/>
),
};
return (
<PageHeaderWrapper
title="单号:234231029431"
logo={
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png" />
}
action={action}
content={description}
extraContent={extra}
tabList={tabList}
>
<Card title="流程进度" style={{ marginBottom: 24 }} bordered={false}>
<Steps direction={stepDirection} progressDot={customDot} current={1}>
<Step title="创建项目" description={desc1} />
<Step title="部门初审" description={desc2} />
<Step title="财务复核" />
<Step title="完成" />
</Steps>
</Card>
<Card title="用户信息" style={{ marginBottom: 24 }} bordered={false}>
<DescriptionList style={{ marginBottom: 24 }}>
<Description term="用户姓名">付小小</Description>
<Description term="会员卡号">32943898021309809423</Description>
<Description term="身份证">3321944288191034921</Description>
<Description term="联系方式">18112345678</Description>
<Description term="联系地址">
曲丽丽 18100000000 浙江省杭州市西湖区黄姑山路工专路交叉路口
</Description>
</DescriptionList>
<DescriptionList style={{ marginBottom: 24 }} title="信息组">
<Description term="某某数据">725</Description>
<Description term="该数据更新时间">2017-08-08</Description>
<Description>&nbsp;</Description>
<Description
term={
<span>
某某数据
<Tooltip title="数据说明">
<Icon
style={{ color: 'rgba(0, 0, 0, 0.43)', marginLeft: 4 }}
type="info-circle-o"
/>
</Tooltip>
</span>
}
>
725
</Description>
<Description term="该数据更新时间">2017-08-08</Description>
</DescriptionList>
<h4 style={{ marginBottom: 16 }}>信息组</h4>
<Card type="inner" title="多层级信息组">
<DescriptionList size="small" style={{ marginBottom: 16 }} title="组名称">
<Description term="负责人">林东东</Description>
<Description term="角色码">1234567</Description>
<Description term="所属部门">XX公司 - YY部</Description>
<Description term="过期时间">2017-08-08</Description>
<Description term="描述">
这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...
</Description>
</DescriptionList>
<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>
</PageHeaderWrapper>
<RouteContext.Consumer>
{value => {
return (
<>
<PageHeader
{...value}
title={
<Typography.Title
level={4}
style={{
margin: 0,
}}
>
单号:234231029431
</Typography.Title>
}
style={{
margin: -24,
}}
extra={action}
footer={<RenderFooter tabList={tabList} />}
>
<div
style={{
display: 'flex',
}}
>
{description}
{extra}
</div>
</PageHeader>
<div
style={{
margin: 24,
marginTop: 48,
}}
>
<GridContent>
<Card title="流程进度" style={{ marginBottom: 24 }} bordered={false}>
<Steps direction={stepDirection} progressDot={customDot} current={1}>
<Step title="创建项目" description={desc1} />
<Step title="部门初审" description={desc2} />
<Step title="财务复核" />
<Step title="完成" />
</Steps>
</Card>
<Card title="用户信息" style={{ marginBottom: 24 }} bordered={false}>
<DescriptionList style={{ marginBottom: 24 }}>
<Description term="用户姓名">付小小</Description>
<Description term="会员卡号">32943898021309809423</Description>
<Description term="身份证">3321944288191034921</Description>
<Description term="联系方式">18112345678</Description>
<Description term="联系地址">
曲丽丽 18100000000 浙江省杭州市西湖区黄姑山路工专路交叉路口
</Description>
</DescriptionList>
<DescriptionList style={{ marginBottom: 24 }} title="信息组">
<Description term="某某数据">725</Description>
<Description term="该数据更新时间">2017-08-08</Description>
<Description>&nbsp;</Description>
<Description
term={
<span>
某某数据
<Tooltip title="数据说明">
<Icon
style={{ color: 'rgba(0, 0, 0, 0.43)', marginLeft: 4 }}
type="info-circle-o"
/>
</Tooltip>
</span>
}
>
725
</Description>
<Description term="该数据更新时间">2017-08-08</Description>
</DescriptionList>
<h4 style={{ marginBottom: 16 }}>信息组</h4>
<Card type="inner" title="多层级信息组">
<DescriptionList size="small" style={{ marginBottom: 16 }} title="组名称">
<Description term="负责人">林东东</Description>
<Description term="角色码">1234567</Description>
<Description term="所属部门">XX公司 - YY部</Description>
<Description term="过期时间">2017-08-08</Description>
<Description term="描述">
这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...
</Description>
</DescriptionList>
<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,
"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": "eslint --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 @@
"hooks": {
"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