forked from Gitlink/forgeplus-react
463 lines
14 KiB
JavaScript
463 lines
14 KiB
JavaScript
import React, { Component } from "react";
|
|
import { Link } from "react-router-dom";
|
|
|
|
import axios from "axios";
|
|
import { getImageUrl } from "educoder";
|
|
import { Form, Popconfirm, Tag, Spin, Popover, Icon, Button } from "antd";
|
|
import Attachments from "../Upload/attachment";
|
|
import RenderHtml from "../../components/render-html";
|
|
import Comments from "../comments/comments";
|
|
import update from 'immutability-helper'
|
|
import "./order.css";
|
|
|
|
class Detail extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
data: undefined,
|
|
isShow: false,
|
|
imgsrc: "",
|
|
journalsdata: undefined,
|
|
//图片区域是否显示 none 隐藏 block 显示
|
|
display: "none",
|
|
titledisplay: "none",
|
|
countvalue: "",
|
|
//是否需要编辑
|
|
isedit: undefined,
|
|
fileList: undefined,
|
|
limit: 10,
|
|
page: 1,
|
|
search_count: undefined,
|
|
isSpins: true,
|
|
showFiles: true,
|
|
quillValue: "",
|
|
quillFlag: false,
|
|
// 点击放大的图片路径
|
|
imageUrl: undefined,
|
|
visible: false,
|
|
journal_spin: false,
|
|
edit_spin: false,
|
|
};
|
|
}
|
|
|
|
componentDidMount = () => {
|
|
this.getDetail();
|
|
};
|
|
|
|
getDetail = () => {
|
|
const { projectsId, orderId, owner } = this.props.match.params;
|
|
const url = `/${owner}/${projectsId}/issues/${orderId}.json`;
|
|
axios
|
|
.get(url)
|
|
.then((result) => {
|
|
if (result) {
|
|
// todo 增加后台返回
|
|
result.data.emojiComment = {
|
|
"😀": {
|
|
"users": ["test"],
|
|
"total": 1
|
|
}
|
|
}
|
|
this.setState({
|
|
data: result.data,
|
|
isSpins: false
|
|
});
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
};
|
|
|
|
handleok = () => {
|
|
this.setState({
|
|
isShow: false,
|
|
});
|
|
};
|
|
handleCancel = () => {
|
|
this.setState({
|
|
isShow: false,
|
|
});
|
|
};
|
|
|
|
//删除任务信息
|
|
deletedetail = (id) => {
|
|
const { projectsId, orderId, owner } = this.props.match.params;
|
|
const url = `/${owner}/${projectsId}/issues/${orderId}.json`;
|
|
axios
|
|
.delete(url, {
|
|
data: {
|
|
project_id: projectsId,
|
|
id: id,
|
|
},
|
|
})
|
|
.then((result) => {
|
|
if (result) {
|
|
this.props.history.push(`/${owner}/${projectsId}/issues`);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
};
|
|
|
|
//关闭任务
|
|
closedetail = (id) => {
|
|
const { projectsId, orderId, owner } = this.props.match.params;
|
|
const url = `/${owner}/${projectsId}/issues/${orderId}/close_issue.json`;
|
|
axios
|
|
.post(url, {
|
|
project_id: projectsId,
|
|
id: orderId,
|
|
status_id: id,
|
|
})
|
|
.then((result) => {
|
|
if (result) {
|
|
this.getDetail();
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
};
|
|
|
|
editdetail = (count, status) => {
|
|
this.setState({
|
|
countvalue: this.stringJson(count),
|
|
isedit: status,
|
|
});
|
|
};
|
|
|
|
//复制
|
|
copydetail = () => {
|
|
const { projectsId, orderId, owner } = this.props.match.params;
|
|
// const url = `/${owner}/${projectsId}/issues/${orderId}/copy.json`;
|
|
// axios
|
|
// .post(url, {
|
|
// project_id: projectsId,
|
|
// id: orderId,
|
|
// })
|
|
// .then((result) => {
|
|
// if (result) {
|
|
// this.props.history.push(
|
|
// `/${owner}/${projectsId}/issues/${result.data.issue_id}/copyetail`
|
|
// );
|
|
// }
|
|
// })
|
|
// .catch((error) => {
|
|
// console.log(error);
|
|
// });
|
|
this.props.history.push(
|
|
`/${owner}/${projectsId}/issues/${orderId}/copyetail`
|
|
);
|
|
};
|
|
|
|
// 翻页
|
|
ChangePage = (page) => {
|
|
this.setState({
|
|
page,
|
|
isSpins: true,
|
|
});
|
|
const { limit } = this.state;
|
|
this.getjournalslist(page, limit);
|
|
};
|
|
|
|
// 判断是否重新上传文件
|
|
changeIsComplete = (flag) => {
|
|
this.setState({
|
|
showFiles: flag,
|
|
});
|
|
};
|
|
|
|
handleShowImage = (value) => {
|
|
this.setState({
|
|
imageUrl: value,
|
|
visible: true,
|
|
});
|
|
};
|
|
setVisible = (flag) => {
|
|
this.setState({
|
|
visible: flag,
|
|
});
|
|
};
|
|
|
|
stringJson = (value) => {
|
|
let _value = null;
|
|
|
|
try {
|
|
_value = JSON.parse(value);
|
|
} catch (e) {
|
|
_value = value;
|
|
}
|
|
return _value;
|
|
};
|
|
|
|
commentCtx = (v) => {
|
|
return <RenderHtml className="break_word_comments imageLayerParent" value={v} url={this.props.history.location} />;
|
|
};
|
|
|
|
render() {
|
|
const { projectsId, orderId, owner } = this.props.match.params;
|
|
const { current_user } = this.props
|
|
const { data, isSpins } = this.state;
|
|
const emojiList = ["😀", "😅"];
|
|
|
|
const update_emoji_comment = (emoji) => {
|
|
// 无emoji评论
|
|
if (!data.emojiComment || !data.emojiComment[emoji] || data.emojiComment[emoji].users.length == 0) {
|
|
var emojiComment = data.emojiComment ? data.emojiComment : {}
|
|
emojiComment[emoji] = {
|
|
"users": [owner],
|
|
"total": 1
|
|
}
|
|
this.setState({
|
|
data: update(data, { emojiComment: { $set: emojiComment } })
|
|
})
|
|
return
|
|
}
|
|
|
|
// 有emoji评论
|
|
var userList = data.emojiComment[emoji].users
|
|
var addNewUser = true
|
|
for (var i = 0; i < userList.length; i++) {
|
|
if (userList[i] == owner) {
|
|
userList.splice(i, 1);
|
|
addNewUser = false
|
|
break
|
|
}
|
|
}
|
|
if (addNewUser) {
|
|
userList.push(owner)
|
|
}
|
|
var emojiComment = data.emojiComment
|
|
emojiComment[emoji] = {
|
|
"users": userList,
|
|
"total": userList.length
|
|
}
|
|
this.setState({
|
|
data: update(data, { emojiComment: { $set: emojiComment } })
|
|
})
|
|
}
|
|
|
|
const emojiComment = (
|
|
emojiList.map((emoji) => {
|
|
return <Button type="link" className="detail_emoji_comment_menu_item"
|
|
onClick={(e) => update_emoji_comment(emoji)} key={emoji}>{emoji}</Button>
|
|
})
|
|
);
|
|
|
|
const get_color = (type) => {
|
|
if (type === "高") {
|
|
return "#e67e22";
|
|
} else if (type === "正常") {
|
|
return "#28be6c";
|
|
} else if (type === "低") {
|
|
return "#1abc9c";
|
|
} else {
|
|
return "#e74c3c";
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Spin spinning={isSpins}>
|
|
<div className="ProjectListIndex">
|
|
<div className="item-list-right">
|
|
<div className="background-f boder-4">
|
|
<div className="grid-item border-1f pd20 ">
|
|
<Link
|
|
to={`/${data && data.author_login}`}
|
|
className="show-user-link"
|
|
>
|
|
<img
|
|
className="user_img"
|
|
src={getImageUrl(`/${data && data.author_picture}`)}
|
|
alt=""
|
|
width="50"
|
|
height="50"
|
|
/>
|
|
</Link>
|
|
<div className="ml10">
|
|
<div className="ver-middle">
|
|
<span className="mr10 ver-middle">
|
|
<span className="font-16">
|
|
【
|
|
{data && data.issue_classify === "issue"
|
|
? data.tracker
|
|
? data.tracker
|
|
: "缺陷"
|
|
: "合并请求"}
|
|
】
|
|
</span>
|
|
<span className="font-16 fwb" style={{ wordBreak: "break-all" }}>{data && data.subject}</span>
|
|
</span>
|
|
|
|
{data && data.priority && (
|
|
<Tag color={get_color(data.priority)}>{data.priority}</Tag>
|
|
)}
|
|
</div>
|
|
<div className="mt10">
|
|
<span className="color-grey-9 mr5">由</span>
|
|
<Link
|
|
to={`/${data && data.author_login}`}
|
|
className="show-user-link color-blue"
|
|
>
|
|
{data && data.author_name}
|
|
</Link>
|
|
<span className="color-grey-9 ml5">
|
|
添加于 {data && data.created_at}
|
|
</span>
|
|
{data && data.user_permission ? (
|
|
<span className="pull-right 123123">
|
|
<a className="color-blue fr" onClick={this.copydetail}>
|
|
复制
|
|
</a>
|
|
<Popconfirm
|
|
placement="bottom"
|
|
title={"您确定要删除吗"}
|
|
okText="是"
|
|
cancelText="否"
|
|
onConfirm={() => this.deletedetail(orderId)}
|
|
>
|
|
<a
|
|
className="color-blue fr"
|
|
style={{ marginLeft: 20, marginRight: 20 }}
|
|
>
|
|
删除
|
|
</a>
|
|
</Popconfirm>
|
|
|
|
<Link
|
|
to={`/${owner}/${projectsId}/issues/${orderId}/updatedetail`}
|
|
className="color-blue fr"
|
|
>
|
|
编辑
|
|
</Link>
|
|
</span>
|
|
) : (
|
|
""
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="pd20">
|
|
<div className="detail_p">
|
|
{data && data.description && data.description.length > 0 ? (
|
|
this.commentCtx(data.description)
|
|
) : (
|
|
<span className="color-grey-9 ml3 mr3">暂无描述</span>
|
|
)}
|
|
</div>
|
|
{data && data.attachments && data.attachments.length > 0 ? (
|
|
<Attachments
|
|
attachments={data.attachments}
|
|
showNotification={this.props.showNotification}
|
|
/>
|
|
) : (
|
|
""
|
|
)}
|
|
<div className="detail_emoji_comment" >
|
|
<style>
|
|
{`
|
|
.ant-popover-inner-content {
|
|
padding: 2px 5px;
|
|
}
|
|
`}
|
|
</style>
|
|
{current_user && current_user.login ? (
|
|
<Popover content={emojiComment} trigger="click">
|
|
<Button shape="circle"><Icon type="smile" theme="outlined" /></Button>
|
|
</Popover>
|
|
) : ("")
|
|
}
|
|
{current_user && current_user.login && data && data.emojiComment ? (
|
|
Object.keys(data.emojiComment).map(key => {
|
|
const item = data.emojiComment[key]
|
|
if (item.users.length == 0) {
|
|
return
|
|
}
|
|
return <Popover className="detail_emoji_pop" content={item.users.join(",")} key={key}>
|
|
<Button className="detail_emoji_button" shape="round" onClick={(e) => update_emoji_comment(key)}>
|
|
{key}+{item.total}
|
|
</Button>
|
|
</Popover>
|
|
})
|
|
) : ("")
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Comments
|
|
order_id={orderId}
|
|
showNotification={this.props.showNotification}
|
|
{...this.props}
|
|
/>
|
|
</div>
|
|
<div className="list-left list-left-padding">
|
|
<div className="list-right-item-padding background-f boder-4">
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">负责人:</span>
|
|
<span>
|
|
{data && data.assign_user_name ? data.assign_user_name : "--"}
|
|
</span>
|
|
</p>
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">标记:</span>
|
|
<span>
|
|
{data && data.issue_tags ? (
|
|
<span className="grid-item">
|
|
<span
|
|
className="tagColor"
|
|
style={{ background: data.issue_tags[0].color }}
|
|
></span>
|
|
{data.issue_tags[0].name}
|
|
</span>
|
|
) : (
|
|
"--"
|
|
)}
|
|
</span>
|
|
</p>
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">里程碑:</span>
|
|
<span className="title_overflow">
|
|
{data && data.version ? data.version : "--"}
|
|
</span>
|
|
</p>
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">状态:</span>
|
|
<span>
|
|
{data && data.issue_status ? data.issue_status : "--"}
|
|
</span>
|
|
</p>
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">分类:</span>
|
|
<span>{data && data.tracker ? data.tracker : "--"}</span>
|
|
</p>
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">开始日期:</span>
|
|
<span>{data && data.start_date ? data.start_date : "--"}</span>
|
|
</p>
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">结束日期:</span>
|
|
<span>{data && data.due_date ? data.due_date : "--"}</span>
|
|
</p>
|
|
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">完成度:</span>
|
|
<span>{data && data.done_ratio ? data.done_ratio : "--"}</span>
|
|
</p>
|
|
<p className="grid-item-left pb15">
|
|
<span className="issue_detail_info">分支:</span>
|
|
<span>{data && data.branch_name ? data.branch_name : "--"}</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Spin>
|
|
);
|
|
}
|
|
}
|
|
|
|
const WrappedDetailForm = Form.create({ name: "DetailOrderForm" })(Detail);
|
|
export default WrappedDetailForm;
|