save-jiekou
This commit is contained in:
parent
834cbaea6c
commit
232f3e7dca
|
|
@ -1,13 +1,20 @@
|
|||
import React , { useState } from 'react';
|
||||
import { Form , Modal , Input, Button } from 'antd';
|
||||
import ColorCard from './colorCard';
|
||||
import axios from 'axios';
|
||||
|
||||
function AddTagsBox({visible,onCancel,onSuccess , form}){
|
||||
function AddTagsBox({visible,onCancel, onSuccess , form ,owner , projectsId}){
|
||||
const { getFieldDecorator , getFieldsValue } = form;
|
||||
const [ colors , setColors ] = useState(undefined);
|
||||
|
||||
function saveFunc(){
|
||||
|
||||
const { desc , name } = getFieldsValue();
|
||||
const url = `/v1/${owner}/${projectsId}/issue_tags`;
|
||||
axios.post(url,{
|
||||
name,description:desc,color:colors ? colors.hex:"#F17013"
|
||||
}).then(result=>{
|
||||
result && onSuccess();
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function getColor(colors){
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
import React,{ useState , useEffect , forwardRef ,useImperativeHandle , useRef } from 'react';
|
||||
import Menus from './menus';
|
||||
import axios from 'axios';
|
||||
|
||||
const array =[
|
||||
{id:1,name:"最新创建"},
|
||||
{id:2,name:"最早创建"},
|
||||
{id:3,name:"最新更新"},
|
||||
{id:4,name:"最早更新"}
|
||||
]
|
||||
|
||||
function AllMenus({owner,projectsId,chooseFunc,update},ref){
|
||||
// 列表右侧所有筛选项的值
|
||||
const [ authorList , setAuthorList ] = useState(undefined);
|
||||
const [ author , setAuthor ] = useState(undefined);
|
||||
const [ tagList , setTagList ] = useState(undefined);
|
||||
const [ tag , setTag ] = useState(undefined);
|
||||
const [ millstoneList , setMillstoneList ] = useState(undefined);
|
||||
const [ millstone , setMillstone ] = useState(undefined);
|
||||
const [ chargeList , setChargeList ] = useState(undefined);
|
||||
const [ charge , setCharge ] = useState(undefined);
|
||||
const [ statusList , setStatusList ] = useState(undefined);
|
||||
const [ prioritiesList , setPrioritiesList ] = useState(undefined);
|
||||
const [ ids , setIds ] = useState({author_id:undefined,issue_priorities_id:undefined,issue_tag_ids:undefined,milestone_id:undefined,sort_by:undefined,status_id:undefined,assigner_id:undefined});
|
||||
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});
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
clearChoose: () => {
|
||||
// 父组件按钮:清除筛选条件,将Ids\names里的字段全部改为undefined
|
||||
setIds({author_id:undefined,issue_tag_ids:undefined,issue_priorities_id:undefined,milestone_id:undefined,sort_by:undefined,status_id:undefined,assigner_id:undefined});
|
||||
setNames({author_name:undefined,issue_tag_name:undefined,issue_priorities_name:undefined,milestone_name:undefined,sortby_name:undefined,status_name:undefined,assigner_name:undefined});
|
||||
}
|
||||
}))
|
||||
// 获取发布人列表
|
||||
useEffect(()=>{
|
||||
getSendPerson();
|
||||
},[author])
|
||||
|
||||
function getSendPerson(){
|
||||
const url = `/v1/${owner}/${projectsId}/issue_authors`;
|
||||
axios.get(url,{params:{keyword:author,only_name:true}}).then(result=>{
|
||||
if(result && result.data){
|
||||
setAuthorList(result.data.authors);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 获取标记列表
|
||||
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(()=>{
|
||||
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(()=>{
|
||||
getCharge();
|
||||
},[charge])
|
||||
|
||||
function getCharge(){
|
||||
const url = `/v1/${owner}/${projectsId}/issue_assigners`;
|
||||
axios.get(url,{params:{keyword:charge,only_name:true}}).then(result=>{
|
||||
if(result && result.data){
|
||||
setChargeList(result.data.assigners);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 获取优先级列表
|
||||
useEffect(()=>{
|
||||
getPriorities();
|
||||
},[])
|
||||
|
||||
function getPriorities(){
|
||||
const url = `/v1/${owner}/${projectsId}/issue_priorities`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setPrioritiesList(result.data.priorities);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 获取状态列表
|
||||
useEffect(()=>{
|
||||
getStatus();
|
||||
},[])
|
||||
|
||||
function getStatus(){
|
||||
const url = `/v1/${owner}/${projectsId}/issue_statues`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
setStatusList(result.data.statues);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function choose(id,name){
|
||||
let copy = {...ids,author_id:id};
|
||||
let copyname = { ...names,author_name:name}
|
||||
setIds(copy);setNames(copyname);
|
||||
chooseFunc(copy);
|
||||
}
|
||||
|
||||
return(
|
||||
<ul className="dropboxul">
|
||||
{ !update && <Menus
|
||||
update={update}
|
||||
id={ids && ids.author_id}
|
||||
name={(names && names.author_name) || "发布人" } size={"large"} imgControl
|
||||
lists={authorList} searchFunc={(value)=>setAuthor(value)}
|
||||
chooseFunc={(id,name)=>choose(id,name,'author_name')}
|
||||
/>
|
||||
}
|
||||
{update && <Menus
|
||||
update={update}
|
||||
id={ids && ids.issue_priorities_id}
|
||||
name={(names && names.issue_priorities_name) || "优先级" } size={"small"}
|
||||
lists={prioritiesList}
|
||||
chooseFunc={(id,name)=>{let copy = {...ids,issue_priorities_id:id};let copyname = { ...names,issue_priorities_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
|
||||
/>
|
||||
}
|
||||
<Menus
|
||||
update={update}
|
||||
id={ids && ids.issue_tag_ids}
|
||||
name={(names && names.issue_tag_name) || "标记" } size={"large"}
|
||||
lists={tagList} searchFunc={(value)=>setTag(value)}
|
||||
chooseFunc={(id,name)=>{let copy = {...ids,issue_tag_ids:id};let copyname = { ...names,issue_tag_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
|
||||
/>
|
||||
<Menus
|
||||
update={update}
|
||||
id={ids && ids.milestone_id}
|
||||
name={(names && names.milestone_name) || "里程碑" } size={"large"}
|
||||
lists={millstoneList} searchFunc={(value)=>setMillstone(value)}
|
||||
chooseFunc={(id,name)=>{let copy = {...ids,milestone_id:id};let copyname = { ...names,milestone_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
|
||||
/>
|
||||
<Menus
|
||||
update={update}
|
||||
id={ids && ids.assigner_id}
|
||||
name={(names && names.assigner_name) || "负责人" } size={"large"} imgControl
|
||||
lists={chargeList} searchFunc={(value)=>setCharge(value)}
|
||||
chooseFunc={(id,name)=>{let copy = {...ids,assigner_id:id};let copyname = { ...names,assigner_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
|
||||
/>
|
||||
<Menus
|
||||
update={update}
|
||||
id={ids && ids.status_id}
|
||||
name={(names && names.status_name) || "状态" } size={"small"}
|
||||
lists={statusList}
|
||||
chooseFunc={(id,name)=>{let copy = {...ids,status_id:id};let copyname = { ...names,status_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
|
||||
/>
|
||||
{ !update && <Menus
|
||||
id={ids && ids.sort_by}
|
||||
name={(names && names.sortby_name) ||"排序"} size={"small"}
|
||||
lists={array}
|
||||
chooseFunc={(id,name)=>{let copy = {...ids,sort_by:id};let copyname = { ...names,sortby_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
|
||||
/>
|
||||
}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
export default forwardRef(AllMenus);
|
||||
|
|
@ -6,39 +6,67 @@ import { Link } from "react-router-dom";
|
|||
|
||||
// issue列表显示
|
||||
function Datas({checkbox ,item , projectsId,owner}){
|
||||
|
||||
function statusTag(name){
|
||||
switch (name) {
|
||||
case "低":
|
||||
return "status low";
|
||||
case "正常":
|
||||
return "status normal";
|
||||
case "高":
|
||||
return "status hight";
|
||||
default:
|
||||
return "status urgent";
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="listdatas">
|
||||
<div>
|
||||
<div className="issuedetail">
|
||||
{checkbox}
|
||||
<div className="ilog">
|
||||
<span className="status normal">{item.priority_name}</span>
|
||||
<span className={statusTag(item.priority_name)}>{item.priority_name}</span>
|
||||
{item.project_issues_index && <span className="number"><Tooltip title="点击复制链接" placement="bottom">#{item.project_issues_index}</Tooltip></span>}
|
||||
</div>
|
||||
<div style={{marginTop:"-2px"}}>
|
||||
<div className="idetails mt2">
|
||||
<img src={issue} alt="" width="16px" className="mr5" />
|
||||
<Link to={`/${owner}/${projectsId}/issues/${item.project_issues_index}`}>{item.subject}</Link>
|
||||
<span style={{color: "#ee955a"}} className="ml5"><i className="iconfont icon-biaoji mr3 font-12"></i>invalid</span>
|
||||
{
|
||||
item.tags && item.tags.length>0?
|
||||
item.tags.map((i,k)=>{
|
||||
return(
|
||||
<span style={{color: i.color}} className="ml8"><i className="iconfont icon-biaoji font-12"></i>{i.name}</span>
|
||||
)
|
||||
})
|
||||
:""
|
||||
}
|
||||
</div>
|
||||
<div className="infos">
|
||||
<img src={`${getImageUrl(item.author && item.author.image_url)}`} alt="" />
|
||||
<span className="mr20">{item.author && item.author.name}</span>
|
||||
<Link to={`/${item.author && item.author.login}`}><img src={`${getImageUrl(item.author && item.author.image_url)}`} alt="" /></Link>
|
||||
<span className="mr20"><Link to={`/${item.author && item.author.login}`}>{item.author && item.author.name}</Link></span>
|
||||
<span className="mr25">{item.created_at} 发布</span>
|
||||
<span className="mr50">{item.updated_at}更新</span>
|
||||
{item.milestone_name && <span><i className="iconfont icon-lichengbeiicon1 font-12 mr2"></i>{item.milestone_name}</span> }
|
||||
{item.milestone_name && <span><i className="iconfont icon-lichengbeiicon1 font-12 mr3"></i>{item.milestone_name}</span> }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="issuecondition">
|
||||
<div className="principal">
|
||||
<img style={{right:`${5*(20-7)}px`,zIndex:1}} src={"https://testforgeplus.trustie.net/images/avatars/User/36480?t=1672730523"} alt="" />
|
||||
<img style={{right:`${4*(20-7)}px`,zIndex:2}} src={"https://testforgeplus.trustie.net/images/avatars/User/36480?t=1672730523"} alt="" />
|
||||
<img style={{right:`${3*(20-7)}px`,zIndex:3}} src={"https://testforgeplus.trustie.net/images/avatars/User/36480?t=1672730523"} alt="" />
|
||||
<img style={{right:`${2*(20-7)}px`,zIndex:4}} src={"https://testforgeplus.trustie.net/images/avatars/User/36480?t=1672730523"} alt="" />
|
||||
<img style={{right:`${20-7}px`,zIndex:5}} src={"https://testforgeplus.trustie.net/images/avatars/User/36480?t=1672730523"} alt="" />
|
||||
<span>...</span>
|
||||
</div>
|
||||
{
|
||||
item.assigners && item.assigners.length > 0 ?
|
||||
<div className="principal">
|
||||
{
|
||||
item.assigners.map((i,k)=>{
|
||||
return(
|
||||
k<5 && <Link to={`/${i.login}`} style={{right:`${(item.assigners.length-k-1)*(20-7)}px`,zIndex:k+1}}><img src={getImageUrl(i.image_url)} alt="" /></Link>
|
||||
)
|
||||
})
|
||||
}
|
||||
{/* <span>...</span> */}
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
<div>{item.status_name}</div>
|
||||
<div className="commentnum"><i className="iconfont icon-a-xiaoxi1 mr5 font-15"></i>{item.comment_journals_count}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,140 @@
|
|||
import React,{useRef,useEffect, useState , forwardRef } from 'react';
|
||||
import { Dropdown , Calendar , Select, Radio, Col, Row } from 'antd';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import moment from 'moment';
|
||||
const { Group , Button } = Radio;
|
||||
|
||||
function Date({name , today , setDate},ref){
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ time , setTime ] = useState();
|
||||
|
||||
useEffect(()=>{
|
||||
if(today){
|
||||
setTime(today);
|
||||
}
|
||||
},[today])
|
||||
|
||||
const refFa = useRef(null);
|
||||
const refBox = useRef(null);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('click', clickMe , false);
|
||||
}, [])
|
||||
|
||||
const clickMe = ({ target }) => {
|
||||
// 查找父组件
|
||||
const faComponent = findDOMNode(refFa.current);
|
||||
const boxComponent = findDOMNode(refBox.current);
|
||||
if (faComponent && boxComponent) {
|
||||
const isChild = faComponent.contains(target);
|
||||
const isBox = boxComponent.contains(target);
|
||||
if(!isChild && !isBox){
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
function onSelect(t){
|
||||
setTime(moment(t).format('YYYY-MM-DD'));
|
||||
setDate(moment(t).format('YYYY-MM-DD'));
|
||||
setVisible(false);
|
||||
}
|
||||
const overlay=(
|
||||
<div ref={refFa} style={{ width: 280, border: '1px solid #d9d9d9', borderRadius: 4 ,backgroundColor:"#fff",marginTop:"-10px"}}>
|
||||
<Calendar
|
||||
fullscreen={false}
|
||||
headerRender={({ value, type, onChange, onTypeChange }) => {
|
||||
const start = 0;
|
||||
const end = 12;
|
||||
const monthOptions = [];
|
||||
const current = value.clone();
|
||||
const localeData = value.localeData();
|
||||
const months = [];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
current.month(i);
|
||||
months.push(localeData.monthsShort(current));
|
||||
}
|
||||
|
||||
for (let index = start; index < end; index++) {
|
||||
monthOptions.push(
|
||||
<Select.Option className="month-item" key={`${index}`}>
|
||||
{months[index]}
|
||||
</Select.Option>,
|
||||
);
|
||||
}
|
||||
const month = value.month();
|
||||
|
||||
const year = value.year();
|
||||
const options = [];
|
||||
for (let i = year - 10; i < year + 10; i += 1) {
|
||||
options.push(
|
||||
<Select.Option key={i} value={i} className="year-item">
|
||||
{i}
|
||||
</Select.Option>,
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div style={{ padding: 10 }}>
|
||||
|
||||
<Row type="flex" justify="space-between">
|
||||
<Col>
|
||||
<Group size="small" onChange={e => onTypeChange(e.target.value)} value={type}>
|
||||
<Button value="month">日期</Button>
|
||||
<Button value="year">月份</Button>
|
||||
</Group>
|
||||
</Col>
|
||||
<Col>
|
||||
<Select
|
||||
size="small"
|
||||
dropdownMatchSelectWidth={false}
|
||||
className="my-year-select"
|
||||
style={{ width: 80 }}
|
||||
onChange={newYear => {
|
||||
const now = value.clone().year(newYear);
|
||||
onChange(now);
|
||||
}}
|
||||
value={String(year)}
|
||||
>
|
||||
{options}
|
||||
</Select>
|
||||
</Col>
|
||||
<Col>
|
||||
<Select
|
||||
size="small"
|
||||
dropdownMatchSelectWidth={false}
|
||||
value={String(month)}
|
||||
onChange={selectedMonth => {
|
||||
const newValue = value.clone();
|
||||
newValue.month(parseInt(selectedMonth, 10));
|
||||
onChange(newValue);
|
||||
}}
|
||||
>
|
||||
{monthOptions}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
return(
|
||||
<Dropdown
|
||||
placement={"bottomLeft"}
|
||||
overlay={overlay}
|
||||
visible={visible}
|
||||
trigger={['click']}
|
||||
>
|
||||
<li>
|
||||
<span>
|
||||
{name}
|
||||
<a ref={refBox} onClick={()=>setVisible(visible ? false : true)}><i className="iconfont icon-riqi font-14" style={{color:"#898d9d"}}></i></a>
|
||||
</span>
|
||||
<p className={time ? "operatevalue color-grey-3 task-hide" : "operatevalue task-hide"}>{time || "未设置"}</p>
|
||||
</li>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
export default forwardRef(Date);
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
import React,{useState, useEffect, useRef, useImperativeHandle,forwardRef} from 'react';
|
||||
import { Dropdown ,Icon } from 'antd';
|
||||
import { Dropdown } from 'antd';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
|
||||
function Drop({overlay,value},ref){
|
||||
function Drop({overlay , children , placement, overlayClassName},ref){
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const refFa = useRef(null);
|
||||
const refBox = useRef(null);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
clearVisible: (value) => {
|
||||
clearVisible: (v) => {
|
||||
// 父组件按钮:清除筛选条件,将dropmenu里的choose字段全部改为0
|
||||
setVisible(value);
|
||||
setVisible(v);
|
||||
}
|
||||
}))
|
||||
|
||||
|
|
@ -32,14 +32,14 @@ function Drop({overlay,value},ref){
|
|||
}
|
||||
return(
|
||||
<Dropdown
|
||||
placement={"bottomRight"}
|
||||
placement={placement}
|
||||
visible={visible}
|
||||
overlay={<div ref={refFa}>{overlay}</div>}
|
||||
trigger={['click']}
|
||||
overlayClassName={overlayClassName}
|
||||
>
|
||||
<li ref={refBox} onClick={()=>setVisible(visible ? false : true)}>
|
||||
<span className="task-hide">{value}</span>
|
||||
<Icon type="caret-down" className="ml5 color-grey-6" />
|
||||
{children}
|
||||
</li>
|
||||
</Dropdown>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
import React ,{ useState , useEffect , useRef } from 'react';
|
||||
import { Dropdown , Menu , Input } from 'antd';
|
||||
import { Dropdown , Menu , Input, message } from 'antd';
|
||||
import { findDOMNode } from 'react-dom';
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
const { Search } = Input;
|
||||
|
||||
function EditMenus({name,list,value , onAdd , searchFlag}){
|
||||
// name:显示的标题
|
||||
// list[]:选项
|
||||
// value[]:显示的值
|
||||
// onAdd:标记管理、只针对标记
|
||||
// searchFlag:是否显示搜索输入框
|
||||
// editFlag:是否有编辑按钮
|
||||
// double:可多选
|
||||
// onChange:选择项后返回id数组
|
||||
function EditMenus({ name , emptyName='未设置',list,value , onAdd , searchFlag , editFlag , searchFunc ,double , onChange , imgFlag}){
|
||||
const [ menus , setMenus ] = useState([]);
|
||||
const [ searchValue , setSearchValue ]= useState(undefined);
|
||||
const [ showValue , setShowValue ] = useState(undefined);
|
||||
const [ valueId , setValueId ] = useState([]);
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
|
||||
const refFa = useRef(null);
|
||||
|
|
@ -15,7 +25,14 @@ function EditMenus({name,list,value , onAdd , searchFlag}){
|
|||
|
||||
useEffect(()=>{
|
||||
setMenus(list);
|
||||
setShowValue(value);
|
||||
if(value && value.length>0 && list && list.length>0){
|
||||
let n = value.map(item=>{
|
||||
let n = list.filter(j=>j.id.toString() === item);
|
||||
return n.length>0 && n[0].name;
|
||||
});
|
||||
setValueId(value);
|
||||
setShowValue(n.join(","));
|
||||
}
|
||||
},[list,value])
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -35,48 +52,106 @@ function EditMenus({name,list,value , onAdd , searchFlag}){
|
|||
}
|
||||
}
|
||||
|
||||
function chooseMenu(e){
|
||||
function chooseMenu(i){
|
||||
setVisible(false);
|
||||
setShowValue(e.item.props.children)
|
||||
let l = valueId;
|
||||
let idStr = i && i.id ? i.id.toString() :i.name;
|
||||
// 分支列表没有id,只能根据name判断
|
||||
if(double){
|
||||
if(l.indexOf(idStr)>=0){
|
||||
l = l.filter(k=>k.toString() !== idStr);
|
||||
}else{
|
||||
if(valueId.length > double){
|
||||
message.info(`最多只能添加${double}个${name}`);
|
||||
return;
|
||||
}
|
||||
l.push(idStr);
|
||||
}
|
||||
setValueId(l);
|
||||
console.log(l);
|
||||
let nameList = i && i.id ? getByid(l) : getByName(l);
|
||||
setShowValue(nameList.length >0 ? nameList.join(",") : undefined);
|
||||
onChange(l);
|
||||
}else{
|
||||
if(l.indexOf(idStr)>=0){
|
||||
setValueId([]);
|
||||
onChange([]);
|
||||
setShowValue(undefined);
|
||||
}else{
|
||||
setValueId([`${i.id || i.name}`]);
|
||||
onChange([`${i.id || i.name}`]);
|
||||
setShowValue(i.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getByid(l){
|
||||
return l.length>0 ? l.map(item=>{
|
||||
let n = list.filter(j=>j.id.toString() === item);
|
||||
return n.length>0 && n[0].name;
|
||||
}) :"";
|
||||
}
|
||||
function getByName(l){
|
||||
return l.length>0 ? l.map(item=>{
|
||||
let n = list.filter(j=>j.name === item);
|
||||
return n.length>0 && n[0].name;
|
||||
}) :"";
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function changeSearchvalue(e){
|
||||
setSearchValue(e.target.value);
|
||||
searchFunc(e.target.value);
|
||||
}
|
||||
|
||||
|
||||
return(
|
||||
<li>
|
||||
<span>{name}<a><i className="iconfont icon-a-bianji12 font-13" style={{color:"#898d9d"}}></i></a></span>
|
||||
<Dropdown visible={visible} overlayClassName={"overlayStyle"} placement="bottomLeft" trigger={['click']}
|
||||
<span>
|
||||
{name}
|
||||
{!editFlag && <a ref={refBox} onClick={()=>setVisible(visible ? false : true)}><i className="iconfont icon-a-bianji12 font-13" style={{color:"#898d9d"}}></i></a>}
|
||||
</span>
|
||||
<Dropdown
|
||||
visible={visible}
|
||||
overlayClassName={"overlayStyle"}
|
||||
placement="bottomLeft"
|
||||
trigger={['click']}
|
||||
overlay={
|
||||
<div className="branch-tagBox" ref={refFa}>
|
||||
{ searchFlag &&
|
||||
<div className="searchbox">
|
||||
<Search placeholder={`搜索${name}`} value={searchValue} onChange={changeSearchvalue} style={{marginRight:"18px"}}/>
|
||||
<Search
|
||||
placeholder={`搜索${name}`}
|
||||
value={searchValue}
|
||||
onChange={changeSearchvalue}
|
||||
style={{marginRight:"18px"}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
menus && menus.length >0?
|
||||
<Menu>
|
||||
<Menu className="piecemenu" selectedKeys={valueId}>
|
||||
{
|
||||
menus.map((i,k)=>{
|
||||
return(
|
||||
<Menu.Item key={i.id} onClick={chooseMenu}>{i.name}</Menu.Item>
|
||||
<Menu.Item key={i.id || i.name} onClick={()=>chooseMenu(i)}>
|
||||
{ imgFlag && <img src={getImageUrl(i.image_url)} alt="" width="22px" className="mr5 radius"/>}
|
||||
{i.color && <span style={{backgroundColor:i.color}} className="colorpiece"></span>}
|
||||
{i.name}
|
||||
</Menu.Item>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Menu>
|
||||
:
|
||||
<div className="menusEmpty">
|
||||
<p>{searchValue ? <span>创建新{showValue}“{searchValue}”</span>: `暂无${name}`}</p>
|
||||
<p>{searchValue ? <span>暂无{name}“{searchValue}”</span>: `暂无${name}`}</p>
|
||||
{ name === "标记" && <a className="color-blue font-15" onClick={()=>{setVisible(false);onAdd()}}><i className="iconfont icon-a-bianji12 font-14 mr5"></i>标记管理</a>}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}>
|
||||
<p ref={refBox} onClick={()=>setVisible(visible ? false : true)} className={showValue?"operatevalue color-grey-3":"operatevalue"}>{showValue || "未设置"}</p>
|
||||
<p className={showValue?"operatevalue color-grey-3 task-hide":"operatevalue task-hide"}>{showValue || emptyName}</p>
|
||||
</Dropdown>
|
||||
</li>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,178 +1,54 @@
|
|||
import React ,{ useImperativeHandle ,forwardRef , useState , useEffect , useRef } from 'react';
|
||||
import { Input , Menu } from 'antd';
|
||||
import React ,{ useState , useRef } from 'react';
|
||||
import { Input , Menu , Icon } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import Drop from './drop';
|
||||
import axios from 'axios';
|
||||
const { Search } = Input;
|
||||
|
||||
// id:固定位置顺序的唯一
|
||||
// name:未选择时显示的内容
|
||||
// updateName:勾选列表后默认显示的内容
|
||||
// choose:选择的项的id
|
||||
// menu:下拉列表,从接口获取,需一一填充
|
||||
// lists:下拉列表,从接口获取,需一一填充
|
||||
// imgControl:控制是否显示头像
|
||||
// size:下拉框宽度,small:120px,large:260px;
|
||||
const menus=[
|
||||
{
|
||||
id:1,
|
||||
name:"发布人",
|
||||
choose:0,
|
||||
imgControl:true,
|
||||
size:"large",
|
||||
menu:[{id:1,name:"111",image_url:'https://testforgeplus.trustie.net/images/avatars/User/36480?t=1672730523'},{id:2,name:"222",image_url:''},{id:3,name:"333",image_url:''},{id:4,name:"4444",image_url:''}]
|
||||
},
|
||||
{
|
||||
id:7,
|
||||
updateName:"更换优先级",
|
||||
choose:0,
|
||||
menu:[{id:1,name:"紧急"},{id:2,name:"正常"},{id:3,name:"低"},{id:4,name:"高"}]
|
||||
},
|
||||
{
|
||||
id:2,
|
||||
name:"标记",
|
||||
updateName:"更换标记",
|
||||
choose:0,
|
||||
size:"large",
|
||||
menu:[{id:1,name:"red"},{id:2,name:"blue"},{id:3,name:"orange"},{id:4,name:"yellow"}]
|
||||
},
|
||||
{
|
||||
id:3,
|
||||
name:"里程碑",
|
||||
updateName:"更换里程碑",
|
||||
choose:0,
|
||||
size:"large",
|
||||
menu:[{id:1,name:"11-11"},{id:2,name:"22-22"},{id:3,name:"33-33"},{id:4,name:"44-44"}]
|
||||
},
|
||||
{
|
||||
id:4,
|
||||
name:"负责人",
|
||||
updateName:"更换负责人",
|
||||
choose:0,
|
||||
size:"large",
|
||||
menu:[{id:1,name:"you",img:''},{id:2,name:"she",img:''},{id:3,name:"he",img:''},{id:4,name:"they",img:''}]
|
||||
},
|
||||
{
|
||||
id:5,
|
||||
name:"状态",
|
||||
updateName:"更换状态",
|
||||
choose:0,
|
||||
size:"small",
|
||||
menu:[{id:1,name:"新增"},{id:2,name:"正在解决"},{id:3,name:"已解决"},{id:4,name:"反馈"},{id:5,name:"关闭"},{id:6,name:"拒绝"}]
|
||||
},
|
||||
{
|
||||
id:6,
|
||||
name:"排序",
|
||||
choose:0,
|
||||
size:"small",
|
||||
menu:[{id:1,name:"最新创建"},{id:2,name:"最早创建"},{id:3,name:"最近更新"},{id:4,name:"最早更新"},{id:5,name:"高优先级"},{id:6,name:"低优先级"}]
|
||||
}
|
||||
]
|
||||
function Menus({update,owner,projectsId},ref){
|
||||
const [ dropmenu , setDropMenu ] = useState(menus);
|
||||
|
||||
|
||||
// chooseValue: 默认选择的项的id
|
||||
// search: 搜索方法
|
||||
// chooseFunc: 选择项后需调用列表的查询方法
|
||||
// update: 编辑状态
|
||||
function Menus({name, id , lists , size , imgControl , searchFunc , chooseFunc , update },ref){
|
||||
const dropRef = useRef(null);
|
||||
|
||||
useEffect(()=>{
|
||||
getSendPerson();
|
||||
getSign();
|
||||
},[])
|
||||
|
||||
// 获取发布人
|
||||
function getSendPerson(){
|
||||
const url = `/v1/${owner}/${projectsId}/issue_authors`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
MenusControl(1,result.data.authors);
|
||||
}
|
||||
})
|
||||
}
|
||||
// 获取标记
|
||||
function getSign(){
|
||||
const url = `/v1/${owner}/${projectsId}/issue_tags`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data){
|
||||
MenusControl(2,result.data.issue_tags);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function MenusControl(num,data){
|
||||
let list = [...dropmenu];
|
||||
let todolist = [];
|
||||
todolist = list.map((i,k)=>i.id === num ? {...i,menu:data} : i);
|
||||
setDropMenu(todolist);
|
||||
}
|
||||
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
clearChoose: () => {
|
||||
// 父组件按钮:清除筛选条件,将dropmenu里的choose字段全部改为0
|
||||
changeMenusValue(0);
|
||||
}
|
||||
}))
|
||||
|
||||
useEffect(()=>{
|
||||
if(update){
|
||||
|
||||
}
|
||||
},[update])
|
||||
|
||||
|
||||
// 修改menus数组里的字段值
|
||||
function changeMenusValue(value,id){
|
||||
let todoList = [...dropmenu];
|
||||
let list = [];
|
||||
if(id){
|
||||
list = todoList.map((i,k)=>id===i.id ? {...i,choose:value} : i);
|
||||
}else{
|
||||
list = todoList.map((i,k)=>id ? i : {...i,choose:value});
|
||||
}
|
||||
setDropMenu(list);
|
||||
chooseFunc(id,value);
|
||||
dropRef.current && dropRef.current.clearVisible(false);
|
||||
// 修改后调用父组件方法重新查询数据
|
||||
|
||||
}
|
||||
|
||||
function menu(item){
|
||||
if(item.menu && item.menu.length>0){
|
||||
return <div className={`overlaydrop ${item.size}`}>
|
||||
{ item.size !== "small" &&
|
||||
<div className="pb10"><Search placeholder={`搜索${item.name}`} /></div>
|
||||
}
|
||||
<Menu selectedKeys={[`${item.choose}`]}>
|
||||
{
|
||||
item.menu.map((i,j)=>{
|
||||
return <Menu.Item key={i.id}>
|
||||
{item.imgControl && <img src={getImageUrl(i.image_url)} alt=""/>}
|
||||
<span onClick={()=>changeMenusValue(i.id,item.id)}>{i.name}</span>
|
||||
</Menu.Item>
|
||||
})
|
||||
}
|
||||
</Menu>
|
||||
</div>
|
||||
function menu(data){
|
||||
return <div className={`overlaydrop ${size}`}>
|
||||
{ size !== "small" &&
|
||||
<div className="pb10"><Search placeholder={`搜索${name}`} allowClear onChange={(e)=>searchFunc(e.target.value)}/></div>
|
||||
}
|
||||
else{
|
||||
return "";
|
||||
}
|
||||
{
|
||||
data && data.length>0 ?
|
||||
<Menu selectedKeys={[`${id}`]}>
|
||||
{
|
||||
data.map((i,j)=>{
|
||||
return <Menu.Item key={i.id}>
|
||||
{imgControl && <img src={getImageUrl(i.image_url)} alt=""/>}
|
||||
<span onClick={()=>changeMenusValue(i.name,i.id)}>{i.name}</span>
|
||||
</Menu.Item>
|
||||
})
|
||||
}
|
||||
</Menu>
|
||||
:
|
||||
<div className="pl15">暂无{id ? <span>'{name}'</span>: name}</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
return(
|
||||
dropmenu && dropmenu.length >0 ?
|
||||
<ul className="dropboxul">
|
||||
{
|
||||
dropmenu.map((item,i)=>{
|
||||
let ichoose = item.choose !== 0 && item.menu.filter(k=>k.id === item.choose);
|
||||
return(
|
||||
((!update && item.name) || (update && item.updateName)) &&
|
||||
<Drop
|
||||
ref={dropRef}
|
||||
overlay={menu(item)}
|
||||
value={item.choose !== 0 ? (ichoose.length>0 && ichoose[0].name):(update ? item.updateName : item.name)}
|
||||
/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
:<div></div>
|
||||
<Drop ref={dropRef} overlay={menu(lists)} placement={"bottomRight"} >
|
||||
<span className="task-hide">{(update && !id) ? `更换${name}` : name }</span>
|
||||
<Icon type="caret-down" className="ml5 color-grey-6" />
|
||||
</Drop>
|
||||
)
|
||||
}
|
||||
export default forwardRef(Menus);
|
||||
export default Menus;
|
||||
|
|
@ -4,7 +4,7 @@ import bj from '../Img/biaoji.png';
|
|||
import issueEmp from '../Img/issue-big.png';
|
||||
import create from '../Img/create.png';
|
||||
import { Link } from "react-router-dom";
|
||||
import Menus from '../Component/menus';
|
||||
import AllMenus from '../Component/allMenus';
|
||||
import Datas from '../Component/datas';
|
||||
import DelBox from '../Component/delBox';
|
||||
import axios from 'axios';
|
||||
|
|
@ -27,8 +27,11 @@ function List(props){
|
|||
const [ allIds , setAllIds ] = useState([]);
|
||||
const [ checkAll , setCheckAll ] = useState(false);
|
||||
|
||||
const [ updateIds , setUpdateIds ] = useState([]);
|
||||
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(undefined);
|
||||
|
||||
const menuRef = useRef(null);
|
||||
const owner = props.match.params.owner;
|
||||
const projectsId = props.match.params.projectsId;
|
||||
|
|
@ -38,13 +41,16 @@ function List(props){
|
|||
Init();
|
||||
},[aboutMe,keyword,category])
|
||||
// 获取issue列表数据
|
||||
function Init(){
|
||||
function Init(params){
|
||||
setTotal(undefined);
|
||||
const url = `/v1/${owner}/${projectsId}/issues`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
participant_category:aboutMe,
|
||||
keyword,category
|
||||
keyword,category,
|
||||
...params,
|
||||
sort_direction:(params && params.sort_by) ? ((params.sort_by === 1 || params.sort_by === 3) ? "desc" : "asc") :undefined,
|
||||
sort_by:(params && params.sort_by) ? ((params.sort_by === 1 || params.sort_by === 2) ? "created_on" : "updated_on") : undefined
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
|
|
@ -77,8 +83,10 @@ function List(props){
|
|||
function clearCondition(){
|
||||
setKeyword(undefined);
|
||||
setAboutMe("aboutme");
|
||||
Init();
|
||||
// 清除下拉选项
|
||||
menuRef.current && menuRef.current.clearChoose();
|
||||
|
||||
}
|
||||
|
||||
// 全选所有issue
|
||||
|
|
@ -105,6 +113,25 @@ function List(props){
|
|||
function cancelUpdate(){
|
||||
setAllValue([]);
|
||||
setCheckAll(false);
|
||||
// 清除下拉选项
|
||||
menuRef.current && menuRef.current.clearChoose();
|
||||
}
|
||||
// 确认修改 allValue updateIds
|
||||
function sureUpdate(){
|
||||
const url = `/v1/${owner}/${projectsId}/issues/batch_update`;
|
||||
axios.patch(url,{
|
||||
assigner_ids: [updateIds && updateIds.assigner_id],
|
||||
ids: allValue,
|
||||
issue_tag_ids: [updateIds && updateIds.issue_tag_ids],
|
||||
milestone_id: updateIds && updateIds.milestone_id,
|
||||
priority_id: updateIds && updateIds.issue_priorities_id,
|
||||
status_id: updateIds && updateIds.status_id
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
Init();
|
||||
cancelUpdate();
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
// 切换页码
|
||||
|
|
@ -114,7 +141,25 @@ function List(props){
|
|||
|
||||
// 删除issue相关 func
|
||||
function onSuccess(){
|
||||
|
||||
const url = `/v1/${owner}/${projectsId}/issues/batch_destroy`;
|
||||
axios.delete(url,{
|
||||
params:{ids:allValue}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setVisible(false);
|
||||
props.showNotification("疑修删除成功!");
|
||||
Init();
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function chooseFunc(ids){
|
||||
if(allValue && allValue.length>0){
|
||||
// 将ids保存下来以便修改
|
||||
setUpdateIds(ids);
|
||||
}else{
|
||||
Init(ids);
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
|
|
@ -158,16 +203,17 @@ function List(props){
|
|||
}
|
||||
</div>
|
||||
<div className="menusul">
|
||||
<Menus
|
||||
<AllMenus
|
||||
ref={menuRef}
|
||||
update={allValue && allValue.length>0}
|
||||
owner={owner}
|
||||
projectsId={projectsId}
|
||||
update={allValue && allValue.length>0}
|
||||
chooseFunc={chooseFunc}
|
||||
/>
|
||||
{
|
||||
allValue && allValue.length>0 ?
|
||||
<div>
|
||||
<Button type="primary" ghost>确定</Button>
|
||||
<Button type="primary" ghost onClick={sureUpdate}>确定</Button>
|
||||
<Button type="danger" ghost className="ml10" onClick={()=>setVisible(true)}>删除</Button>
|
||||
<Button ghost className="ml10 mr10" onClick={cancelUpdate}>取消</Button>
|
||||
</div>
|
||||
|
|
@ -191,7 +237,7 @@ function List(props){
|
|||
issueList.map((item,key)=>{
|
||||
return(
|
||||
<Datas
|
||||
checkbox={ <Checkbox value={0} key={0} style={{marginRight: "16px"}}></Checkbox> }
|
||||
checkbox={ <Checkbox value={item.id} key={item.id} style={{marginRight: "16px"}}></Checkbox> }
|
||||
item={item}
|
||||
owner={owner}
|
||||
projectsId={projectsId}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React , { useEffect , useState } from 'react';
|
||||
import { Button, Input , Dropdown , Menu } from 'antd';
|
||||
import React , { useEffect , useState , forwardRef } from 'react';
|
||||
import { Button, Input , Form } from 'antd';
|
||||
import { Box , LongWidth } from '../../Component/layout';
|
||||
import MDEditor from "../../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import Upload from "../../Upload/Index";
|
||||
|
|
@ -7,18 +7,131 @@ import Attachments from "../../Upload/attachment";
|
|||
import UploadImg from '../Img/UploadImg.png';
|
||||
import EditMenus from '../Component/editMenus';
|
||||
import AddTagsBox from '../Component/addTagsBox';
|
||||
import Date from '../Component/date';
|
||||
import axios from 'axios';
|
||||
import moment from 'moment';
|
||||
|
||||
const menus = {
|
||||
milestones:[{id:1,name:"里程碑1"},{id:2,name:"里程碑22"}],
|
||||
issue_tags:[{id:1,name:"标记1"},{id:2,name:"标记22"}]
|
||||
}
|
||||
function New(props){
|
||||
const [ content , setContent ] = useState("");
|
||||
const [ description , setDescription ] = useState("");
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ fileList , setFileList] = useState(undefined);
|
||||
const [ attachments , setAttachments ] = useState([]);
|
||||
|
||||
|
||||
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 [ start_date, setStartDate ] = useState(moment().format('YYYY-MM-DD'));
|
||||
const [ due_date, setDueDate ] = useState("");
|
||||
|
||||
const [ receivers_login , setReceiversLogin ] = useState(undefined);
|
||||
|
||||
const owner = props.match.params.owner;
|
||||
const projectsId = props.match.params.projectsId;
|
||||
|
||||
const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props;
|
||||
|
||||
// 获取状态列表
|
||||
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){
|
||||
setPrioritiesList(result.data.priorities);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取负责人列表
|
||||
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 onContentChange(value){
|
||||
setContent(value);
|
||||
setDescription(value);
|
||||
}
|
||||
function UploadFunc(fileList){
|
||||
setFileList(fileList);
|
||||
|
|
@ -26,26 +139,72 @@ function New(props){
|
|||
|
||||
// 标记管理弹框
|
||||
function onSuccess(){
|
||||
|
||||
// 添加标记成功后需更新标记的数据数组
|
||||
|
||||
getSign();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
// 创建
|
||||
function createFunc(){
|
||||
validateFields((error,values)=>{
|
||||
if (!error) {
|
||||
const { subject } = values;
|
||||
const url = `/v1/${owner}/${projectsId}/issues`;
|
||||
axios.post(url,{
|
||||
description,subject,
|
||||
branch_name:branchId.join(","),
|
||||
status_id:statusId.join(","),
|
||||
priority_id:prioritiesId.join(","),
|
||||
milestone_id:millstoneId.join(","),
|
||||
issue_tag_ids:tagId,
|
||||
assigner_ids:charegeId,
|
||||
attachment_ids:fileList,
|
||||
start_date,due_date,receivers_login
|
||||
}).then(result=>{
|
||||
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 changeAtWhoLoginList(loginList){
|
||||
let list = new Set(receivers_login);
|
||||
loginList.map(item => list.add(item));
|
||||
setReceiversLogin(Array.from(list));
|
||||
};
|
||||
|
||||
|
||||
return(
|
||||
<div>
|
||||
<AddTagsBox visible={visible} onCancel={()=>setVisible(false)} onSuccess={onSuccess} />
|
||||
<AddTagsBox
|
||||
owner={owner}
|
||||
projectsId={projectsId}
|
||||
visible={visible}
|
||||
onCancel={()=>setVisible(false)} onSuccess={onSuccess}
|
||||
/>
|
||||
<p className="font-20 color-grey-3 mt20 mb15">新建疑修</p>
|
||||
<Box>
|
||||
<LongWidth>
|
||||
<Input placeholder="标题"/>
|
||||
<Form className="explain">
|
||||
<Form.Item>
|
||||
{getFieldDecorator("subject",{
|
||||
rules:[{required:true,message:"请输入疑修标题"}]
|
||||
})(
|
||||
<Input placeholder="标题" maxLength={100}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<MDEditor
|
||||
placeholder={"请输入描述信息"}
|
||||
height={392}
|
||||
mdID={"order-new-description"}
|
||||
initValue={content}
|
||||
initValue={description}
|
||||
onChange={onContentChange}
|
||||
className="mt20"
|
||||
changeAtWhoLoginList = {changeAtWhoLoginList}
|
||||
></MDEditor>
|
||||
<div className="pb20">
|
||||
<Upload
|
||||
|
|
@ -72,19 +231,22 @@ function New(props){
|
|||
}
|
||||
</div>
|
||||
<div style={{display:"flex"}}>
|
||||
<Button type="primary" className="operateButton" style={{width:"100px"}}>创建</Button>
|
||||
<Button type="primary" className="operateButton" style={{width:"100px"}} onClick={createFunc}>创建</Button>
|
||||
<Button className="ml30" style={{width:"100px"}}>取消</Button>
|
||||
</div>
|
||||
</LongWidth>
|
||||
<div className="shortwidth">
|
||||
<EditMenus name="负责人" list={menus.issue_tags} searchFlag/>
|
||||
<EditMenus name="状态" list={menus.issue_tags} searchFlag/>
|
||||
<EditMenus name="优先级" list={[]}/>
|
||||
<EditMenus name="标记" list={[]} onAdd={()=>setVisible(true)} searchFlag/>
|
||||
<EditMenus name="里程碑" list={menus.milestones} searchFlag/>
|
||||
<EditMenus name="负责人" imgFlag onChange={(ids)=>setCharegeId(ids)} list={chargeList} searchFlag searchFunc={(value)=>setCharge(value)} double={5}/>
|
||||
<EditMenus name="状态" onChange={(ids)=>setStatusId(ids)} list={statusList} editFlag value={statusId}/>
|
||||
<EditMenus name="优先级" onChange={(ids)=>setPrioritiesId(ids)} list={prioritiesList} value={prioritiesId}/>
|
||||
<EditMenus name="标记" onChange={(ids)=>setTagId(ids)} list={tagList} onAdd={()=>setVisible(true)} searchFlag double={3} searchFunc={(value)=>setTag(value)}/>
|
||||
<EditMenus name="里程碑" emptyName="未关联" onChange={(ids)=>setMillstoneId(ids)} list={millstoneList} searchFlag searchFunc={(value)=>setMillstone(value)}/>
|
||||
<EditMenus name="关联分支" emptyName="未关联" onChange={(ids)=>setBranchId(ids)} list={branchList} searchFlag searchFunc={(value)=>setBranch(value)}/>
|
||||
<Date name="开始日期" today={start_date} setDate={(date)=>setStartDate(date)}/>
|
||||
<Date name="结束日期" today={due_date} setDate={(date)=>setDueDate(date)}/>
|
||||
</div>
|
||||
</Box>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default New;
|
||||
export default Form.create()(forwardRef(New));
|
||||
|
|
@ -201,7 +201,7 @@
|
|||
align-items: center;
|
||||
color: #898d9d;
|
||||
margin-top: 12px;
|
||||
&>img{
|
||||
img{
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
margin-right: 4px;
|
||||
|
|
@ -214,14 +214,22 @@
|
|||
color: #40424a;
|
||||
.principal{
|
||||
position: relative;
|
||||
height: 30px;
|
||||
height: 20px;
|
||||
&:hover{
|
||||
a{
|
||||
position:initial;
|
||||
}
|
||||
}
|
||||
a{
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
transition: 0.6s;
|
||||
}
|
||||
img,span{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
bottom: 4px;
|
||||
}
|
||||
span{
|
||||
background-color:#ced5ef;
|
||||
|
|
@ -395,7 +403,6 @@
|
|||
line-height: 20px;
|
||||
color: #acb0bf;
|
||||
margin-top: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -445,15 +452,28 @@
|
|||
border-top: 1px solid rgba(172, 176, 191, 0.17);
|
||||
}
|
||||
}
|
||||
.piecemenu{
|
||||
li{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.colorpiece{
|
||||
display: block;
|
||||
width: 22px;
|
||||
height: 15px;
|
||||
margin-right: 9px;
|
||||
border-radius:2px;
|
||||
}
|
||||
.overlayStyle{
|
||||
background-color:#ffffff;
|
||||
border-radius:6px;
|
||||
box-shadow:0px 0px 10px rgba(24, 54, 181, 0.17);
|
||||
.searchbox{
|
||||
padding:18px 20px 0px 16px;
|
||||
padding:12px 20px 0px 16px;
|
||||
}
|
||||
.ant-menu{
|
||||
padding:0px 20px 10px 16px;
|
||||
padding:12px 16px 10px 16px;
|
||||
max-height: 338px;
|
||||
overflow-y: auto;
|
||||
li{
|
||||
|
|
@ -513,6 +533,12 @@
|
|||
align-items: center;
|
||||
}
|
||||
}
|
||||
// 新建页面
|
||||
.explain{
|
||||
.ant-form-explain{
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
// 评论相关
|
||||
.addcomments{
|
||||
|
|
|
|||
|
|
@ -70,10 +70,12 @@ class Index extends Component {
|
|||
|
||||
fileIdList = (fileList) => {
|
||||
let array = [];
|
||||
fileList && fileList.length > 0 && fileList.map((item) => {
|
||||
return array.push(item.response && (item.response.id || (item.response.data && item.response.data.id)));
|
||||
})
|
||||
array && this.props.load && this.props.load(array);
|
||||
if(fileList && fileList.length > 0){
|
||||
fileList.map((item) => {
|
||||
return item.response && item.status==="done" && array.push((item.response.id || (item.response.data && item.response.data.id)));
|
||||
})
|
||||
array && array.length>0 && this.props.load(array);
|
||||
}
|
||||
}
|
||||
|
||||
checkFile=(str)=>{
|
||||
|
|
|
|||
Loading…
Reference in New Issue