diff --git a/.umirc.js b/.umirc.js index 75ec0fc91214c0f490a31f8e6dd71856d8abe7d1..85f1038f928e8e09395f08268816b551e3e96b19 100644 --- a/.umirc.js +++ b/.umirc.js @@ -3,7 +3,7 @@ export default { [ 'umi-plugin-block-dev', { - layout: 'ant-design-pro-user', + layout: 'ant-design-pro', menu: { name: '主页', icon: 'home', diff --git a/Workplace/src/components/EditableLinkGroup/index.tsx b/Workplace/src/components/EditableLinkGroup/index.tsx index ae3d93c712b8b019078fe37bd07286716349ef3f..122a0186801bc37bdc8193d00637f34357e9acf7 100644 --- a/Workplace/src/components/EditableLinkGroup/index.tsx +++ b/Workplace/src/components/EditableLinkGroup/index.tsx @@ -1,11 +1,20 @@ 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 { static propTypes = { links: PropTypes.array, onAdd: PropTypes.func, diff --git a/Workplace/src/components/PageHeaderWrapper/index.less b/Workplace/src/components/PageHeaderWrapper/index.less index 39a449657a98b039c29e6654fd117267cbb5283a..908db575ae9f0a0cd75d04952ba4f37b3002da42 100644 --- a/Workplace/src/components/PageHeaderWrapper/index.less +++ b/Workplace/src/components/PageHeaderWrapper/index.less @@ -1,11 +1,86 @@ @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; } } diff --git a/Workplace/src/components/PageHeaderWrapper/index.tsx b/Workplace/src/components/PageHeaderWrapper/index.tsx index d121b2c4994d8c5110f9ff69fd9079dddcd183dc..ef6422dae72dd08c3acf6d1b2315deedb2ae3ffb 100644 --- a/Workplace/src/components/PageHeaderWrapper/index.tsx +++ b/Workplace/src/components/PageHeaderWrapper/index.tsx @@ -1,26 +1,47 @@ 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 }) => ( -
- } - key="pageheader" - {...restProps} - linkElement={Link} - itemRender={item => { - if (item.locale) { - return ; - } - return item.title; - }} - /> - {children ?
{children}
: null} -
+interface IPageHeaderWrapperProps { + content?: React.ReactNode; + title?: React.ReactNode; + extraContent?: React.ReactNode; +} + +const PageHeaderWrapper: React.SFC = ({ + children, + content, + title, + extraContent, + ...restProps +}) => ( + + {value => ( +
+ +
+
+
+ {content &&
{content}
} + {extraContent &&
{extraContent}
} +
+
+
+
+ {children ? ( + +
{children}
+
+ ) : null} +
+ )} +
); export default PageHeaderWrapper; diff --git a/Workplace/src/data.d.ts b/Workplace/src/data.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..36514554b311ab6b2f51fc68c5715d4559bf9f74 --- /dev/null +++ b/Workplace/src/data.d.ts @@ -0,0 +1,78 @@ +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; +} diff --git a/Workplace/src/index.tsx b/Workplace/src/index.tsx index 91cd597c79a3b117bf3c9c8e481dd70745b7eb27..7a87036f81ef4bfff77614110e477daed5bc189f 100644 --- a/Workplace/src/index.tsx +++ b/Workplace/src/index.tsx @@ -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 { 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 ( @@ -165,7 +183,7 @@ class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { loading={projectLoading} bodyStyle={{ padding: 0 }} > - {notice.map(item => ( + {projectNotice.map(item => (
- {notice.map(item => ( + {projectNotice.map(item => ( diff --git a/Workplace/src/model.ts b/Workplace/src/model.ts index 0d19862f7f74bed3115b92e6413ff2ad2825aec9..89ecbf29e0dea16730658332f097a5d620c1ee6a 100644 --- a/Workplace/src/model.ts +++ b/Workplace/src/model.ts @@ -1,81 +1,43 @@ +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; + projectNotice: Notice[]; + activities: Activeties[]; + radarData: RadarData[]; +} + +export type Effect = ( + action: AnyAction, + effects: EffectsCommandMap & { select: (func: (state: ModalState) => T) => T } +) => void; + +export interface ModelType { + namespace: string; + state: ModalState; + reducers: { + save: Reducer; + clear: Reducer; + }; + 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;