|
|
@@ -0,0 +1,144 @@
|
|
|
+import React from 'react'
|
|
|
+import { Menu, Icon, Card, Row, Col, Dropdown } from 'antd'
|
|
|
+import { connect } from 'dva'
|
|
|
+import Ellipsis from 'ant-design-pro/lib/Ellipsis'
|
|
|
+import { dateFormat } from '../../utils/baseUtils'
|
|
|
+import Thumbnail from '../dashboard/thumbnail'
|
|
|
+const CardGrid = Card.Grid
|
|
|
+
|
|
|
+/**
|
|
|
+ * 尝试抽出generateCard()作为一个公共模块
|
|
|
+ * 需要指定以下props:
|
|
|
+ * mode 模式,分为主页、看板、图表模式 (homepage, dashboard, chart)
|
|
|
+ * list 数据所在的列表,存于models中
|
|
|
+ * filterLabel 生成列表时使用的过滤器字段
|
|
|
+ * onDistribute
|
|
|
+ * onTransfer
|
|
|
+ * onDelete
|
|
|
+ *
|
|
|
+ * 备注: chart和dashboard的thumbnail部分需要抽取出来形成公用的
|
|
|
+ *
|
|
|
+ * @class CardList
|
|
|
+ * @extends {React.Component}
|
|
|
+ */
|
|
|
+
|
|
|
+class CardList extends React.Component {
|
|
|
+
|
|
|
+ generateCard() {
|
|
|
+ const { mode, dispatch } = this.props;
|
|
|
+ const modeMapper = {
|
|
|
+ 'dashboard': this.props.dashboard, //这里只是临时指向全体列表,等待专门的收藏列表接口完成后需要修改
|
|
|
+ 'chart': this.props.chart //同上
|
|
|
+ }
|
|
|
+ let list = modeMapper[mode].list
|
|
|
+ let filterLabel = modeMapper[mode].filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
|
|
|
+ const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
|
|
|
+ const operationMenu = (
|
|
|
+ <Menu className='menu-operation'>
|
|
|
+ <Menu.Item onClick={() => {
|
|
|
+ // this.setState({visibleDistributeBox: true})
|
|
|
+ }}>
|
|
|
+ <Icon type='share-alt'/>分发
|
|
|
+ </Menu.Item>
|
|
|
+ <Menu.Divider />
|
|
|
+ <Menu.Item
|
|
|
+ onClick={()=>{
|
|
|
+ // this.setState({ visibleTransferBox: true})
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Icon type="swap" />移交
|
|
|
+ </Menu.Item>
|
|
|
+ <Menu.Item
|
|
|
+ onClick={(e) => {
|
|
|
+ // this.setState({ visibleDeleteBox: true})
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Icon type="delete" />删除
|
|
|
+
|
|
|
+ </Menu.Item>
|
|
|
+ </Menu>
|
|
|
+ )
|
|
|
+
|
|
|
+ let cards = list.filter(l => {
|
|
|
+ let reg = new RegExp('(' + filterLabel + '){1}', 'ig');
|
|
|
+ return (l.name || '').search(reg) !== -1 || (l.description || '').search(reg) !== -1;
|
|
|
+ }).sort((a, b) => {
|
|
|
+ return new Date(b.createTime) - new Date(a.createTime)
|
|
|
+ }).map( (l, i) => (
|
|
|
+ <CardGrid className='dashboard-card' key={i} onClick={() => {
|
|
|
+ this.setState({ selectedRecord: l })
|
|
|
+ }}>
|
|
|
+ <Card
|
|
|
+ title={
|
|
|
+ <Row type='flex' justify='space-between'>
|
|
|
+ <Col span={21} style={{ overflow: 'hidden', textOverflow: 'ellipsis' }} >
|
|
|
+ { filterLabel ?
|
|
|
+ ((l.name || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
|
|
|
+ return (
|
|
|
+ fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
|
|
|
+ <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
|
|
|
+ fragment
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )) : l.name
|
|
|
+ }
|
|
|
+ </Col>
|
|
|
+ <Col style={{ textAlign: 'right' }} span={3} >
|
|
|
+ <Icon type='star-o'/>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ }
|
|
|
+ cover={
|
|
|
+ <Col className='cover-body'>
|
|
|
+ <Row className='thumb' onClick={() => {
|
|
|
+ dispatch({ type: 'dashboardDesigner/reset' });
|
|
|
+ dispatch({ type: 'main/redirect', path: '/dashboard/' + l.code });
|
|
|
+ }}>
|
|
|
+ <Thumbnail type={l.type} code={l.code} option={l.chartOption} thumbnail={l.thumbnail}/>
|
|
|
+ </Row>
|
|
|
+ <Row className='desc'>
|
|
|
+ <Ellipsis tooltip={l.description.length > 16} lines={2}>{
|
|
|
+ <span>
|
|
|
+ { filterLabel ?
|
|
|
+ ((l.description || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
|
|
|
+ return (
|
|
|
+ fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
|
|
|
+ <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
|
|
|
+ fragment
|
|
|
+ )
|
|
|
+ }
|
|
|
+ )) : l.description
|
|
|
+ }
|
|
|
+ </span>
|
|
|
+ }</Ellipsis>
|
|
|
+ </Row>
|
|
|
+ <Row className='footer' type='flex' justify='end' align='bottom'>
|
|
|
+ <Col style={{ textAlign: 'left' }} span={22}>
|
|
|
+ <Row>{l.creator} {dateFormat(l.createTime, 'yyyy-MM-dd')}</Row>
|
|
|
+ </Col>
|
|
|
+ <Col span={2} style={{ textAlign: 'right' }}>
|
|
|
+ <Dropdown overlay={operationMenu} trigger={['click']}>
|
|
|
+ <Icon type="ellipsis" />
|
|
|
+ </Dropdown>
|
|
|
+ </Col>
|
|
|
+ </Row>
|
|
|
+ </Col>
|
|
|
+ }
|
|
|
+ >
|
|
|
+ </Card>
|
|
|
+ </CardGrid>
|
|
|
+ ));
|
|
|
+ if(cards.length === 0) {
|
|
|
+ cards = <div style={{ padding: '7px', textAlign: 'center', fontSize: '14px', color: 'rgba(0, 0, 0, 0.45)' }}>暂无数据</div>
|
|
|
+ return cards
|
|
|
+ }
|
|
|
+
|
|
|
+ return cards.slice(0,3); //此处为了开发方便,限制了只显示前3个,之后可能要做成分页
|
|
|
+ }
|
|
|
+
|
|
|
+ render() {
|
|
|
+ return this.generateCard()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export default connect(({ present: { dashboard, homepage, chart } }) => { return { homepage, dashboard, chart }})(CardList)
|