Commit 45474f29 authored by 愚道's avatar 愚道

migrate workplace to ts

parent 127df717
......@@ -3,7 +3,7 @@ export default {
[
'umi-plugin-block-dev',
{
layout: 'ant-design-pro-user',
layout: 'ant-design-pro',
menu: {
name: '主页',
icon: 'home',
......
import React, { PureComponent, createElement } from 'react';
import PropTypes from 'prop-types';
import PropTypes, { string } from 'prop-types';
import { Button } from 'antd';
import styles from './index.less';
// TODO: 添加逻辑
export interface EditableLink {
title: string;
href: string;
}
interface EditableLinkGroupProps {
onAdd: () => void;
links: EditableLink[];
linkElement: React.Component;
}
class EditableLinkGroup extends PureComponent {
class EditableLinkGroup extends PureComponent<EditableLinkGroupProps> {
static propTypes = {
links: PropTypes.array,
onAdd: PropTypes.func,
......
@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 { FormattedMessage } from 'umi-plugin-react/locale';
import Link from 'umi/link';
import { PageHeader } from 'ant-design-pro';
import { RouteContext } from '@ant-design/pro-layout';
import { PageHeader, Typography } from 'antd';
import styles from './index.less';
import { GridContent } from '@ant-design/pro-layout';
const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, ...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>
interface IPageHeaderWrapperProps {
content?: React.ReactNode;
title?: React.ReactNode;
extraContent?: React.ReactNode;
}
const PageHeaderWrapper: React.SFC<IPageHeaderWrapperProps> = ({
children,
content,
title,
extraContent,
...restProps
}) => (
<RouteContext.Consumer>
{value => (
<div style={{ margin: '-24px -24px 0' }}>
<PageHeader
title={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 ITag {
key: string;
label: string;
}
export interface Province {
label: string;
key: string;
}
export interface City {
label: string;
key: string;
}
export interface Geographic {
province: Province;
city: City;
}
export interface Notice {
id: string;
title: string;
logo: string;
description: string;
updatedAt: string;
member: string;
href: string;
memberLink: string;
}
export interface CurrentUser {
name: string;
avatar: string;
userid: string;
notice: Notice[];
email: string;
signature: string;
title: string;
group: string;
tags: ITag[];
notifyCount: number;
unreadCount: number;
country: string;
geographic: Geographic;
address: string;
phone: string;
}
export interface Member {
avatar: string;
name: string;
id: string;
}
export interface Activeties {
id: string,
updatedAt: string,
user: {
name: string,
avatar: string,
},
group: {
name: string,
link: string,
},
project: {
name: string,
link: string,
},
template: string,
}
export interface RadarData {
label: string;
name: string;
value: number;
}
......@@ -3,10 +3,13 @@ import moment from 'moment';
import { connect } from 'dva';
import Link from 'umi/link';
import { Row, Col, Card, List, Avatar } from 'antd';
import { Dispatch } from 'redux';
import { Charts } from 'ant-design-pro';
import EditableLinkGroup from './components/EditableLinkGroup';
import PageHeaderWrapper from './components/PageHeaderWrapper';
import { ModalState } from './model';
import { CurrentUser, Activeties, RadarData, Notice } from './data';
import styles from './style.less';
......@@ -39,16 +42,33 @@ const links = [
},
];
@connect(({ BLOCK_NAME_CAMEL_CASE: { user, project, activities, chart }, loading }) => ({
currentUser: user.currentUser,
project,
interface BLOCK_NAME_CAMEL_CASEProps {
currentUser: CurrentUser;
projectNotice: Notice[];
activities: Activeties[];
radarData: RadarData[];
dispatch: Dispatch;
currentUserLoading: boolean;
projectLoading: boolean;
activitiesLoading: boolean;
}
@connect(({
BLOCK_NAME_CAMEL_CASE: { currentUser, projectNotice, activities, radarData },
loading,
}: {
BLOCK_NAME_CAMEL_CASE: ModalState,
loading: { effects: any },
}) => ({
currentUser,
projectNotice,
activities,
chart,
radarData,
currentUserLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchUserCurrent'],
projectLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchProjectNotice'],
activitiesLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchActivitiesList'],
}))
class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent<BLOCK_NAME_CAMEL_CASEProps> {
componentDidMount() {
const { dispatch } = this.props;
dispatch({
......@@ -65,9 +85,9 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
renderActivities() {
const {
activities: { list },
activities,
} = this.props;
return list.map(item => {
return activities.map(item => {
const events = item.template.split(/@\{([^{}]*)\}/gi).map(key => {
if (item[key]) {
return (
......@@ -103,11 +123,10 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
render() {
const {
currentUser,
currentUserLoading,
project: { notice },
projectNotice,
projectLoading,
activitiesLoading,
chart: { radarData },
radarData,
} = this.props;
const pageHeaderContent =
......@@ -150,7 +169,6 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
return (
<PageHeaderWrapper
loading={currentUserLoading}
content={pageHeaderContent}
extraContent={extraContent}
>
......@@ -165,7 +183,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
loading={projectLoading}
bodyStyle={{ padding: 0 }}
>
{notice.map(item => (
{projectNotice.map(item => (
<Card.Grid className={styles.projectGrid} key={item.id}>
<Card bodyStyle={{ padding: 0 }} bordered={false}>
<Card.Meta
......@@ -228,7 +246,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent {
>
<div className={styles.members}>
<Row gutter={48}>
{notice.map(item => (
{projectNotice.map(item => (
<Col span={12} key={`members-item-${item.id}`}>
<Link to={item.href}>
<Avatar src={item.logo} size="small" />
......
import { EffectsCommandMap } from 'dva';
import { Reducer, AnyAction } from 'redux';
import { queryCurrent, queryProjectNotice, queryActivities, fakeChartData } from './service';
import { CurrentUser, Notice, Activeties, RadarData } from './data';
export default {
export interface ModalState {
currentUser: Partial<CurrentUser>;
projectNotice: Notice[];
activities: Activeties[];
radarData: RadarData[];
}
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap & { select: <T>(func: (state: ModalState) => T) => T }
) => void;
export interface ModelType {
namespace: string;
state: ModalState;
reducers: {
save: Reducer<ModalState>;
clear: Reducer<ModalState>;
};
effects: {
init: Effect;
fetchUserCurrent: Effect;
fetchProjectNotice: Effect;
fetchActivitiesList: Effect;
fetchChart: Effect;
};
}
const Model: ModelType = {
namespace: 'BLOCK_NAME_CAMEL_CASE',
state: {
user: {
currentUser: {},
},
project: {
notice: [],
},
activities: {
list: [],
},
chart: {
visitData: [],
visitData2: [],
salesData: [],
searchData: [],
offlineData: [],
offlineChartData: [],
salesTypeData: [],
salesTypeDataOnline: [],
salesTypeDataOffline: [],
radarData: [],
loading: false,
},
},
reducers: {
saveCurrentUser(state, action) {
return {
...state,
user: {
currentUser: action.payload || {},
},
};
},
saveNotice(state, action) {
return {
...state,
project: {
notice: action.payload,
},
};
},
saveList(state, action) {
return {
...state,
activities: {
list: action.payload,
},
};
},
saveChart(state, { payload }) {
return {
...state,
chart: {
...payload,
},
};
},
clear(state) {
return {
...state,
chart: {
visitData: [],
visitData2: [],
salesData: [],
searchData: [],
offlineData: [],
offlineChartData: [],
salesTypeData: [],
salesTypeDataOnline: [],
salesTypeDataOffline: [],
radarData: [],
},
};
},
currentUser: {},
projectNotice: [],
activities: [],
radarData: [],
},
effects: {
*init(_, { put }) {
......@@ -87,30 +49,56 @@ export default {
*fetchUserCurrent(_, { call, put }) {
const response = yield call(queryCurrent);
yield put({
type: 'saveCurrentUser',
payload: response,
type: 'save',
payload: {
currentUser: response,
},
});
},
*fetchProjectNotice(_, { call, put }) {
const response = yield call(queryProjectNotice);
yield put({
type: 'saveNotice',
payload: Array.isArray(response) ? response : [],
type: 'save',
payload: {
projectNotice: Array.isArray(response) ? response : [],
}
});
},
*fetchActivitiesList(_, { call, put }) {
const response = yield call(queryActivities);
yield put({
type: 'saveList',
payload: Array.isArray(response) ? response : [],
type: 'save',
payload: {
activities: Array.isArray(response) ? response : [],
}
});
},
*fetchChart(_, { call, put }) {
const response = yield call(fakeChartData);
const { radarData } = yield call(fakeChartData);
yield put({
type: 'saveChart',
payload: response,
type: 'save',
payload: {
radarData,
},
});
},
},
reducers: {
save(state, { payload }) {
return {
...state,
...payload,
};
},
clear() {
return {
currentUser: {},
projectNotice: [],
activities: [],
radarData: [],
};
},
},
};
export default Model;
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