forgeplus-react/src/forge/Issues/Pages/details.jsx

391 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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));