forked from Gitlink/forgeplus-react
249 lines
10 KiB
JavaScript
249 lines
10 KiB
JavaScript
import React, { Component } from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import { Dropdown, Icon, Menu, Pagination, Popconfirm, Spin, Button, Tooltip } from 'antd';
|
|
import emp from '../../forge/Issues/Img/emp.png';
|
|
import axios from 'axios';
|
|
import './milepost.scss';
|
|
class Milepost extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
data: undefined,
|
|
limit: 10,
|
|
page: 1,
|
|
order_type: undefined,
|
|
// 里程碑 开启/关闭 状态
|
|
status: 'open',
|
|
order_name: undefined,
|
|
spinings: true,
|
|
// tooltip显隐
|
|
visible: false
|
|
}
|
|
}
|
|
componentDidUpdate(){
|
|
this.updateDocumentTitle();
|
|
}
|
|
|
|
componentDidMount = () => {
|
|
this.getList(1, this.state.limit, this.state.status);
|
|
this.updateDocumentTitle();
|
|
}
|
|
|
|
// 更新网页标题
|
|
updateDocumentTitle(){
|
|
const {projectDetail} = this.props;
|
|
if(projectDetail){
|
|
const { author, name} = projectDetail;
|
|
document.title = `里程碑-${author.name}/${name}`;
|
|
}
|
|
}
|
|
|
|
getList = (page, limit, category, sort_by, sort_direction) => {
|
|
const { projectsId ,owner } = this.props.match.params;
|
|
const url = `/v1/${owner}/${projectsId}/milestones.json`;
|
|
axios.get(url, {
|
|
params: {
|
|
page, limit: limit, category, sort_by, sort_direction
|
|
}
|
|
}).then((result) => {
|
|
if (result) {
|
|
this.setState({
|
|
data: result.data,
|
|
spinings: false
|
|
})
|
|
}
|
|
}).catch((error) => {
|
|
console.log(error);
|
|
})
|
|
}
|
|
|
|
opneMilelist = (type) => {
|
|
if (type) {
|
|
this.setState({
|
|
status: type === 1 ? 'open' : 'closed'
|
|
})
|
|
this.getList(1, this.state.limit, type === 1 ? 'open' : 'closed', this.state.order_name, this.state.order_type);
|
|
}
|
|
}
|
|
|
|
updatestatusemile = (status, arr) => {
|
|
const { projectsId , owner } = this.props.match.params;
|
|
const url = `/${owner}/${projectsId}/milestones/${arr.id}/update_status.json`;
|
|
axios.post(url, {
|
|
project_id: projectsId,
|
|
id: arr.id,
|
|
status: status
|
|
}).then(result => {
|
|
if (result) {
|
|
this.getList(1, this.state.limit, this.state.status, this.state.order_name, this.state.order_type);
|
|
const { getDetail } = this.props;
|
|
getDetail && getDetail();
|
|
}
|
|
}).catch(error => {
|
|
console.log(error);
|
|
})
|
|
}
|
|
|
|
closemile = (arr) => {
|
|
const { projectsId , owner } = this.props.match.params;
|
|
const url = `/${owner}/${projectsId}/milestones/${arr.id}.json`;
|
|
axios.delete(url, {
|
|
data: {
|
|
project_id: projectsId,
|
|
id: arr.id
|
|
}
|
|
}).then((result) => {
|
|
if (result) {
|
|
this.getList(1, this.state.limit, this.state.status, this.state.order_name, this.state.order_type);
|
|
const { getDetail } = this.props;
|
|
getDetail && getDetail();
|
|
}
|
|
}).catch((error) => {
|
|
console.log(error);
|
|
})
|
|
}
|
|
|
|
ChangePage = (page) => {
|
|
document.body.scrollIntoView();
|
|
this.setState({
|
|
page
|
|
})
|
|
this.getList(page, this.state.limit, this.state.status, this.state.order_name, this.state.order_type);
|
|
}
|
|
|
|
// 排序
|
|
arrayList = (e) => {
|
|
const name = e.key !== 'order' ? e.key : undefined;
|
|
const type = e.item.props.value !== 'order' ? e.item.props.value : undefined;
|
|
this.setState({
|
|
order_name: name,
|
|
order_type: type
|
|
})
|
|
this.getList(1, this.state.limit, this.state.status, name, type);
|
|
}
|
|
|
|
// 分页组件
|
|
onShowSizeChange = (current, pageSize) =>{
|
|
this.setState({
|
|
page: 1,
|
|
limit: pageSize
|
|
})
|
|
this.getList(1, pageSize, this.state.status, this.state.order_name, this.state.order_type);
|
|
}
|
|
|
|
// tooltip判断是否显示
|
|
// onVisibleChange = (visible, value) => {
|
|
// console.log('visible, value', visible, value);
|
|
// this.setState({
|
|
// visible: value.length >24 ? visible : false
|
|
// })
|
|
// }
|
|
|
|
render() {
|
|
const { data, limit, page, spinings, status, order_name, order_type, visible } = this.state;
|
|
const { projectsId , owner } = this.props.match.params;
|
|
const { isManager, isDeveloper} = this.props;
|
|
const menu = (
|
|
<Menu className="orderCondition milepostSort" onClick={this.arrayList}>
|
|
<Menu.Item key={'order'} value={'order'}>默认排序</Menu.Item>
|
|
<Menu.Item key={'effective_date'} value="desc">到期日从后到先</Menu.Item>
|
|
<Menu.Item key={'effective_date'} value="asc">到期日从先到后</Menu.Item>
|
|
<Menu.Item key={'percent'} value="asc">完成度从低到高</Menu.Item>
|
|
<Menu.Item key={'percent'} value="desc">完成度从高到低</Menu.Item>
|
|
<Menu.Item key={'issues_count'} value="desc">任务从多到少</Menu.Item>
|
|
<Menu.Item key={'issues_count'} value="asc">任务从少到多</Menu.Item>
|
|
</Menu>
|
|
)
|
|
|
|
// 排序字段 选中显示文本
|
|
const sortByMile = {
|
|
'effective_date':{
|
|
'desc': '到期日从后到先',
|
|
'asc': '到期日从先到后'
|
|
},
|
|
'percent':{
|
|
'desc': '完成度从低到高',
|
|
'asc': '完成度从高到低'
|
|
},
|
|
'issues_count':{
|
|
'desc': '任务从多到少',
|
|
'asc': '任务从少到多'
|
|
},
|
|
'order':{
|
|
'order': '排序'
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Spin spinning={spinings}>
|
|
<div className="main milepostBox">
|
|
{/* 创建里程碑按钮 */}
|
|
{/* <div className='createMilepost mb25'>
|
|
{(isManager || isDeveloper) && <Button type='primary' onClick={() => {this.props.history.push(`/${owner}/${projectsId}/milestones/new`)}} className='createMilepostBtn'>+ 创建里程碑</Button>}
|
|
</div> */}
|
|
{/* 里程碑列表表头 */}
|
|
<div className='milepostHead flexSpaceBetween'>
|
|
<div>
|
|
<span className={`pointBox font-15 postStatus ${status === "closed" ? "" : "active"}`} onClick={() => this.opneMilelist(1)}>开启中<span className='statusCount font-13'>{data && data.opening_milestone_count}</span></span>
|
|
<span className={`pointBox ml35 font-15 postStatus ${status === "closed" ? "active" : ""}`} onClick={() => this.opneMilelist(2)}>已关闭<span className='statusCount font-13'>{data && data.closed_milestone_count}</span></span>
|
|
</div>
|
|
<div>
|
|
{(isManager || isDeveloper) && <Button type='primary' onClick={() => {this.props.history.push(`/${owner}/${projectsId}/milestones/new`)}} className='createMilepostBtn mr20'>+ 创建里程碑</Button>}
|
|
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
|
<span className='pointBox'>{order_name ? sortByMile[order_name][order_type] : '排序'}<Icon type="caret-down" className="ml5"/></span>
|
|
</Dropdown>
|
|
</div>
|
|
</div>
|
|
{/* 里程碑列表展示 */}
|
|
{data && data.milestones && data.milestones.length === 0 && <div className="milestonesNoDate"><img src={emp} alt=""/></div>}
|
|
{data && data.milestones && data.milestones.length > 0 && <div className='milepostList'>
|
|
{data.milestones.map((item, key)=>{
|
|
return <div className='flexSpaceBetween milepostItemBox'>
|
|
<div>
|
|
<div className="flexSpaceBetween">
|
|
<i className="iconfont icon-lichengbeiicon1 font-12 mr10 primaryColor"></i>
|
|
<Link to={`/${owner}/${projectsId}/milestones/${item.id}`} className="font-16 task-hide milepostInfo">{item.name}</Link>
|
|
</div>
|
|
{item.description && item.description.length > 44 ? <Tooltip title={item.description} placement={'topLeft'} overlayStyle={{width: '600px'}}><span className='color-grey-89 task-hide milepostInfo'>{item.description}</span></Tooltip> : <span className='color-grey-89 milepostInfo'>{item.description}</span>}
|
|
</div>
|
|
<div className="flexSpaceBetween actionMileBox">
|
|
<div className="grid-item effectiveDate">
|
|
<i className={`iconfont icon-a-31shijian font-15 mr10 ${item.effective_date ? "effectiveDate" : "color-grey-89"}`}></i>
|
|
<span className={`${item.effective_date ? "" : "color-grey-89"} ${item.effective_date && status !== 'closed' && new Date().getTime()-new Date(`${item.effective_date} 24:0`).getTime() > 0 ? 'outTime' : ''}`}>{item.effective_date || "暂无截止时间"}</span>
|
|
</div>
|
|
<div className="mr10 effectiveDate">
|
|
<span>{item.opened_issues_count || 0}个开启</span>
|
|
<span className='color-grey-89'> | </span>
|
|
<span>{item.close_issues_count || 0}个关闭</span>
|
|
</div>
|
|
{
|
|
(isManager || isDeveloper) && <div className="flexSpaceBetween">
|
|
<Link to={`/${owner}/${projectsId}/milestones/${item.id}/edit`} className="primaryColor"><i className="iconfont icon-a-bianji12 font-14 mr5 primaryColor"></i>编辑</Link>
|
|
<div className="grid-item ml15">
|
|
<i className={`effectiveDate iconfont font-14 mr5 ${item.status === "closed" ? "icon-gouxuan":"icon-shanchu8"}`}></i>
|
|
<a onClick={() => this.updatestatusemile(item.status === "closed" ? "open" : "closed", item)} className="effectiveDate">{item.status === "closed" ? "开启" : "关闭"}</a>
|
|
</div>
|
|
<div className="grid-item ml15">
|
|
<i className="iconfont icon-fuzhi-shanchu font-14 mr5 colorRed" ></i>
|
|
<Popconfirm placement="bottom" title={'是否删除里程碑?'} okText="是" cancelText="否" onConfirm={() => this.closemile(item)}>
|
|
<a className="colorRed">删除</a>
|
|
</Popconfirm>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
})}
|
|
</div>}
|
|
{
|
|
data && data.total_count > limit ?
|
|
<div className="mt30 mb50 edu-txt-right">
|
|
<Pagination current={page} total={data && data.total_count} pageSize={limit} onChange={this.ChangePage} showQuickJumper showSizeChanger onShowSizeChange={this.onShowSizeChange}></Pagination>
|
|
</div> : ""
|
|
}
|
|
</div>
|
|
</Spin>
|
|
)
|
|
}
|
|
}
|
|
export default Milepost; |