Commit a1b9d9b2 authored by 陈帅's avatar 陈帅

CardList finish

parent e1843dd8
import React from 'react';
import { RouteContext } from '@ant-design/pro-layout';
import { PageHeader } from 'antd';
import { PageHeader, Typography } from 'antd';
import styles from './index.less';
interface IPageHeaderWrapperProps {
......@@ -10,13 +10,27 @@ interface IPageHeaderWrapperProps {
const PageHeaderWrapper: React.SFC<IPageHeaderWrapperProps> = ({
children,
title,
content,
...restProps
}) => (
<RouteContext.Consumer>
{value => (
<div style={{ margin: '-24px -24px 0' }}>
<PageHeader {...restProps} {...value}>
<PageHeader
title={
<Typography.Title
level={4}
style={{
margin: 0,
}}
>
{title}
</Typography.Title>
}
{...restProps}
{...value}
>
{content}
</PageHeader>
{children ? <div className={styles.content}>{children}</div> : null}
......
......@@ -57,7 +57,11 @@ function fakeList(count: number): BasicListItemDataType[] {
title: titles[i % 8],
avatar: avatars[i % 8],
cover: parseInt(i / 4 + '', 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)],
status: ['active', 'exception', 'normal'][i % 3],
status: ['active', 'exception', 'normal'][i % 3] as
| 'normal'
| 'exception'
| 'active'
| 'success',
percent: Math.ceil(Math.random() * 50) + 50,
logo: avatars[i % 8],
href: 'https://ant.design',
......
import React from 'react';
import { RouteContext } from '@ant-design/pro-layout';
import { PageHeader } from 'antd';
import { PageHeader, Typography } from 'antd';
import styles from './index.less';
interface IPageHeaderWrapperProps {
......@@ -8,15 +8,23 @@ interface IPageHeaderWrapperProps {
title: React.ReactNode;
}
const PageHeaderWrapper: React.SFC<IPageHeaderWrapperProps> = ({
children,
content,
...restProps
}) => (
const PageHeaderWrapper: React.SFC<IPageHeaderWrapperProps> = ({ children, content, title }) => (
<RouteContext.Consumer>
{value => (
<div style={{ margin: '-24px -24px 0' }}>
<PageHeader {...restProps} {...value}>
<PageHeader
title={
<Typography.Title
level={4}
style={{
margin: 0,
}}
>
{title}
</Typography.Title>
}
{...value}
>
{content}
</PageHeader>
{children ? <div className={styles.content}>{children}</div> : null}
......
import { CardListItemDataType } from './data';
const titles = [
'Alipay',
'Angular',
......@@ -32,6 +34,7 @@ const desc = [
'城镇中有那么多的酒馆,她却偏偏走进了我的酒馆',
'那时候我只会想自己想要什么,从不想自己拥有什么',
];
const user = [
'付小小',
'曲丽丽',
......@@ -45,7 +48,7 @@ const user = [
'仲尼',
];
function fakeList(count) {
function fakeList(count: number): CardListItemDataType[] {
const list = [];
for (let i = 0; i < count; i += 1) {
list.push({
......@@ -53,13 +56,17 @@ function fakeList(count) {
owner: user[i % 10],
title: titles[i % 8],
avatar: avatars[i % 8],
cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)],
status: ['active', 'exception', 'normal'][i % 3],
cover: parseInt(i / 4 + '', 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)],
status: ['active', 'exception', 'normal'][i % 3] as
| 'normal'
| 'exception'
| 'active'
| 'success',
percent: Math.ceil(Math.random() * 50) + 50,
logo: avatars[i % 8],
href: 'https://ant.design',
updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i),
createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i),
updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i).getTime(),
createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i).getTime(),
subDescription: desc[i % 5],
description:
'在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。',
......@@ -93,7 +100,7 @@ function fakeList(count) {
return list;
}
function getFakeList(req, res) {
function getFakeList(req: { query: any }, res: { json: (arg0: CardListItemDataType[]) => void }) {
const params = req.query;
const count = params.count * 1 || 20;
......
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, wrapperClassName, ...restProps }) => (
<div style={{ margin: '-24px -24px 0' }} className={wrapperClassName}>
<PageHeader
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 {
.children-content {
margin: 24px 24px 0;
}
@media screen and (max-width: @screen-sm) {
.main {
.detail {
display: flex;
}
.row {
display: flex;
width: 100%;
}
.title-content {
margin-bottom: 16px;
}
@media screen and (max-width: @screen-sm) {
.content {
margin: 24px 0 0;
}
}
.title,
.content {
margin: 24px 0 0;
flex: auto;
}
.extraContent,
.main {
flex: 0 1 auto;
}
.main {
width: 100%;
}
.title {
margin-bottom: 16px;
}
.logo,
.content,
.extraContent {
margin-bottom: 16px;
}
.extraContent {
min-width: 242px;
margin-left: 88px;
text-align: right;
}
}
@media screen and (max-width: @screen-xl) {
.extraContent {
margin-left: 44px;
}
}
@media screen and (max-width: @screen-lg) {
.extraContent {
margin-left: 20px;
}
}
@media screen and (max-width: @screen-md) {
.row {
display: block;
}
.action,
.extraContent {
margin-left: 0;
text-align: left;
}
}
@media screen and (max-width: @screen-sm) {
.detail {
display: block;
}
}
import React from 'react';
import { RouteContext } from '@ant-design/pro-layout';
import { PageHeader, Typography } from 'antd';
import styles from './index.less';
import { GridContent } from '@ant-design/pro-layout';
interface IPageHeaderWrapperProps {
content?: React.ReactNode;
title: React.ReactNode;
extraContent?: React.ReactNode;
}
const PageHeaderWrapper: React.SFC<IPageHeaderWrapperProps> = ({
children,
title,
content,
extraContent,
...restProps
}) => (
<RouteContext.Consumer>
{value => (
<div style={{ margin: '-24px -24px 0' }}>
<PageHeader
title={
<Typography.Title
level={4}
style={{
margin: 0,
}}
>
{title}
</Typography.Title>
}
{...restProps}
{...value}
>
<div className={styles.detail}>
<div className={styles.main}>
<div className={styles.row}>
{content && <div className={styles.content}>{content}</div>}
{extraContent && <div className={styles.extraContent}>{extraContent}</div>}
</div>
</div>
</div>
</PageHeader>
{children ? (
<GridContent>
<div className={styles['children-content']}>{children}</div>
</GridContent>
) : null}
</div>
)}
</RouteContext.Consumer>
);
export default PageHeaderWrapper;
export interface Member {
avatar: string;
name: string;
id: string;
}
export interface CardListItemDataType {
id: string;
owner: string;
title: string;
avatar: string;
cover: string;
status: 'normal' | 'exception' | 'active' | 'success';
percent: number;
logo: string;
href: string;
body?: any;
updatedAt: number;
createdAt: number;
subDescription: string;
description: string;
activeUser: number;
newUser: number;
star: number;
like: number;
message: number;
content: string;
members: Member[];
}
import React, { PureComponent } from 'react';
import React, { Component } from 'react';
import { connect } from 'dva';
import { Card, Button, Icon, List } from 'antd';
import { Ellipsis } from 'ant-design-pro';
import { Dispatch } from 'redux';
import { IStateType } from './model';
import { CardListItemDataType } from './data';
import { Card, Button, Typography, Icon, List } from 'antd';
import PageHeaderWrapper from './components/PageHeaderWrapper';
const { Paragraph } = Typography;
import styles from './style.less';
@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({
BLOCK_NAME_CAMEL_CASE,
loading: loading.models.list,
}))
class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
interface PAGE_NAME_UPPER_CAMEL_CASEProps {
BLOCK_NAME_CAMEL_CASE: IStateType;
dispatch: Dispatch;
loading: boolean;
}
interface PAGE_NAME_UPPER_CAMEL_CASEState {
visible: boolean;
done: boolean;
current?: Partial<CardListItemDataType>;
}
@connect(
({
BLOCK_NAME_CAMEL_CASE,
loading,
}: {
BLOCK_NAME_CAMEL_CASE: IStateType;
loading: {
models: { [key: string]: boolean };
};
}) => ({
BLOCK_NAME_CAMEL_CASE,
loading: loading.models.list,
})
)
class PAGE_NAME_UPPER_CAMEL_CASE extends Component<
PAGE_NAME_UPPER_CAMEL_CASEProps,
PAGE_NAME_UPPER_CAMEL_CASEState
> {
componentDidMount() {
const { dispatch } = this.props;
dispatch({
......@@ -59,7 +86,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
/>
</div>
);
const nullData = {} as CardListItemDataType;
return (
<PageHeaderWrapper title="卡片列表" content={content} extraContent={extraContent}>
<div className={styles.cardList}>
......@@ -67,7 +94,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
rowKey="id"
loading={loading}
grid={{ gutter: 24, lg: 3, md: 2, sm: 1, xs: 1 }}
dataSource={['', ...list]}
dataSource={[nullData, ...list]}
renderItem={item =>
item ? (
<List.Item key={item.id}>
......@@ -76,9 +103,9 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
avatar={<img alt="" className={styles.cardAvatar} src={item.avatar} />}
title={<a>{item.title}</a>}
description={
<Ellipsis className={styles.item} lines={3}>
<Paragraph className={styles.item} ellipsis={{ rows: 3 }}>
{item.description}
</Ellipsis>
</Paragraph>
}
/>
</Card>
......
import { queryFakeList } from './service';
import { CardListItemDataType } from './data';
import { Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { AnyAction } from 'redux';
export default {
export interface IStateType {
list: CardListItemDataType[];
}
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap & { select: <T>(func: (state: IStateType) => T) => T }
) => void;
export interface ModelType {
namespace: string;
state: IStateType;
effects: {
fetch: Effect;
};
reducers: {
queryList: Reducer<IStateType>;
};
}
const Model: ModelType = {
namespace: 'BLOCK_NAME_CAMEL_CASE',
state: {
......@@ -26,3 +50,5 @@ export default {
},
},
};
export default Model;
import request from 'umi-request';
export async function queryFakeList(params) {
export async function queryFakeList(params: { count: number }) {
return request(`/api/BLOCK_NAME/fake_list`, {
params,
});
......
......@@ -36,9 +36,9 @@
}
.extraImg {
margin-top: -60px;
margin-top: -20px;
text-align: center;
width: 195px;
width: 155px;
img {
width: 100%;
}
......
{
"private": true,
"scripts": {
"dev": "cross-env PAGES_PATH='BasicProfile/src' umi dev",
"dev": "cross-env PAGES_PATH='CardList/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",
......
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