diff --git a/src/forge/Issues/Component/addTagsBox.jsx b/src/forge/Issues/Component/addTagsBox.jsx
index 257f81977..65ca4e763 100644
--- a/src/forge/Issues/Component/addTagsBox.jsx
+++ b/src/forge/Issues/Component/addTagsBox.jsx
@@ -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){
diff --git a/src/forge/Issues/Component/allMenus.jsx b/src/forge/Issues/Component/allMenus.jsx
new file mode 100644
index 000000000..fc55ad011
--- /dev/null
+++ b/src/forge/Issues/Component/allMenus.jsx
@@ -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(
+
+ { !update && setAuthor(value)}
+ chooseFunc={(id,name)=>choose(id,name,'author_name')}
+ />
+ }
+ {update && {let copy = {...ids,issue_priorities_id:id};let copyname = { ...names,issue_priorities_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
+ />
+ }
+ 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)}}
+ />
+ setMillstone(value)}
+ chooseFunc={(id,name)=>{let copy = {...ids,milestone_id:id};let copyname = { ...names,milestone_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
+ />
+ setCharge(value)}
+ chooseFunc={(id,name)=>{let copy = {...ids,assigner_id:id};let copyname = { ...names,assigner_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
+ />
+ {let copy = {...ids,status_id:id};let copyname = { ...names,status_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
+ />
+ { !update && {let copy = {...ids,sort_by:id};let copyname = { ...names,sortby_name:name};setNames(copyname);setIds(copy);chooseFunc(copy)}}
+ />
+ }
+
+ )
+}
+export default forwardRef(AllMenus);
\ No newline at end of file
diff --git a/src/forge/Issues/Component/datas.jsx b/src/forge/Issues/Component/datas.jsx
index 2eb685ca7..514f08dda 100644
--- a/src/forge/Issues/Component/datas.jsx
+++ b/src/forge/Issues/Component/datas.jsx
@@ -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(
{checkbox}
- {item.priority_name}
+ {item.priority_name}
{item.project_issues_index && #{item.project_issues_index}}
{item.subject}
-
invalid
+ {
+ item.tags && item.tags.length>0?
+ item.tags.map((i,k)=>{
+ return(
+
{i.name}
+ )
+ })
+ :""
+ }
-

-
{item.author && item.author.name}
+

+
{item.author && item.author.name}
{item.created_at} 发布
{item.updated_at}更新
- {item.milestone_name &&
{item.milestone_name} }
+ {item.milestone_name &&
{item.milestone_name} }
-
+ {
+ item.assigners && item.assigners.length > 0 ?
+
+ {
+ item.assigners.map((i,k)=>{
+ return(
+ k<5 &&
})
+ )
+ })
+ }
+ {/*
... */}
+
+ :""
+ }
{item.status_name}
{item.comment_journals_count}
diff --git a/src/forge/Issues/Component/date.jsx b/src/forge/Issues/Component/date.jsx
new file mode 100644
index 000000000..326bdad47
--- /dev/null
+++ b/src/forge/Issues/Component/date.jsx
@@ -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=(
+
+
{
+ 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(
+
+ {months[index]}
+ ,
+ );
+ }
+ const month = value.month();
+
+ const year = value.year();
+ const options = [];
+ for (let i = year - 10; i < year + 10; i += 1) {
+ options.push(
+
+ {i}
+ ,
+ );
+ }
+ return (
+
+
+
+
+ onTypeChange(e.target.value)} value={type}>
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }}
+ onSelect={onSelect}
+ />
+
+ )
+ return(
+
+
+
+ {name}
+ setVisible(visible ? false : true)}>
+
+ {time || "未设置"}
+
+
+ )
+}
+export default forwardRef(Date);
\ No newline at end of file
diff --git a/src/forge/Issues/Component/drop.jsx b/src/forge/Issues/Component/drop.jsx
index 9a4fe474a..272d96489 100644
--- a/src/forge/Issues/Component/drop.jsx
+++ b/src/forge/Issues/Component/drop.jsx
@@ -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(
{overlay} }
trigger={['click']}
+ overlayClassName={overlayClassName}
>
setVisible(visible ? false : true)}>
- {value}
-
+ {children}
)
diff --git a/src/forge/Issues/Component/editMenus.jsx b/src/forge/Issues/Component/editMenus.jsx
index 0191ef354..926b98a0b 100644
--- a/src/forge/Issues/Component/editMenus.jsx
+++ b/src/forge/Issues/Component/editMenus.jsx
@@ -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(
- {name}
-
+ {name}
+ {!editFlag && setVisible(visible ? false : true)}>}
+
+
{ searchFlag &&
-
+
}
{
menus && menus.length >0?
-
}>
- setVisible(visible ? false : true)} className={showValue?"operatevalue color-grey-3":"operatevalue"}>{showValue || "未设置"}
+ {showValue || emptyName}
)
diff --git a/src/forge/Issues/Component/menus.jsx b/src/forge/Issues/Component/menus.jsx
index 17f25b175..9aab7e5ba 100644
--- a/src/forge/Issues/Component/menus.jsx
+++ b/src/forge/Issues/Component/menus.jsx
@@ -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
- { item.size !== "small" &&
-
- }
-
- {
- item.menu.map((i,j)=>{
- return
- {item.imgControl &&
}
- changeMenusValue(i.id,item.id)}>{i.name}
-
- })
- }
-
-
+ function menu(data){
+ return
+ { size !== "small" &&
+
searchFunc(e.target.value)}/>
}
- else{
- return "";
- }
+ {
+ data && data.length>0 ?
+
+ {
+ data.map((i,j)=>{
+ return
+ {imgControl &&
}
+ changeMenusValue(i.name,i.id)}>{i.name}
+
+ })
+ }
+
+ :
+
暂无{id ? '{name}': name}
+ }
+
}
return(
- dropmenu && dropmenu.length >0 ?
-
- {
- dropmenu.map((item,i)=>{
- let ichoose = item.choose !== 0 && item.menu.filter(k=>k.id === item.choose);
- return(
- ((!update && item.name) || (update && item.updateName)) &&
- 0 && ichoose[0].name):(update ? item.updateName : item.name)}
- />
- )
- })
- }
-
- :
+
+ {(update && !id) ? `更换${name}` : name }
+
+
)
}
-export default forwardRef(Menus);
\ No newline at end of file
+export default Menus;
\ No newline at end of file
diff --git a/src/forge/Issues/Pages/list.jsx b/src/forge/Issues/Pages/list.jsx
index 63e5ea473..455c2ae99 100644
--- a/src/forge/Issues/Pages/list.jsx
+++ b/src/forge/Issues/Pages/list.jsx
@@ -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){
}
-
0}
owner={owner}
projectsId={projectsId}
- update={allValue && allValue.length>0}
+ chooseFunc={chooseFunc}
/>
{
allValue && allValue.length>0 ?
-
+
@@ -191,7 +237,7 @@ function List(props){
issueList.map((item,key)=>{
return(
}
+ checkbox={ }
item={item}
owner={owner}
projectsId={projectsId}
diff --git a/src/forge/Issues/Pages/new.jsx b/src/forge/Issues/Pages/new.jsx
index 111b73c28..ec017a2b4 100644
--- a/src/forge/Issues/Pages/new.jsx
+++ b/src/forge/Issues/Pages/new.jsx
@@ -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(
-
setVisible(false)} onSuccess={onSuccess} />
+ setVisible(false)} onSuccess={onSuccess}
+ />
新建疑修
-
+
+ {getFieldDecorator("subject",{
+ rules:[{required:true,message:"请输入疑修标题"}]
+ })(
+
+ )}
+
+
-
+
-
-
-
- setVisible(true)} searchFlag/>
-
+ setCharegeId(ids)} list={chargeList} searchFlag searchFunc={(value)=>setCharge(value)} double={5}/>
+ setStatusId(ids)} list={statusList} editFlag value={statusId}/>
+ setPrioritiesId(ids)} list={prioritiesList} value={prioritiesId}/>
+ setTagId(ids)} list={tagList} onAdd={()=>setVisible(true)} searchFlag double={3} searchFunc={(value)=>setTag(value)}/>
+ setMillstoneId(ids)} list={millstoneList} searchFlag searchFunc={(value)=>setMillstone(value)}/>
+ setBranchId(ids)} list={branchList} searchFlag searchFunc={(value)=>setBranch(value)}/>
+ setStartDate(date)}/>
+ setDueDate(date)}/>
)
}
-export default New;
\ No newline at end of file
+export default Form.create()(forwardRef(New));
\ No newline at end of file
diff --git a/src/forge/Issues/index.scss b/src/forge/Issues/index.scss
index 0be735da4..1be819fcb 100644
--- a/src/forge/Issues/index.scss
+++ b/src/forge/Issues/index.scss
@@ -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{
diff --git a/src/forge/Upload/Index.js b/src/forge/Upload/Index.js
index e9881393c..ea8ab180e 100644
--- a/src/forge/Upload/Index.js
+++ b/src/forge/Upload/Index.js
@@ -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)=>{