620 lines
21 KiB
JavaScript
620 lines
21 KiB
JavaScript
import React, { Component } from "react";
|
||
import { Form, Input, Select, Button, DatePicker ,Spin } from "antd";
|
||
import Upload from "../Upload/Index";
|
||
import UploadImg from "../Images/upload.png";
|
||
import MDEditor from "../../modules/tpm/challengesnew/tpm-md-editor";
|
||
import moment from "moment";
|
||
import "./order.scss";
|
||
import Attachments from "../Upload/attachment";
|
||
|
||
import axios from "axios";
|
||
|
||
const Option = Select.Option;
|
||
class order_form extends Component {
|
||
constructor(props) {
|
||
super(props);
|
||
this.state = {
|
||
branch_name: "",
|
||
issue_tag_ids: "",
|
||
fixed_version_id: "",
|
||
tracker_id: "4",
|
||
issue_type: "1",
|
||
status_id: "1",
|
||
assigned_to_id: "",
|
||
priority_id: "2",
|
||
done_ratio: "0%",
|
||
issue_chosen: undefined,
|
||
branches: undefined,
|
||
fileList: undefined,
|
||
description: undefined,
|
||
isSpin: true,
|
||
token: undefined,
|
||
start_date: "",
|
||
due_date: "",
|
||
subject: "",
|
||
get_attachments: undefined,
|
||
show_token: false,
|
||
cannot_edit: false,
|
||
issue_current_user: true,
|
||
atWhoLoginList:undefined
|
||
};
|
||
}
|
||
componentDidUpdate=(prevPros)=>{
|
||
if(prevPros && this.props && this.props.checkIfLogin()===false){
|
||
this.props.history.push("/403")
|
||
return
|
||
}
|
||
this.updateDocumentTitle();
|
||
}
|
||
componentDidMount = () => {
|
||
this.getSelectList();
|
||
};
|
||
|
||
// 更新网页标题
|
||
updateDocumentTitle(){
|
||
const {form_type, projectDetail} = this.props;
|
||
const {subject} = this.state;
|
||
if(projectDetail && form_type){
|
||
const { author, name} = projectDetail;
|
||
if(form_type === 'feedback'){
|
||
document.title = `意见反馈`
|
||
}else if(form_type === 'new'){
|
||
document.title = `新建任务-${author.name}/${name}`
|
||
}else{
|
||
subject && (document.title = `${subject}-任务-${author.name}/${name}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
copyIssueAtWhoInit = (description) =>{
|
||
if (description.indexOf("@") !== -1){
|
||
this.setState({isSpin: true});
|
||
const { projectsId, owner } = this.props.match.params;
|
||
axios.get(`/${owner}/${projectsId}/members.json`).then(response => {
|
||
this.setState({ isSpin: false});
|
||
if (response.data.total_count !== 0) {
|
||
const allUser = response.data.users;
|
||
if (allUser && allUser.length !== 0 && description && description.indexOf("@") !== -1) {
|
||
const list = new Set();
|
||
allUser.map(item => {
|
||
if (description.indexOf(`[@${item.username}](/${item.login})`) !== -1) {
|
||
list.add(item.login);
|
||
}
|
||
})
|
||
this.setState({ atWhoLoginList: Array.from(list) });
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
get_detail = () => {
|
||
this.setState({
|
||
isSpin:true
|
||
})
|
||
const { projectsId, orderId, owner } = this.props.match.params;
|
||
const url = `/${owner}/${projectsId}/issues/${orderId}/edit.json`;
|
||
axios.get(url).then((result) => {
|
||
if (result) {
|
||
let data ={
|
||
branch_name: result.data.branch_name,
|
||
issue_tag_ids:
|
||
result.data.issue_tags && result.data.issue_tags[0].id ?
|
||
String(result.data.issue_tags[0].id) : ""
|
||
,
|
||
fixed_version_id: result.data.fixed_version_id ? String(result.data.fixed_version_id) : "",
|
||
tracker_id: result.data.tracker_id ? String(result.data.tracker_id) : "",
|
||
issue_type: result.data.issue_type,
|
||
status_id: result.data.status_id ? String(result.data.status_id) : "",
|
||
assigned_to_id: result.data.assigned_to_id ? String(result.data.assigned_to_id) : "",
|
||
priority_id: result.data.priority_id ? String(result.data.priority_id) : "",
|
||
done_ratio: result.data.done_ratio,
|
||
fileList: undefined,
|
||
description: result.data.description,
|
||
isSpin: false,
|
||
token: result.data.token,
|
||
get_attachments: result.data.attachments,
|
||
start_date: result.data.start_date,
|
||
due_date: result.data.due_date,
|
||
subject: result.data.subject,
|
||
}
|
||
if (this.props.form_type === "copy" && result.data.description){
|
||
this.copyIssueAtWhoInit(result.data.description);
|
||
}
|
||
this.props.form.setFieldsValue({ ...data });
|
||
this.setState({ ...data });
|
||
}
|
||
}).catch((error) => {
|
||
this.setState({
|
||
isSpin:false
|
||
})
|
||
console.log(error);
|
||
});
|
||
};
|
||
getSelectList = () => {
|
||
let {projectsId, owner , milepostId} = this.props.match.params;
|
||
|
||
const url = `/${owner}/${projectsId}/issues/new.json`;
|
||
axios.get(url).then((result) => {
|
||
if (result && result.data) {
|
||
this.setState({
|
||
issue_chosen: result.data.issue_chosen,
|
||
branches: result.data.issue_chosen.branches,
|
||
isSpin:false
|
||
});
|
||
|
||
if(this.props.form_type === "feedback"){
|
||
let data ={
|
||
//指定指派成员,类型:缺陷,优先度:正常,issue状态:新增
|
||
tracker_id: "1",
|
||
assigned_to_id: window.location.host === "www.gitlink.org.cn" ? "86107":"36480",
|
||
priority_id: "2",
|
||
status_id: "1",
|
||
description:"####问题描述\n\n\n####重现问题步骤\n\n\n####截图\n\n\n####建议解决办法\n",
|
||
}
|
||
this.setState({ ...data });
|
||
this.props.form.setFieldsValue({
|
||
...this.state,
|
||
fixed_version_id: milepostId || ""
|
||
});
|
||
|
||
}else if(this.props.form_type !== "new"){
|
||
this.get_detail();
|
||
}else{
|
||
this.props.form.setFieldsValue({
|
||
...this.state,
|
||
fixed_version_id: milepostId || ""
|
||
});
|
||
}
|
||
}
|
||
}).catch((error) => {
|
||
console.log(error);
|
||
});
|
||
};
|
||
|
||
renderSelect = (list) => {
|
||
if (list && list.length > 0) {
|
||
return list.map((item, key) => {
|
||
return (
|
||
<Option key={key + 1} value={String(item.id)}>
|
||
{item.color && <span className="tagColor" style={{backgroundColor:`${item.color}`}}></span>}{item.name}
|
||
</Option>
|
||
);
|
||
});
|
||
}
|
||
};
|
||
|
||
// 创建
|
||
handleSubmit = () => {
|
||
|
||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||
if (!err) {
|
||
this.setState({
|
||
isSpin: true,
|
||
});
|
||
const { form_type } = this.props;
|
||
const { projectsId , orderId , owner } = this.props.match.params;
|
||
|
||
const { fileList } = this.state;
|
||
|
||
if (values.status_id === "新增") {
|
||
values.status_id = "1";
|
||
}
|
||
if (values.tracker_id === "缺陷") {
|
||
values.tracker_id = "1";
|
||
}
|
||
if (values.priority_id === "正常") {
|
||
values.priority_id = "2";
|
||
}
|
||
if (values.done_ratio === "0%") {
|
||
values.done_ratio = "0";
|
||
}
|
||
if (values.issue_tag_ids.length > 0) {
|
||
values.issue_tag_ids = [values.issue_tag_ids];
|
||
}
|
||
const { description, start_date, due_date, issue_type , atWhoLoginList } = this.state;
|
||
if (form_type !== "edit") {
|
||
const url = `/${owner}/${projectsId}/issues.json`;
|
||
axios.post(url, {
|
||
...values,
|
||
description: description,
|
||
attachment_ids: fileList,
|
||
start_date: start_date,
|
||
due_date: due_date,
|
||
issue_type: issue_type,
|
||
receivers_login:atWhoLoginList,
|
||
}).then((result) => {
|
||
if (result && result.data.id) {
|
||
this.props.showNotification("任务创建成功!");
|
||
this.props.history.push(`/${owner}/${projectsId}/issues/${result.data.id}`);
|
||
const { getDetail } = this.props;
|
||
getDetail && getDetail();
|
||
this.props.showNpsModal("createIssue", 1);
|
||
}
|
||
this.setState({
|
||
isSpin: false,
|
||
});
|
||
})
|
||
.catch((error) => {
|
||
this.setState({
|
||
isSpin: false
|
||
});
|
||
});
|
||
} else {
|
||
const url = `/${owner}/${projectsId}/issues/${orderId}.json`;
|
||
axios.put(url, {
|
||
description: description,
|
||
attachment_ids: fileList,
|
||
start_date: start_date,
|
||
due_date: due_date,
|
||
issue_type: issue_type,
|
||
...values,
|
||
receivers_login:atWhoLoginList,
|
||
}).then((result) => {
|
||
if (result) {
|
||
this.props.history.push(`/${owner}/${projectsId}/issues/${orderId}`);
|
||
this.props.showNotification("任务更新成功!");
|
||
const { getDetail } = this.props;
|
||
getDetail && getDetail();
|
||
this.props.showNpsModal("submitIssue", 1);
|
||
}
|
||
this.setState({
|
||
isSpin: false
|
||
});
|
||
})
|
||
.catch((error) => {
|
||
this.setState({
|
||
isSpin: false
|
||
});
|
||
});
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
// 获取上传后的文件id数组
|
||
UploadFunc = (fileList) => {
|
||
this.setState({
|
||
fileList,
|
||
});
|
||
};
|
||
|
||
onContentChange = (value) => {
|
||
this.setState({
|
||
description: value,
|
||
});
|
||
};
|
||
|
||
//issue中at谁列表(存储:login)
|
||
changeAtWhoLoginList = (loginList) =>{
|
||
let list = new Set(this.state.atWhoLoginList);
|
||
loginList.map(item => list.add(item));
|
||
this.setState({
|
||
atWhoLoginList: Array.from(list),
|
||
});
|
||
};
|
||
|
||
// 修改开始时间
|
||
changeBeginTime = (start_date, value) => {
|
||
this.setState({
|
||
start_date: value,
|
||
});
|
||
};
|
||
changeEndTime = (due_date, value) => {
|
||
this.setState({
|
||
due_date: value,
|
||
});
|
||
};
|
||
// 切换完成度
|
||
changeRatio = (e) => {
|
||
if (e === "0") {
|
||
this.props.form.setFieldsValue({
|
||
status_id: "1",
|
||
});
|
||
this.setState({
|
||
status_id: "1",
|
||
});
|
||
} else if (e === "100") {
|
||
this.props.form.setFieldsValue({
|
||
status_id: "3",
|
||
});
|
||
this.setState({
|
||
status_id: "3",
|
||
});
|
||
} else {
|
||
this.props.form.setFieldsValue({
|
||
status_id: "2",
|
||
});
|
||
this.setState({
|
||
status_id: "2",
|
||
});
|
||
}
|
||
};
|
||
//切换状态
|
||
changeStatus = (e) => {
|
||
if (e === "1") {
|
||
this.props.form.setFieldsValue({
|
||
done_ratio: "0",
|
||
});
|
||
this.setState({
|
||
done_ratio: "0",
|
||
issue_current_user: true,
|
||
});
|
||
} else if (e === "3") {
|
||
this.props.form.setFieldsValue({
|
||
done_ratio: "100",
|
||
});
|
||
this.setState({
|
||
done_ratio: "100",
|
||
issue_current_user: true,
|
||
});
|
||
}else if (e === "5") {
|
||
this.setState({
|
||
issue_current_user: false,
|
||
});
|
||
}
|
||
};
|
||
|
||
//切换是否上链操作
|
||
change_issue_type = (e) => {
|
||
if (e) {
|
||
this.setState({
|
||
issue_type: "2",
|
||
show_token: true,
|
||
});
|
||
} else {
|
||
this.setState({
|
||
issue_type: "1",
|
||
show_token: false,
|
||
});
|
||
}
|
||
};
|
||
|
||
render() {
|
||
const { getFieldDecorator } = this.props.form;
|
||
const { projectsId , owner } = this.props.match.params;
|
||
const { orderId } = this.props.match.params;
|
||
const { form_type } = this.props;
|
||
const {issue_chosen,branches,description,get_attachments,isSpin,start_date,due_date} = this.state;
|
||
return (
|
||
<Spin spinning={isSpin}>
|
||
<div className="ProjectListIndex issue-form-index">
|
||
<Form className="width100 display-in" size="small">
|
||
<div className="list-right">
|
||
<div className="pd20">
|
||
<h3 className="mb15">
|
||
{form_type === "edit" ? "编辑" :( form_type === "copy" ? "复制" : "新建")}任务
|
||
</h3>
|
||
<Form.Item>
|
||
{getFieldDecorator("subject", {
|
||
rules: [
|
||
{
|
||
required: true,
|
||
message: "请填写任务标题",
|
||
},
|
||
]
|
||
})(<Input placeholder="标题" size="large" maxLength={200}/>)}
|
||
</Form.Item>
|
||
<div className="quillContent">
|
||
<MDEditor
|
||
placeholder={"请输入描述信息"}
|
||
height={500}
|
||
mdID={"order-new-description"}
|
||
initValue={description}
|
||
onChange={this.onContentChange}
|
||
isCanAtme = {true}
|
||
changeAtWhoLoginList = {this.changeAtWhoLoginList}
|
||
owner = {owner}
|
||
projectsId = {projectsId}
|
||
></MDEditor>
|
||
</div>
|
||
{get_attachments && get_attachments.length > 0 ? (
|
||
<div className="mt20">
|
||
<Attachments
|
||
attachments={get_attachments}
|
||
showNotification={this.props.showNotification}
|
||
canDelete={true}
|
||
/>
|
||
</div>
|
||
) : (
|
||
""
|
||
)}
|
||
<Upload
|
||
className="commentStyle mt30"
|
||
isComplete={true}
|
||
load={this.UploadFunc}
|
||
icon={
|
||
<img
|
||
src={UploadImg}
|
||
width="58"
|
||
alt=""
|
||
style={{ marginBottom: 15 }}
|
||
/>
|
||
}
|
||
size={100}
|
||
showNotification={this.props.showNotification}
|
||
/>
|
||
<p className="clearfix mt20">
|
||
<Button
|
||
type="primary"
|
||
onClick={this.handleSubmit}
|
||
>
|
||
<span className="plr10">
|
||
{form_type === "new" || form_type === "feedback" ? "创建" : "提交"}
|
||
</span>
|
||
</Button>
|
||
<Button
|
||
type="default"
|
||
className="ml30"
|
||
onClick={()=>
|
||
this.props.history.push(form_type === "new" || form_type === "feedback" ? `/${owner}/${projectsId || orderId}/issues` : `/${owner}/${projectsId}/issues/${orderId}`)}
|
||
>
|
||
<span className="plr10">取消</span>
|
||
</Button>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div className="list-left list-left-padding issue-edit-form-right">
|
||
<div className="pd20 background-f issue-form-right">
|
||
<Form.Item label="指派成员">
|
||
{getFieldDecorator("assigned_to_id", {rules: []})(
|
||
<Select
|
||
showSearch
|
||
className="searchIcon"
|
||
showArrow={true}
|
||
suffixIcon={<i className="iconfont icon-sousuo1"></i>}
|
||
optionFilterProp="children"
|
||
filterOption={(input, option) =>
|
||
option.props.children[1] && option.props.children[1].toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||
}
|
||
placeholder="搜索成员"
|
||
>
|
||
<Option value={""}>未指派成员</Option>
|
||
{this.renderSelect(
|
||
issue_chosen && issue_chosen.assign_user
|
||
)}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
<Form.Item label="状态">
|
||
{getFieldDecorator("status_id", {
|
||
rules: [{
|
||
required: true,
|
||
message: "请选择完成状态",
|
||
}]
|
||
})(
|
||
<Select onChange={this.changeStatus}>
|
||
{this.renderSelect( issue_chosen && issue_chosen.issue_status )}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
<Form.Item label="类型">
|
||
{getFieldDecorator("tracker_id", {
|
||
rules: [{
|
||
required: true,
|
||
message: "请选择类型",
|
||
}]
|
||
})(
|
||
<Select>
|
||
{this.renderSelect(issue_chosen && issue_chosen.tracker)}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
|
||
<Form.Item label="优先度">
|
||
{getFieldDecorator("priority_id", {
|
||
rules: [{
|
||
required: true,
|
||
message: "请选择优先度",
|
||
}]
|
||
})(
|
||
<Select>
|
||
{this.renderSelect(issue_chosen && issue_chosen.priority)}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
|
||
<Form.Item label="里程碑">
|
||
{getFieldDecorator("fixed_version_id", {rules: []})(
|
||
<Select
|
||
showSearch
|
||
className="searchIcon"
|
||
showArrow={true}
|
||
suffixIcon={<i className="iconfont icon-sousuo1"></i>}
|
||
optionFilterProp="children"
|
||
filterOption={(input, option) =>
|
||
option.props.children[1] && option.props.children[1].toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||
}
|
||
>
|
||
<Option value={""}>
|
||
{issue_chosen && issue_chosen.issue_version.length > 0
|
||
? "未选择里程碑"
|
||
: "请添加里程碑"}
|
||
</Option>
|
||
{this.renderSelect(
|
||
issue_chosen && issue_chosen.issue_version
|
||
)}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
<Form.Item label="标记">
|
||
{getFieldDecorator("issue_tag_ids", {rules: []})(
|
||
<Select
|
||
showSearch
|
||
className="searchIcon"
|
||
showArrow={true}
|
||
suffixIcon={<i className="iconfont icon-sousuo1"></i>}
|
||
optionFilterProp="children"
|
||
filterOption={(input, option) =>
|
||
option.props.children[1] && option.props.children[1].toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||
}
|
||
>
|
||
<Option value={""}>
|
||
{issue_chosen && issue_chosen.issue_tag.length > 0
|
||
? "未选择标记"
|
||
: "请在仓库设置里添加标记"}
|
||
</Option>
|
||
{this.renderSelect(issue_chosen && issue_chosen.issue_tag)}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
|
||
<Form.Item label="开始日期">
|
||
<DatePicker
|
||
value={start_date ? moment(start_date, "YYYY-MM-DD") : null}
|
||
style={{ width: "100%" }}
|
||
placeholder="请选择开始日期"
|
||
onChange={this.changeBeginTime}
|
||
/>
|
||
</Form.Item>
|
||
<Form.Item label="结束日期">
|
||
<DatePicker
|
||
value={due_date ? moment(due_date, "YYYY-MM-DD") : null}
|
||
style={{ width: "100%" }}
|
||
placeholder="请选择结束日期"
|
||
onChange={this.changeEndTime}
|
||
/>
|
||
</Form.Item>
|
||
<Form.Item label="完成度">
|
||
{getFieldDecorator("done_ratio", {rules: []})(
|
||
<Select onChange={this.changeRatio}>
|
||
{this.renderSelect(issue_chosen && issue_chosen.done_ratio)}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
<Form.Item label="指定分支">
|
||
{getFieldDecorator("branch_name", {
|
||
rules: []
|
||
})(
|
||
<Select
|
||
showSearch
|
||
className="searchIcon"
|
||
showArrow={true}
|
||
suffixIcon={<i className="iconfont icon-sousuo1"></i>}
|
||
optionFilterProp="children"
|
||
filterOption={(input, option) =>
|
||
option.props.children && option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||
}
|
||
>
|
||
<Option value={""}>分支未指定</Option>
|
||
{branches && branches.length > 0 && branches.map((item, key) => {
|
||
return (
|
||
<Option value={item} key={key}>
|
||
{item}
|
||
</Option>
|
||
);
|
||
})}
|
||
</Select>
|
||
)}
|
||
</Form.Item>
|
||
</div>
|
||
</div>
|
||
</Form>
|
||
</div>
|
||
</Spin>
|
||
);
|
||
}
|
||
}
|
||
const WrappedNewForm = Form.create({ name: "NewOrderForm" })(order_form);
|
||
export default WrappedNewForm;
|