forked from Gitlink/forgeplus-react
391 lines
16 KiB
JavaScript
391 lines
16 KiB
JavaScript
import React , { useEffect , useState , forwardRef } from 'react';
|
||
import { Spin , Form } from 'antd';
|
||
import { getImageUrl } from 'educoder';
|
||
import { Link } from 'react-router-dom';
|
||
import { Box , LongWidth } from '../../Component/layout';
|
||
import RenderHtml from "../../../components/render-html";
|
||
import EditMenus from '../Component/editMenus';
|
||
import Add from '../Component/comments/add';
|
||
import NewPanel from '../Component/newPanel';
|
||
import Attachments from "../../Upload/attachment";
|
||
import AddTagsBox from '../Component/addTagsBox';
|
||
import DelBox from '../Component/delBox';
|
||
import Date from '../Component/date';
|
||
import moment from 'moment';
|
||
import Copy from '../Component/copy';
|
||
import axios from 'axios';
|
||
|
||
function Details(props){
|
||
const [ details , setDetails ] = useState(undefined);
|
||
const owner = props.match.params.owner;
|
||
const projectsId = props.match.params.projectsId;
|
||
const index = props.match.params.index;
|
||
|
||
const [ statusList , setStatusList ] = useState([]);
|
||
const [ prioritiesList , setPrioritiesList ] = useState([]);
|
||
const [ chargeList , setChargeList ] = useState([]);
|
||
const [ charge , setCharge ] = useState(undefined);
|
||
const [ millstoneList , setMillstoneList ] = useState([]);
|
||
const [ millstone , setMillstone ] = useState(undefined);
|
||
const [ tagList , setTagList ] = useState(undefined);
|
||
const [ tag , setTag ] = useState(undefined);
|
||
const [ branchList , setBranchList ] = useState(undefined);
|
||
const [ branch , setBranch ] = useState(undefined);
|
||
|
||
const [ charegeId , setCharegeId ] = useState([]);
|
||
const [ statusId , setStatusId ] = useState([`1`]);
|
||
const [ prioritiesId , setPrioritiesId ] = useState([`2`]);
|
||
const [ tagId , setTagId ] = useState([]);
|
||
const [ millstoneId , setMillstoneId ] = useState([]);
|
||
const [ branchId , setBranchId ] = useState([]);
|
||
|
||
const [ names , setNames ] = useState({author_name:undefined,issue_priorities_name:undefined,issue_tag_name:undefined,milestone_name:undefined,sortby_name:undefined,status_name:undefined,assigner_name:undefined});
|
||
|
||
const [ visible , setVisible ] = useState(false);
|
||
const [ delVisible , setDelVisible] = useState(false);
|
||
const [ edit , setEdit] = useState(false);
|
||
const [ copy , setCopy] = useState(false);
|
||
|
||
const [ start_date, setStartDate ] = useState("");
|
||
const [ due_date, setDueDate ] = useState("");
|
||
const pathname = props.history.location.pathname;
|
||
|
||
useEffect(()=>{
|
||
if(pathname === `/${owner}/${projectsId}/issues/${index}/copy`){
|
||
setEdit(true);
|
||
setCopy(true);
|
||
}else{
|
||
setEdit(false);
|
||
setCopy(false);
|
||
}
|
||
},[pathname])
|
||
|
||
useEffect(()=>{
|
||
if(index){
|
||
Init();
|
||
}
|
||
},[index])
|
||
|
||
function Init(){
|
||
const url = `/v1/${owner}/${projectsId}/issues/${index}`;
|
||
axios.get(url).then(result=>{
|
||
if(result && result.data){
|
||
let data = result.data;
|
||
setDetails(data);
|
||
let cIds = data.assigners && data.assigners.length>0 ? data.assigners.map((i)=>{return i.id.toString();}):undefined;
|
||
let cNames = data.assigners && data.assigners.length>0 ? data.assigners.map((i)=>{return i.name.toString();}):undefined;
|
||
setCharegeId(cIds);
|
||
setStatusId([`${data.status && data.status.id}`]);
|
||
setPrioritiesId([`${data.priority && data.priority.id}`]);
|
||
let tags = data.tags && data.tags.length>0 ? data.tags.map((i)=>{return i.id.toString();}):undefined;
|
||
let tagNames = data.tags && data.tags.length>0 ? data.tags.map((i)=>{return i.name.toString();}):undefined;
|
||
setTagId(tags);
|
||
setMillstoneId((data.milestone && data.milestone.id) ? [`${ data.milestone.id}`] :undefined)
|
||
setBranchId(data.branch_name && [data.branch_name]);
|
||
const n = {
|
||
issue_priorities_name:data.priority ? [`${data.priority.name}`]:undefined,
|
||
issue_tag_name:tagNames && [tagNames],
|
||
milestone_name:data.milestone ? [`${data.milestone.name}`]:undefined,
|
||
status_name:data.status ? [`${data.status.name}`]:undefined,
|
||
assigner_name:cNames && [cNames]
|
||
}
|
||
setNames(n);
|
||
data.start_date && setStartDate(moment(data.start_date).format('YYYY-MM-DD'));
|
||
data.due_date && setDueDate(moment(data.due_date).format('YYYY-MM-DD'));
|
||
|
||
const {projectDetail} = props;
|
||
if(projectDetail){
|
||
const { author, name} = projectDetail;
|
||
document.title = `${data.subject}-疑修-${author.name}/${name}`;
|
||
}
|
||
}
|
||
}).catch(error=>{})
|
||
}
|
||
|
||
|
||
function statusTag(name){
|
||
switch (name) {
|
||
case "低":
|
||
return "status low";
|
||
case "正常":
|
||
return "status normal";
|
||
case "高":
|
||
return "status hight";
|
||
default:
|
||
return "status urgent";
|
||
}
|
||
}
|
||
// 获取状态列表
|
||
useEffect(()=>{
|
||
getStatus();
|
||
},[])
|
||
function getStatus(){
|
||
const url = `/v1/${owner}/${projectsId}/issue_statues`;
|
||
axios.get(url).then(result=>{
|
||
if(result && result.data){
|
||
setStatusList(result.data.statues);
|
||
}
|
||
})
|
||
}
|
||
// 获取优先级列表
|
||
useEffect(()=>{
|
||
getPriorities();
|
||
},[])
|
||
|
||
function getPriorities(){
|
||
const url = `/v1/${owner}/${projectsId}/issue_priorities`;
|
||
axios.get(url).then(result=>{
|
||
if(result && result.data){
|
||
let priorities = result.data.priorities;
|
||
let array =[];
|
||
let colors = ["#1abcb1","#28be6c","#db3d1d","#db3d1d"];
|
||
if(priorities && priorities.length>0){
|
||
array = priorities.map((i,k)=>{
|
||
let arr = {...i,color:colors[k]}
|
||
return arr;
|
||
})
|
||
}
|
||
setPrioritiesList(array);
|
||
}
|
||
})
|
||
}
|
||
|
||
// 获取负责人列表
|
||
useEffect(()=>{
|
||
getCharge();
|
||
},[charge])
|
||
|
||
function getCharge(){
|
||
const url = `/v1/${owner}/${projectsId}/collaborators`;
|
||
axios.get(url,{params:{keyword:charge,only_name:true}}).then(result=>{
|
||
if(result && result.data){
|
||
setChargeList(result.data.collaborators);
|
||
}
|
||
})
|
||
}
|
||
// 获取里程碑列表
|
||
useEffect(()=>{
|
||
getMillstone();
|
||
},[millstone])
|
||
|
||
function getMillstone(){
|
||
const url = `/v1/${owner}/${projectsId}/milestones`;
|
||
axios.get(url,{params:{keyword:millstone,only_name:true}}).then(result=>{
|
||
if(result && result.data){
|
||
setMillstoneList(result.data.milestones);
|
||
}
|
||
})
|
||
}
|
||
// 获取标记列表
|
||
useEffect(()=>{
|
||
getSign();
|
||
},[tag])
|
||
function getSign(){
|
||
const url = `/v1/${owner}/${projectsId}/issue_tags`;
|
||
axios.get(url,{params:{keyword:tag,only_name:true}}).then(result=>{
|
||
if(result && result.data){
|
||
setTagList(result.data.issue_tags);
|
||
}
|
||
})
|
||
}
|
||
// 获取标记列表
|
||
useEffect(()=>{
|
||
getBranch(branch);
|
||
},[branch])
|
||
function getBranch(branch){
|
||
if(branch){
|
||
let b = [...branchList];
|
||
let l = b.filter(i=>i.name.indexOf(branch)>-1);
|
||
setBranchList(l);
|
||
return ;
|
||
}
|
||
const url = `/${owner}/${projectsId}/branches.json`;
|
||
axios.get(url,{params:{keyword:tag}}).then(result=>{
|
||
if(result && result.data){
|
||
setBranchList(result.data);
|
||
}
|
||
})
|
||
}
|
||
|
||
function onSuccess(){
|
||
getSign();
|
||
setVisible(false);
|
||
}
|
||
|
||
// 可单个编辑保存右侧的项(!copy:非复制状态下)
|
||
function saveForeach(c,s,p,t,m,b,sDate,eDate){
|
||
if(!copy){
|
||
const url = `/v1/${owner}/${projectsId}/issues/${index}`;
|
||
axios.patch(url,{
|
||
branch_name: b ? b.join(",") :undefined,
|
||
status_id: s ? s.join(",") : undefined,
|
||
priority_id: p ? p.join(",") :undefined,
|
||
milestone_id: m ? m.join(",") :undefined,
|
||
issue_tag_ids: t?t:undefined,
|
||
assigner_ids: c?c:undefined,
|
||
start_date:sDate,
|
||
due_date:eDate
|
||
}).then(result=>{
|
||
if(result){
|
||
Init();
|
||
}
|
||
}).catch(error=>{})
|
||
}
|
||
}
|
||
|
||
function deleteFunc(){
|
||
const url = `/v1/${owner}/${projectsId}/issues/${index}`;
|
||
axios.delete(url).then(result=>{
|
||
if(result){
|
||
props.showNotification("疑修删除成功!");
|
||
props.history.push(`/${owner}/${projectsId}/issues`);
|
||
}
|
||
}).catch(error=>{})
|
||
}
|
||
|
||
// 编辑保存
|
||
function createFunc(values,fileList,receivers_login,description){
|
||
let params ={
|
||
subject: values.subject,
|
||
attachment_ids: fileList,
|
||
receivers_login: receivers_login,
|
||
description: description
|
||
}
|
||
if(!copy){
|
||
// 调用编辑保存接口
|
||
const url = `/v1/${owner}/${projectsId}/issues/${index}`;
|
||
axios.patch(url,{
|
||
...params
|
||
}).then(result=>{
|
||
if(result){
|
||
props.showNotification("疑修更新成功!");
|
||
Init();
|
||
setEdit(false);
|
||
}
|
||
}).catch(error=>{})
|
||
}else{
|
||
// 调用新建保存接口
|
||
console.log(branchId,statusId,prioritiesId,millstoneId,tagId, charegeId);
|
||
const url = `/v1/${owner}/${projectsId}/issues`;
|
||
axios.post(url,{
|
||
...params,
|
||
branch_name:branchId && branchId.join(","),
|
||
status_id:statusId && statusId.join(","),
|
||
priority_id:prioritiesId && prioritiesId.join(","),
|
||
milestone_id:millstoneId && millstoneId.join(","),
|
||
issue_tag_ids:tagId,
|
||
assigner_ids:charegeId,
|
||
start_date,due_date
|
||
}).then(result=>{
|
||
debugger;
|
||
if(result && result.data && result.data.project_issues_index){
|
||
props.showNotification("任务复制成功!");
|
||
props.history.push(`/${owner}/${projectsId}/issues/${result.data.project_issues_index}`);
|
||
}
|
||
}).catch(error=>{})
|
||
}
|
||
}
|
||
|
||
// 取消编辑或复制
|
||
function onCancel(){
|
||
if(copy){
|
||
props.history.push(`/${owner}/${projectsId}/issues/${index}`);
|
||
}else{
|
||
setEdit(false)
|
||
}
|
||
}
|
||
let host = window.location.hostname === "localhost" ? "testforgeplus.trustie.net" : window.location.hostname;
|
||
return(
|
||
details ?
|
||
<Box>
|
||
<LongWidth>
|
||
<DelBox
|
||
visible={delVisible}
|
||
onCancel={()=>setDelVisible(false)}
|
||
onSuccess={deleteFunc}
|
||
content={<div style={{paddingTop:"3px"}}><p className="font-15 mb20">您确定要删除当前疑修?</p></div>}
|
||
/>
|
||
<AddTagsBox
|
||
owner={owner}
|
||
projectsId={projectsId}
|
||
visible={visible}
|
||
onCancel={()=>setVisible(false)} onSuccess={onSuccess}
|
||
/>
|
||
{
|
||
edit ?
|
||
<div style={{paddingTop:"25px"}} >
|
||
<NewPanel
|
||
{...props}
|
||
onCancel={onCancel}
|
||
title={details.subject}
|
||
desc={details.description}
|
||
files={details.attachments}
|
||
createFunc={createFunc}
|
||
owner = {owner} projectsId = {projectsId}
|
||
/>
|
||
</div>
|
||
:
|
||
<React.Fragment>
|
||
<div className="detailbanner">
|
||
<div className="detailtitle">
|
||
<div className="ilog">
|
||
{details.priority && <span className={statusTag(details.priority.name)}>{ details.priority.name }</span> }
|
||
<Copy value={`${host}/${owner}/${projectsId}/issues/${index}`}><span className="number">#{details.project_issues_index}</span></Copy>
|
||
</div>
|
||
<div>
|
||
<p className="name">{details.subject}</p>
|
||
{
|
||
details.author &&
|
||
<div>
|
||
<a className="author"><img src={getImageUrl(details.author.image_url)} alt="" />{details.author.name}</a>
|
||
<span className="ml10" style={{color:"#898d9d"}}>添加于{details.created_at}</span>
|
||
</div>
|
||
}
|
||
</div>
|
||
</div>
|
||
{
|
||
details.user_permission &&
|
||
<ul className="detailoperate">
|
||
<li><a className="color-blue" onClick={()=>setEdit(true)}><i className="iconfont icon-a-bianji12 font-12 mr5"></i>编辑</a></li>
|
||
<li><Link to={`/${owner}/${projectsId}/issues/${index}/copy`} className="color-blue ml20"><i className="iconfont icon-a-fuzhi2 font-12 mr5"></i>复制</Link></li>
|
||
<li><a className="color-red ml20" onClick={()=>setDelVisible(true)}><i className="iconfont icon-fuzhi-shanchu font-12 mr5"></i>删除</a></li>
|
||
</ul>
|
||
}
|
||
</div>
|
||
<div class="descPanel">
|
||
{details.description ?
|
||
<RenderHtml className="break_word_comments imageLayerParent" value={details.description} url={props.history.location} />
|
||
:
|
||
<span className="color-grey-9 ml3 mr3">暂无描述</span>
|
||
}
|
||
{details.attachments && details.attachments.length > 0 ?
|
||
<Attachments
|
||
attachments={details.attachments}
|
||
showNotification={props.showNotification}
|
||
/>
|
||
: ""
|
||
}
|
||
</div>
|
||
</React.Fragment>
|
||
}
|
||
|
||
{/* <div className="pt20 pb30">
|
||
<Add />
|
||
</div> */}
|
||
</LongWidth>
|
||
<div className="shortwidth mt25">
|
||
<EditMenus name="负责人" names={names && names.assigner_name} imgFlag onChange={(ids,name)=>{saveForeach(ids);let copyname = { ...names,assigner_name:name};setNames(copyname);setCharegeId(ids);}} list={chargeList} value={charegeId} searchFlag searchFunc={(value)=>{setCharge(value)}} double={5} editFlag={details && !details.user_permission}/>
|
||
<EditMenus name="状态" names={names && names.status_name} onChange={(ids,name)=>{setStatusId(ids);saveForeach(undefined,ids);let copyname = { ...names,status_name:name};setNames(copyname);}} list={statusList} value={statusId} editFlag={details && !details.user_permission}/>
|
||
<EditMenus name="优先级" names={names && names.issue_priorities_name} onChange={(ids,name)=>{setPrioritiesId(ids);saveForeach(undefined,undefined,ids);let copyname = { ...names,issue_priorities_name:name};setNames(copyname);}} list={prioritiesList} value={prioritiesId} editFlag={details && !details.user_permission}/>
|
||
<EditMenus name="标记" names={names && names.issue_tag_name} onChange={(ids,name)=>{setTagId(ids);saveForeach(undefined,undefined,undefined,ids);let copyname = { ...names,issue_tag_name:name};setNames(copyname);}} list={tagList} value={tagId} onAdd={()=>setVisible(true)} searchFlag double={3} searchFunc={(value)=>setTag(value)} editFlag={details && !details.user_permission}/>
|
||
<EditMenus name="里程碑" names={names && names.milestone_name} emptyName="未关联" onChange={(ids,name)=>{setMillstoneId(ids);saveForeach(undefined,undefined,undefined,undefined,ids);let copyname = { ...names,milestone_name:name};setNames(copyname);}} value={millstoneId} list={millstoneList} searchFlag searchFunc={(value)=>setMillstone(value)} editFlag={details && !details.user_permission}/>
|
||
<EditMenus name="关联分支" names={branchId} emptyName="未关联" onChange={(ids)=>{setBranchId(ids);saveForeach(undefined,undefined,undefined,undefined,undefined,ids);}} value={branchId} list={branchList} searchFlag searchFunc={(value)=>setBranch(value)} editFlag={details && !details.user_permission}/>
|
||
<Date name="开始日期" today={start_date} setDate={(date)=>{setStartDate(date);saveForeach(undefined,undefined,undefined,undefined,undefined,undefined,date)}} editFlag={details && !details.user_permission}/>
|
||
<Date name="结束日期" today={due_date} setDate={(date)=>{setDueDate(date);saveForeach(undefined,undefined,undefined,undefined,undefined,undefined,undefined,date)}} editFlag={details && !details.user_permission}/>
|
||
</div>
|
||
</Box>
|
||
:
|
||
<div style={{width:"100%",display:"flex",alignItems:"center",justifyContent:'center',height:"400px"}}><Spin /></div>
|
||
)
|
||
}
|
||
export default Form.create()(forwardRef(Details)); |