forked from Gitlink/forgeplus-react
Merge branch 'newVersion_forge' of http://gitea.trustie.net/jasder/forgeplus-react into newVersion_forge
This commit is contained in:
commit
982db1460b
File diff suppressed because one or more lines are too long
|
@ -94,6 +94,18 @@ const MilepostDetail = Loadable({
|
|||
loader: () => import('../Order/MilepostDetail'),
|
||||
loading: Loading,
|
||||
})
|
||||
const WatchUsers = Loadable({
|
||||
loader: () => import('../UsersList/watch_users'),
|
||||
loading: Loading,
|
||||
})
|
||||
const PraiseUsers = Loadable({
|
||||
loader: () => import('../UsersList/praise_users'),
|
||||
loading: Loading,
|
||||
})
|
||||
const ForkUsers = Loadable({
|
||||
loader: () => import('../UsersList/fork_users'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
||||
const TrendsIndex = Loadable({
|
||||
|
@ -174,18 +186,23 @@ class Detail extends Component {
|
|||
// 关注和取消关注
|
||||
focusFunc = (flag) => {
|
||||
const { project_id } = this.state;
|
||||
axios({
|
||||
method: flag ? 'delete' : 'post',
|
||||
url: `/projects/${project_id}/watchers/${flag ? 'unfollow' : 'follow'}.json`
|
||||
})
|
||||
.then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.setWatchersCount(result.data.watchers_count, result.data.watched);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
axios({
|
||||
method: flag? 'delete' : 'post',
|
||||
url: `/watchers/${flag? 'unfollow' : 'follow'}.json`,
|
||||
params: {
|
||||
target_type: "project",
|
||||
id: project_id
|
||||
}
|
||||
})
|
||||
.then(result => {
|
||||
if(result && result.data.status === 0){
|
||||
this.setWatchersCount(result.data.watchers_count, result.data.watched);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 点赞和取消点赞
|
||||
|
@ -318,19 +335,28 @@ class Detail extends Component {
|
|||
<img src={watched ? img_focused : img_focus} alt="" width="14px" />
|
||||
{watched ? '取消关注' : '关注'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||
<Link className="detail_tag_btn_count" to={{pathname:`/projects/${projectsId}/watch_users`, state}}>
|
||||
{watchers_count}
|
||||
</Link>
|
||||
{/* <span className="detail_tag_btn_count">{watchers_count}</span> */}
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={() => this.pariseFunc(praised)}>
|
||||
<img src={praised ? img_parised : img_parise} width="13px" alt="" />
|
||||
{praised ? '取消点赞' : '点赞'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
<Link className="detail_tag_btn_count" to={{pathname:`/projects/${projectsId}/praise_users`,state}}>
|
||||
{praises_count}
|
||||
</Link>
|
||||
{/* <span className="detail_tag_btn_count">{praises_count}</span> */}
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
||||
<img src={img_fork} alt="" width="10px" />Fork</a>
|
||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||
<img src={img_fork} alt="" width="10px"/>Fork</a>
|
||||
<Link className="detail_tag_btn_count" to={{pathname:`/projects/${projectsId}/fork_users`,state}}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
{/* <span className="detail_tag_btn_count">{forked_count}</span> */}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -521,6 +547,21 @@ class Detail extends Component {
|
|||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/watch_users"
|
||||
render={
|
||||
(props) => (<WatchUsers {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/praise_users"
|
||||
render={
|
||||
(props) => (<PraiseUsers {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/fork_users"
|
||||
render={
|
||||
(props) => (<ForkUsers {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} />)
|
||||
|
|
|
@ -316,11 +316,15 @@
|
|||
}
|
||||
.detail_tag_btn_count{
|
||||
padding:0px 10px;
|
||||
color: #fff;
|
||||
background: #71A6FF;
|
||||
color: #fff !important;
|
||||
background: rgba(255,255,255,0.2);
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.detail_tag_btn_count:hover{
|
||||
/* color: #1C91FF !important; */
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
/* 详情-代码 */
|
||||
.branch-wrapper{
|
||||
border:1px solid #eee;
|
||||
|
|
|
@ -1,112 +1,151 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {Popconfirm} from "antd";
|
||||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Popconfirm } from "antd";
|
||||
|
||||
class MergeItem extends Component{
|
||||
constructor(props){
|
||||
class MergeItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
this.state = {
|
||||
//显示 隐藏
|
||||
isdisplay:false,
|
||||
orderid:'',
|
||||
}
|
||||
isdisplay: false,
|
||||
orderid: "",
|
||||
};
|
||||
}
|
||||
|
||||
onMouseMove=(type)=>{
|
||||
onMouseMove = (type) => {
|
||||
this.setState({
|
||||
isdisplay:true,
|
||||
orderid:type
|
||||
})
|
||||
}
|
||||
isdisplay: true,
|
||||
orderid: type,
|
||||
});
|
||||
};
|
||||
|
||||
onMouseOut=()=>{
|
||||
onMouseOut = () => {
|
||||
this.setState({
|
||||
isdisplay:false
|
||||
})
|
||||
}
|
||||
isdisplay: false,
|
||||
});
|
||||
};
|
||||
|
||||
set_issue_tags =(issue_tags)=>{
|
||||
if(issue_tags && issue_tags.length > 0){
|
||||
return(
|
||||
issue_tags.map((item,key)=>{
|
||||
return(
|
||||
<span className="issue-tag-show" style={{background: item.color}}>{item.name}</span>
|
||||
)
|
||||
})
|
||||
)
|
||||
}else{
|
||||
return("--")
|
||||
set_issue_tags = (issue_tags) => {
|
||||
if (issue_tags && issue_tags.length > 0) {
|
||||
return issue_tags.map((item, key) => {
|
||||
return (
|
||||
<span className="issue-tag-show" style={{ background: item.color }}>
|
||||
{item.name}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return "--";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render(){
|
||||
const { issues , search_count , page , limit } = this.props;
|
||||
render() {
|
||||
const { issues, search_count, page, limit } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { current_user } = this.props;
|
||||
const renderList =()=>{
|
||||
if(issues && issues.length > 0){
|
||||
return(
|
||||
issues.map((item,key)=>{
|
||||
return(
|
||||
<div className="issueItem">
|
||||
const renderList = () => {
|
||||
if (issues && issues.length > 0) {
|
||||
return issues.map((item, key) => {
|
||||
return (
|
||||
<div className="issueItem">
|
||||
<div className="flex-1">
|
||||
<p className="mb15 df">
|
||||
<span className={item.issue_status==="关闭"? "issueNo":"issueNo issueOpen"}># {search_count - (key + (page-1) * limit)}</span>
|
||||
<Link to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`} className="flex-1 hide-1 font-16 color-grey-3 lineh-30">{item.name}</Link>
|
||||
</p>
|
||||
<p className="color-grey-6 font-12">
|
||||
<span>{item.format_time}</span><span className="ml5">发布</span>
|
||||
{
|
||||
item.updated_at === item.format_time ?
|
||||
""
|
||||
:
|
||||
<span className="ml20"><span>{item.updated_at}</span><span className="ml5">更新</span></span>
|
||||
<p className="mb15 df">
|
||||
<span
|
||||
className={
|
||||
item.issue_status === "关闭"
|
||||
? "issueNo"
|
||||
: "issueNo issueOpen"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<ul className="topWrapper_select no-cursor" onMouseMove={()=>this.onMouseMove(item.id)} onMouseOut={()=>this.onMouseOut()}>
|
||||
<li>{this.set_issue_tags(item.issue_tags)}</li>
|
||||
{/*<li>{item.issue_type || "--"}</li>*/}
|
||||
<li>{item.version || "--"}</li>
|
||||
<li>
|
||||
{
|
||||
item.assign_user_name ?
|
||||
<Link to={`/users/${item.assign_user_login}/projects`} className="show-user-link">
|
||||
{item.assign_user_name}
|
||||
</Link>
|
||||
: "--"
|
||||
}
|
||||
</li>
|
||||
<li>
|
||||
<div className="flex-1">
|
||||
<p>
|
||||
{ item.journals_count ? <Link to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}><i className="iconfont icon-pinglun1 mr3 font-16"></i>{item.journals_count}</Link> : "" }
|
||||
</p>
|
||||
{
|
||||
current_user && current_user.login ?
|
||||
<div className="milepostleft" style={{display:this.state.orderid===item.id&&this.state.isdisplay?'flex':'none'}}>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<Link to={`/projects/${projectsId}/merge/${item.pull_request_id}/updatemerge`} className="color-grey-9"><i className="iconfont icon-bianji3 font-14 mr5"></i></Link>
|
||||
</div>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
>
|
||||
# {search_count - (key + (page - 1) * limit)}
|
||||
</span>
|
||||
<Link
|
||||
to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}
|
||||
className="flex-1 hide-1 font-16 color-grey-3 lineh-30"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
</p>
|
||||
<p className="color-grey-6 font-12">
|
||||
<span>{item.format_time}</span>
|
||||
<span className="ml5">发布</span>
|
||||
{item.updated_at === item.format_time ? (
|
||||
""
|
||||
) : (
|
||||
<span className="ml20">
|
||||
<span>{item.updated_at}</span>
|
||||
<span className="ml5">更新</span>
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
)
|
||||
<ul
|
||||
className="topWrapper_select no-cursor"
|
||||
onMouseMove={() => this.onMouseMove(item.id)}
|
||||
onMouseOut={() => this.onMouseOut()}
|
||||
>
|
||||
<li>{this.set_issue_tags(item.issue_tags)}</li>
|
||||
{/*<li>{item.issue_type || "--"}</li>*/}
|
||||
<li>{item.version || "--"}</li>
|
||||
<li>
|
||||
{item.assign_user_name ? (
|
||||
<Link
|
||||
to={`/users/${item.assign_user_login}/projects`}
|
||||
className="show-user-link"
|
||||
>
|
||||
{item.assign_user_name}
|
||||
</Link>
|
||||
) : (
|
||||
"--"
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
<div className="flex-1">
|
||||
<p>
|
||||
{item.journals_count ? (
|
||||
<Link
|
||||
to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}
|
||||
>
|
||||
<i className="iconfont icon-pinglun1 mr3 font-16"></i>
|
||||
{item.journals_count}
|
||||
</Link>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</p>
|
||||
{current_user && current_user.login ? (
|
||||
<div
|
||||
className="milepostleft"
|
||||
style={{
|
||||
display:
|
||||
this.state.orderid === item.id &&
|
||||
this.state.isdisplay
|
||||
? "flex"
|
||||
: "none",
|
||||
}}
|
||||
>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<Link
|
||||
to={`/projects/${projectsId}/merge/${item.pull_request_id}/updatemerge`}
|
||||
className="color-grey-9"
|
||||
>
|
||||
<i className="iconfont icon-bianji3 font-14 mr5"></i>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
{renderList()}
|
||||
</div>
|
||||
)
|
||||
};
|
||||
return <div>{renderList()}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export default MergeItem;
|
||||
export default MergeItem;
|
||||
|
|
|
@ -33,8 +33,8 @@ class merge extends Component {
|
|||
search: undefined,
|
||||
author_id: undefined,
|
||||
assigned_to_id: undefined,
|
||||
limit: 15,
|
||||
page: 1,
|
||||
// limit: 15,
|
||||
// page: 1,
|
||||
search_count: undefined,
|
||||
issue_type: undefined,
|
||||
status_type: '1',
|
||||
|
@ -44,7 +44,17 @@ class merge extends Component {
|
|||
issue_tag_ids: '标签',
|
||||
fixed_version_ids: '里程碑',
|
||||
assigned_to_ids: '指派人',
|
||||
paix: '排序'
|
||||
paix: '排序',
|
||||
select_params: {
|
||||
status_type: "1", //开启中和关闭中,默认为开启中的
|
||||
assigned_to_id: undefined, // 指派人
|
||||
fixed_version_id: undefined,
|
||||
order_name: undefined,
|
||||
order_type: undefined,
|
||||
search: undefined,
|
||||
page: 1,
|
||||
limit: 15,
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -70,14 +80,12 @@ class merge extends Component {
|
|||
}
|
||||
|
||||
// 获取列表数据
|
||||
getIssueList = (page, limit, search, author_id, assigned_to_id, status_type, id, value, order_type, order_name) => {
|
||||
getIssueList = () => {
|
||||
const { select_params } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
page, limit, search, author_id, assigned_to_id, status_type, order_type, order_name,
|
||||
[id]: value
|
||||
}
|
||||
params: select_params,
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
|
@ -92,34 +100,51 @@ class merge extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
getOption = (e, id, name) => {
|
||||
if (id + 's' === "issue_tag_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
issue_tag_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "fixed_version_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
fixed_version_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "assigned_to_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
assigned_to_ids: name
|
||||
})
|
||||
}
|
||||
getMenu = (e, id, name) => {
|
||||
this.setState({
|
||||
[id]: e.key
|
||||
})
|
||||
const { page, limit, search, author_id, assigned_to_id, status_type } = this.state;
|
||||
if (e.key === "all") {
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id);
|
||||
} else {
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id, e.key);
|
||||
isSpin: true,
|
||||
});
|
||||
let key_name = e.key.split("-");
|
||||
if (key_name[0] === "created_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
paix: "最新创建",
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
paix: "最早创建",
|
||||
});
|
||||
}
|
||||
this.state.select_params.order_name = e.key;
|
||||
} else if (key_name[0] === "updated_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
paix: "最新更新",
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
paix: "最早更新",
|
||||
});
|
||||
}
|
||||
}
|
||||
this.state.select_params.order_name = key_name[0];
|
||||
this.state.select_params.order_type = e.item.props.value;
|
||||
this.state.select_params.page = 1;
|
||||
this.getIssueList();
|
||||
};
|
||||
|
||||
getOption = (e, id, name) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
let option_id = e.key === "all" ? undefined : e.key;
|
||||
this.setState({
|
||||
["${id}s"]: name,
|
||||
});
|
||||
this.state.select_params[`${id}`] = option_id;
|
||||
this.state.select_params.page = 1;
|
||||
this.state[`${id}s`] = name;
|
||||
this.getIssueList();
|
||||
}
|
||||
|
||||
renderMenu = (array, name, id) => {
|
||||
|
@ -140,85 +165,72 @@ class merge extends Component {
|
|||
// 翻页
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page,
|
||||
isSpin: true
|
||||
})
|
||||
const { limit, search, status_type, author_id, assigned_to_id } = this.state;
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type);
|
||||
isSpin: true,
|
||||
});
|
||||
this.state.select_params.page = page;
|
||||
this.getIssueList();
|
||||
}
|
||||
|
||||
// 搜索
|
||||
searchFunc = (value) => {
|
||||
this.setState({
|
||||
search: value,
|
||||
isSpin: true
|
||||
})
|
||||
const { page, limit, status_type, author_id, assigned_to_id } = this.state;
|
||||
this.getIssueList(page, limit, value, author_id, assigned_to_id, status_type);
|
||||
isSpin: true,
|
||||
});
|
||||
this.state.select_params.search = value;
|
||||
this.state.select_params.page = 1;
|
||||
this.getIssueList();
|
||||
}
|
||||
|
||||
openorder = (type) => {
|
||||
if (type) {
|
||||
if (type === 1) {
|
||||
this.setState({
|
||||
status_type: '1',
|
||||
closeselect: undefined,
|
||||
openselect: '123',
|
||||
issue_tag_ids: '标签',
|
||||
fixed_version_ids: '里程碑',
|
||||
assigned_to_ids: '指派人',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList("", "", "", "", "", 1, "");
|
||||
// if (type) {
|
||||
// if (type === 1) {
|
||||
// this.setState({
|
||||
// status_type: '1',
|
||||
// closeselect: undefined,
|
||||
// openselect: '123',
|
||||
// issue_tag_ids: '标签',
|
||||
// fixed_version_ids: '里程碑',
|
||||
// assigned_to_ids: '指派人',
|
||||
// paix: '排序'
|
||||
// })
|
||||
// this.getIssueList("", "", "", "", "", 1, "");
|
||||
|
||||
} else {
|
||||
this.setState({
|
||||
status_type: '2',
|
||||
openselect: undefined,
|
||||
closeselect: '123',
|
||||
|
||||
issue_tag_ids: '标签',
|
||||
fixed_version_ids: '里程碑',
|
||||
assigned_to_ids: '指派人',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList("", "", "", "", "", 2, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
arrayList = (e) => {
|
||||
const { limit, search, status_type, author_id, assigned_to_id } = this.state;
|
||||
if (e.key === 'created_on') {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
paix: '最新创建'
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
paix: '最早创建'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
paix: '最新更新'
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
paix: '最早更新'
|
||||
})
|
||||
}
|
||||
}
|
||||
// } else {
|
||||
// this.setState({
|
||||
// status_type: '2',
|
||||
// openselect: undefined,
|
||||
// closeselect: '123',
|
||||
|
||||
// issue_tag_ids: '标签',
|
||||
// fixed_version_ids: '里程碑',
|
||||
// assigned_to_ids: '指派人',
|
||||
// paix: '排序'
|
||||
// })
|
||||
// this.getIssueList("", "", "", "", "", 2, "");
|
||||
// }
|
||||
// }
|
||||
|
||||
this.setState({
|
||||
order_name: e.key,
|
||||
order_type: e.item.props.value
|
||||
})
|
||||
this.getIssueList(1, limit, search, author_id, assigned_to_id, status_type, undefined, undefined, e.item.props.value, e.key);
|
||||
}
|
||||
isSpin: true,
|
||||
});
|
||||
if (type) {
|
||||
this.setState({
|
||||
status_type: type,
|
||||
issue_tag_ids: '标签',
|
||||
fixed_version_ids: '里程碑',
|
||||
assigned_to_ids: '指派人',
|
||||
paix: '排序'
|
||||
});
|
||||
this.state.select_params = {
|
||||
status_type: type,
|
||||
search: undefined,
|
||||
page: 1,
|
||||
limit: 15,
|
||||
};
|
||||
this.getIssueList();
|
||||
}}
|
||||
|
||||
|
||||
islogin() {
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
@ -230,15 +242,23 @@ class merge extends Component {
|
|||
}
|
||||
}
|
||||
render() {
|
||||
const { issue_chosen, issues, limit, page, search_count, data, isSpin, openselect, closeselect } = this.state;
|
||||
const { issue_chosen, issues, limit, page, search_count, data, isSpin, status_type, select_params } = this.state;
|
||||
const menu = (
|
||||
<Menu onClick={(e) => this.arrayList(e)}>
|
||||
<Menu.Item key={'created_on'} value="desc">最新创建</Menu.Item>
|
||||
<Menu.Item key={'created_on'} value="asc">最早创建</Menu.Item>
|
||||
<Menu.Item key={'updated_on'} value="desc">最新更新</Menu.Item>
|
||||
<Menu.Item key={'updated_on'} value="asc">最早更新</Menu.Item>
|
||||
<Menu onClick={(e) => this.getMenu(e)}>
|
||||
<Menu.Item key={"created_on-desc"} value="desc">
|
||||
最新创建
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"created_on-asc"} value="asc">
|
||||
最早创建
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"updated_on-desc"} value="desc">
|
||||
最新更新
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"updated_on-asc"} value="asc">
|
||||
最早更新
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
);
|
||||
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
|
@ -254,8 +274,8 @@ class merge extends Component {
|
|||
<div className="main">
|
||||
<div className="topWrapper" style={{ borderBottom: "none" }}>
|
||||
<p className="topWrapper_type">
|
||||
<li className={openselect ? "active" : ""} onClick={() => this.openorder(1)}>{data && data.open_count ? data.open_count : 0}个开启中</li>
|
||||
<li className={closeselect ? "active" : ""} onClick={() => this.openorder(2)}>{data && data.close_count ? data.close_count : 0}个已关闭</li>
|
||||
<li className={status_type === "1" ? "active" : ""} onClick={() => this.openorder("1")}>{data && data.open_count ? data.open_count : 0}个开启中</li>
|
||||
<li className={status_type === "2" ? "active" : ""} onClick={() => this.openorder("2")}>{data && data.close_count ? data.close_count : 0}个已关闭</li>
|
||||
</p>
|
||||
|
||||
<div className="topWrapper_select">
|
||||
|
@ -300,7 +320,7 @@ class merge extends Component {
|
|||
data && data.search_count && data.search_count > 0 ?
|
||||
<div>
|
||||
<Spin spinning={isSpin}>
|
||||
<OrderItem issues={issues} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state}></OrderItem>
|
||||
<OrderItem issues={issues} search_count={search_count} page={select_params.page} limit={select_params.limit} {...this.props} {...this.state}></OrderItem>
|
||||
{Paginations}
|
||||
</Spin>
|
||||
</div>
|
||||
|
@ -312,4 +332,5 @@ class merge extends Component {
|
|||
)
|
||||
}
|
||||
}
|
||||
export default merge;
|
||||
export default merge;
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React, { Component } from "react";
|
||||
import { Input, Dropdown, Menu, Icon, Pagination, Spin } from 'antd';
|
||||
import './order.css';
|
||||
import { Input, Dropdown, Menu, Icon, Pagination, Spin } from "antd";
|
||||
import "./order.css";
|
||||
|
||||
import NoneData from '../Nodata';
|
||||
import OrderItem from './OrderItem';
|
||||
import NoneData from "../Nodata";
|
||||
import OrderItem from "./OrderItem";
|
||||
|
||||
import axios from 'axios';
|
||||
import axios from "axios";
|
||||
|
||||
const Search = Input.Search;
|
||||
/**
|
||||
|
@ -33,312 +33,284 @@ class order extends Component {
|
|||
search: undefined,
|
||||
author_id: undefined,
|
||||
assigned_to_id: undefined,
|
||||
limit: 15,
|
||||
page: 1,
|
||||
// limit: 15,
|
||||
// page: 1,
|
||||
search_count: undefined,
|
||||
issue_type: undefined,
|
||||
status_type: '1',
|
||||
status_type: "1",
|
||||
//设置选择高亮
|
||||
openselect: 1,
|
||||
closeselect: undefined,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
|
||||
}
|
||||
// openselect: 1,
|
||||
// closeselect: undefined,
|
||||
issue_tag_ids: "标签",
|
||||
tracker_ids: "所有分类",
|
||||
author_ids: "发布人",
|
||||
assigned_to_ids: "指派人",
|
||||
priority_ids: "优先度",
|
||||
done_ratios: "完成度",
|
||||
paix: "排序",
|
||||
select_params: {
|
||||
status_type: "1", //开启中和关闭中,默认为开启中的
|
||||
assigned_to_id: undefined, // 指派人
|
||||
author_id: undefined, // 发布人
|
||||
issue_tag_id: undefined, // 标签
|
||||
tracker_id: undefined, //所有分类
|
||||
done_ratio: undefined, // 完成度
|
||||
priority_id: undefined, // 优先级
|
||||
order_name: undefined,
|
||||
order_type: undefined,
|
||||
search: undefined,
|
||||
page: 1,
|
||||
limit: 15,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.getSelectList();
|
||||
this.getIssueList("", "", "", "", "", "1", "", "", "", "");
|
||||
}
|
||||
this.getIssueList();
|
||||
};
|
||||
|
||||
getSelectList = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const url = `/projects/${projectsId}/issues/index_chosen.json`;
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
issue_chosen: result.data.issue_chosen
|
||||
})
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
issue_chosen: result.data.issue_chosen,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 获取列表数据
|
||||
getIssueList = (page, limit, search, author_id, assigned_to_id, status_type, id, value, order_name, order_type) => {
|
||||
getIssueList = () => {
|
||||
const { select_params } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues.json`;
|
||||
axios.get(url, {
|
||||
params: {
|
||||
page, limit, search, author_id, assigned_to_id, status_type, order_name, order_type,
|
||||
[id]: value
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
axios
|
||||
.get(url, {
|
||||
params: select_params,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
issues: result.data.issues,
|
||||
search_count: result.data.search_count,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
getMenu = (e, id, name) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
let key_name = e.key.split("-");
|
||||
if (key_name[0] === "created_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
issues: result.data.issues,
|
||||
search_count: result.data.search_count,
|
||||
isSpin: false
|
||||
})
|
||||
paix: "最新创建",
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
paix: "最早创建",
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
this.state.select_params.order_name = e.key;
|
||||
} else if (key_name[0] === "updated_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
paix: "最新更新",
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
paix: "最早更新",
|
||||
});
|
||||
}
|
||||
}
|
||||
this.state.select_params.order_name = key_name[0];
|
||||
this.state.select_params.order_type = e.item.props.value;
|
||||
this.state.select_params.page = 1;
|
||||
this.getIssueList();
|
||||
};
|
||||
|
||||
getOption = (e, id, name) => {
|
||||
if (id + 's' === "issue_tag_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
issue_tag_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "tracker_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
tracker_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "author_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
author_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "assigned_to_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
assigned_to_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "priority_ids") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
priority_ids: name
|
||||
})
|
||||
}
|
||||
if (id + 's' === "done_ratios") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
done_ratios: name
|
||||
})
|
||||
}
|
||||
if (e.key === "created_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最新创建'
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最早创建'
|
||||
})
|
||||
}
|
||||
} else if (e.key === "updated_on") {
|
||||
if (e.item.props.value === "desc") {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最新更新'
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
paix: '最早更新'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const { current_user } = this.props;
|
||||
this.setState({
|
||||
[id]: e.key,
|
||||
})
|
||||
const { page, limit, search, author_id, assigned_to_id, status_type } = this.state;
|
||||
if (e.key === "all") {
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id);
|
||||
} else if (e.key === "created_on" || e.key === "updated_on") {
|
||||
this.setState({
|
||||
order_name: e.key,
|
||||
order_type: e.item.props.value
|
||||
})
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id, undefined, e.key, e.item.props.value);
|
||||
isSpin: true,
|
||||
});
|
||||
let option_id = e.key === "all" ? undefined : e.key;
|
||||
this.state.select_params[`${id}`] = option_id;
|
||||
this.state.select_params.page = 1;
|
||||
this.state[`${id}s`] = name;
|
||||
if (current_user) {
|
||||
if ( this.state.select_params.author_id && parseInt(this.state.select_params.author_id) === current_user.user_id) {
|
||||
this.state.author_id = current_user.user_id;
|
||||
} else {
|
||||
this.state.author_id = undefined;
|
||||
}
|
||||
|
||||
if (this.state.select_params.assigned_to_id && parseInt(this.state.select_params.assigned_to_id) === current_user.user_id ) {
|
||||
this.state.assigned_to_id = current_user.user_id;
|
||||
} else {
|
||||
this.state.assigned_to_id = undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type, id, e.key);
|
||||
}
|
||||
}
|
||||
this.getIssueList();
|
||||
};
|
||||
|
||||
renderMenu = (array, name, id) => {
|
||||
return (
|
||||
<Menu>
|
||||
<Menu.Item key={"all"} onClick={(e) => this.getOption(e, id, name)}>{name}</Menu.Item>
|
||||
{
|
||||
array && array.length > 0 && array.map((item, key) => {
|
||||
<Menu.Item key={"all"} onClick={(e) => this.getOption(e, id, name)}>
|
||||
{name}
|
||||
</Menu.Item>
|
||||
{array &&
|
||||
array.length > 0 &&
|
||||
array.map((item, key) => {
|
||||
return (
|
||||
<Menu.Item key={item.id} onClick={(e) => this.getOption(e, id, item.name)}>{item.name}</Menu.Item>
|
||||
)
|
||||
})
|
||||
}
|
||||
<Menu.Item
|
||||
key={item.id}
|
||||
onClick={(e) => this.getOption(e, id, item.name)}
|
||||
>
|
||||
{item.name}
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// 翻页
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page,
|
||||
isSpin: true
|
||||
})
|
||||
const { limit, search, status_type, author_id, assigned_to_id } = this.state;
|
||||
this.getIssueList(page, limit, search, author_id, assigned_to_id, status_type);
|
||||
}
|
||||
isSpin: true,
|
||||
});
|
||||
this.state.select_params.page = page;
|
||||
this.getIssueList();
|
||||
};
|
||||
|
||||
// 搜索
|
||||
searchFunc = (value) => {
|
||||
this.setState({
|
||||
search: value,
|
||||
isSpin: true
|
||||
})
|
||||
const { page, limit, status_type, author_id, assigned_to_id } = this.state;
|
||||
this.getIssueList(page, limit, value, author_id, assigned_to_id, status_type);
|
||||
}
|
||||
isSpin: true,
|
||||
});
|
||||
this.state.select_params.search = value;
|
||||
this.state.select_params.page = 1;
|
||||
this.getIssueList();
|
||||
};
|
||||
|
||||
openorder = (type) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
if (type) {
|
||||
console.log(this.state.closeselect + "|" + this.state.openselect)
|
||||
const { current_user } = this.props;
|
||||
if (type === 1) {
|
||||
this.setState({
|
||||
status_type: '1',
|
||||
closeselect: undefined,
|
||||
openselect: 1,
|
||||
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList("", "", "", "", "", 1, "");
|
||||
|
||||
} else {
|
||||
this.setState({
|
||||
status_type: '2',
|
||||
openselect: undefined,
|
||||
closeselect: 1,
|
||||
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList("", "", "", "", "", 2, "");
|
||||
}
|
||||
this.setState({
|
||||
author_id: undefined,
|
||||
assigned_to_id: undefined,
|
||||
status_type: type,
|
||||
issue_tag_ids: "标签",
|
||||
tracker_ids: "所有分类",
|
||||
author_ids: "发布人",
|
||||
assigned_to_ids: "指派人",
|
||||
priority_ids: "优先度",
|
||||
done_ratios: "完成度",
|
||||
paix: "排序",
|
||||
});
|
||||
this.state.select_params = {
|
||||
status_type: type,
|
||||
search: undefined,
|
||||
page: 1,
|
||||
limit: 15,
|
||||
};
|
||||
this.getIssueList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
// 筛选:全部、指派给我、由我创建
|
||||
ChangeAssign = (type) => {
|
||||
const { limit, search, status_type } = this.state;
|
||||
const { current_user } = this.props;
|
||||
|
||||
this.setState({
|
||||
isSpin: true
|
||||
})
|
||||
console.log(current_user)
|
||||
|
||||
isSpin: true,
|
||||
});
|
||||
if (type) {
|
||||
if (current_user === undefined) {
|
||||
this.setState({
|
||||
isSpin: false
|
||||
})
|
||||
isSpin: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (type === 1) {
|
||||
this.setState({
|
||||
page: 1,
|
||||
author_id: undefined,
|
||||
assigned_to_ids: current_user.username,
|
||||
assigned_to_id: current_user.user_id,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList(1, limit, search, undefined, current_user.user_id, status_type);
|
||||
|
||||
author_id: undefined,
|
||||
author_ids: "发布人",
|
||||
});
|
||||
this.state.select_params.author_id = undefined;
|
||||
this.state.select_params.assigned_to_id = current_user.user_id;
|
||||
} else {
|
||||
this.setState({
|
||||
page: 1,
|
||||
author_ids: current_user.username,
|
||||
author_id: current_user.user_id,
|
||||
assigned_to_id: undefined,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList(1, limit, search, current_user.user_id, undefined, status_type);
|
||||
assigned_to_ids: "指派人",
|
||||
});
|
||||
this.state.select_params.assigned_to_id = undefined;
|
||||
this.state.select_params.author_id = current_user.user_id;
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
page: 1,
|
||||
author_ids: "发布人",
|
||||
author_id: undefined,
|
||||
assigned_to_ids: "指派人",
|
||||
assigned_to_id: undefined,
|
||||
issue_tag_ids: '标签',
|
||||
tracker_ids: '所有分类',
|
||||
author_ids: '发布人',
|
||||
assigned_to_ids: '指派人',
|
||||
priority_ids: '优先度',
|
||||
done_ratios: '完成度',
|
||||
paix: '排序'
|
||||
})
|
||||
this.getIssueList(1, limit, search, undefined, undefined, status_type);
|
||||
});
|
||||
this.state.select_params.assigned_to_id = undefined;
|
||||
this.state.select_params.author_id = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
this.getIssueList();
|
||||
};
|
||||
|
||||
deletedetail = (id) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${id}.json`;
|
||||
axios.delete(url, {
|
||||
data: {
|
||||
project_id: projectsId,
|
||||
id: id
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
this.getIssueList()
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
})
|
||||
console.log(id)
|
||||
}
|
||||
axios
|
||||
.delete(url, {
|
||||
data: {
|
||||
project_id: projectsId,
|
||||
id: id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.getIssueList();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
console.log(id);
|
||||
};
|
||||
|
||||
islogin() {
|
||||
const { projectsId } = this.props.match.params;
|
||||
if (this.props.checkIfLogin() === false) {
|
||||
this.props.showLoginDialog()
|
||||
return
|
||||
this.props.showLoginDialog();
|
||||
return;
|
||||
} else {
|
||||
this.props.history.push(`/projects/${projectsId}/orders/new`);
|
||||
}
|
||||
|
@ -347,33 +319,68 @@ class order extends Component {
|
|||
render() {
|
||||
const { current_user } = this.props;
|
||||
|
||||
const { issue_chosen, issues, limit, page, search_count, data, assigned_to_id, author_id, isSpin, openselect, closeselect } = this.state;
|
||||
const {
|
||||
issue_chosen,
|
||||
issues,
|
||||
search_count,
|
||||
data,
|
||||
author_id,
|
||||
assigned_to_id,
|
||||
isSpin,
|
||||
status_type,
|
||||
select_params,
|
||||
} = this.state;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={(e) => this.getOption(e)}>
|
||||
<Menu.Item key={'created_on'} value="desc">最新创建</Menu.Item>
|
||||
<Menu.Item key={'created_on'} value="asc">最早创建</Menu.Item>
|
||||
<Menu.Item key={'updated_on'} value="desc">最新更新</Menu.Item>
|
||||
<Menu.Item key={'updated_on'} value="asc">最早更新</Menu.Item>
|
||||
<Menu onClick={(e) => this.getMenu(e)}>
|
||||
<Menu.Item key={"created_on-desc"} value="desc">
|
||||
最新创建
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"created_on-asc"} value="asc">
|
||||
最早创建
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"updated_on-desc"} value="desc">
|
||||
最新更新
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"updated_on-asc"} value="asc">
|
||||
最早更新
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
);
|
||||
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
{
|
||||
search_count > limit ?
|
||||
<div className="mt30 mb50 edu-txt-center">
|
||||
<Pagination simple defaultCurrent={page} total={search_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div> : ""
|
||||
}
|
||||
{search_count > select_params.limit ? (
|
||||
<div className="mt30 mb50 edu-txt-center">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={select_params.page}
|
||||
total={search_count}
|
||||
pageSize={select_params.limit}
|
||||
onChange={this.ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</React.Fragment>
|
||||
)
|
||||
);
|
||||
return (
|
||||
<div className="main">
|
||||
<div className="topWrapper" style={{ borderBottom: "none" }}>
|
||||
<p className="topWrapper_type">
|
||||
<li className={openselect ? "active" : ""} onClick={() => this.openorder(1)}>{data && data.open_count}个开启中</li>
|
||||
<li className={closeselect ? "active" : ""} onClick={() => this.openorder(2)}>{data && data.close_count}个已关闭</li>
|
||||
<li
|
||||
className={status_type === "1" ? "active" : ""}
|
||||
onClick={() => this.openorder("1")}
|
||||
>
|
||||
{data && data.open_count}个开启中
|
||||
</li>
|
||||
<li
|
||||
className={status_type === "2" ? "active" : ""}
|
||||
onClick={() => this.openorder("2")}
|
||||
>
|
||||
{data && data.close_count}个已关闭
|
||||
</li>
|
||||
</p>
|
||||
|
||||
<div className="topWrapper_select">
|
||||
|
@ -385,67 +392,176 @@ class order extends Component {
|
|||
style={{ width: 300 }}
|
||||
/>
|
||||
</div>
|
||||
<a className="topWrapper_btn ml10" onClick={() => this.islogin()} >创建任务</a>
|
||||
<a className="topWrapper_btn ml10" onClick={() => this.islogin()}>
|
||||
创建任务
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="f-wrap-between mb20">
|
||||
<ul className="topWrapper_type">
|
||||
<li className={!author_id && !assigned_to_id ? "active" : ""} onClick={() => this.ChangeAssign()}>全部</li>
|
||||
{}
|
||||
<li style={{ display: current_user && current_user.login === "" ? 'none' : 'flex' }} className={assigned_to_id ? "active" : ""} onClick={() => this.ChangeAssign(1)}>指派给我</li>
|
||||
<li style={{ display: current_user && current_user.login === "" ? 'none' : 'flex' }} className={author_id ? "active" : ""} onClick={() => this.ChangeAssign(2)}>由我创建</li>
|
||||
<li
|
||||
className={!author_id && !assigned_to_id ? "active" : ""}
|
||||
onClick={() => this.ChangeAssign()}
|
||||
>
|
||||
全部
|
||||
</li>
|
||||
<li
|
||||
style={{
|
||||
display:
|
||||
current_user && current_user.login === "" ? "none" : "flex",
|
||||
}}
|
||||
className={assigned_to_id ? "active" : ""}
|
||||
onClick={() => this.ChangeAssign(1)}
|
||||
>
|
||||
指派给我
|
||||
</li>
|
||||
<li
|
||||
style={{
|
||||
display:
|
||||
current_user && current_user.login === "" ? "none" : "flex",
|
||||
}}
|
||||
className={author_id ? "active" : ""}
|
||||
onClick={() => this.ChangeAssign(2)}
|
||||
>
|
||||
由我创建
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_tag, '标签', 'issue_tag_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.issue_tag_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.issue_tag,
|
||||
"标签",
|
||||
"issue_tag_id"
|
||||
)}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
{this.state.issue_tag_ids}
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.tracker, '所有分类', 'tracker_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.tracker_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.tracker,
|
||||
"所有分类",
|
||||
"tracker_id"
|
||||
)}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
{this.state.tracker_ids}
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user, '发布人', 'author_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.author_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.assign_user,
|
||||
"发布人",
|
||||
"author_id"
|
||||
)}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
{this.state.author_ids}
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user, '指派人', 'assigned_to_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.assigned_to_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.assign_user,
|
||||
"指派人",
|
||||
"assigned_to_id"
|
||||
)}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
{this.state.assigned_to_ids}
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.priority, '优先度', 'priority_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.priority_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.priority,
|
||||
"优先度",
|
||||
"priority_id"
|
||||
)}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
{this.state.priority_ids}
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.done_ratio, '完成度', 'done_ratio')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.done_ratios}<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={this.renderMenu(
|
||||
issue_chosen && issue_chosen.done_ratio,
|
||||
"完成度",
|
||||
"done_ratio"
|
||||
)}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
{this.state.done_ratios}
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.paix}<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={menu}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
{this.state.paix}
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
:
|
||||
<OrderItem issues={issues} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state} deletedetail={this.deletedetail}></OrderItem>
|
||||
}
|
||||
{search_count === 0 ? (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
) : (
|
||||
<OrderItem
|
||||
issues={issues}
|
||||
search_count={search_count}
|
||||
page={select_params.page}
|
||||
limit={select_params.limit}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
deletedetail={this.deletedetail}
|
||||
></OrderItem>
|
||||
)}
|
||||
{Paginations}
|
||||
|
||||
</Spin>
|
||||
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
export default order;
|
||||
export default order;
|
||||
|
|
|
@ -1,208 +1,423 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Input , AutoComplete , Dropdown , Menu , Icon , Spin , Pagination } from 'antd';
|
||||
import axios from 'axios';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import {
|
||||
Input,
|
||||
AutoComplete,
|
||||
Dropdown,
|
||||
Menu,
|
||||
Icon,
|
||||
Spin,
|
||||
Pagination,
|
||||
Button,
|
||||
Table,
|
||||
Tooltip
|
||||
} from "antd";
|
||||
import NoneData from "../Nodata";
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
const { Search } = Input;
|
||||
|
||||
const { Option } = AutoComplete;
|
||||
const MENU_LIST = [{
|
||||
id:"Manager",
|
||||
name:'管理员'
|
||||
},{
|
||||
id:"Developer",
|
||||
name:'可写权限'
|
||||
},{
|
||||
id:"Reporter",
|
||||
name:'可读权限'
|
||||
}];
|
||||
const MENU_LIST = [
|
||||
{
|
||||
id: "Manager",
|
||||
name: "管理员",
|
||||
},
|
||||
{
|
||||
id: "Developer",
|
||||
name: "开发者",
|
||||
},
|
||||
{
|
||||
id: "Reporter",
|
||||
name: "报告者",
|
||||
},
|
||||
];
|
||||
const LIMIT = 15;
|
||||
class Collaborator extends Component{
|
||||
constructor(props){
|
||||
class Collaborator extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
listData:undefined,
|
||||
user:undefined,
|
||||
user_id:undefined,
|
||||
userDataSource:undefined,
|
||||
page:1,
|
||||
total_count:undefined,
|
||||
isSpin:true,
|
||||
searchKey: undefined
|
||||
}
|
||||
this.state = {
|
||||
listData: undefined,
|
||||
user: undefined,
|
||||
user_id: undefined,
|
||||
userDataSource: undefined,
|
||||
page: 1,
|
||||
total_count: undefined,
|
||||
isSpin: true,
|
||||
searchKey: undefined,
|
||||
search: undefined,
|
||||
role: undefined,
|
||||
otherSpin: false,
|
||||
searchSpin: false,
|
||||
roleName: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
if(this.props.project_id){
|
||||
const { page } = this.state;
|
||||
this.getMember(this.props.project_id,page);
|
||||
componentDidMount = () => {
|
||||
if (this.props.project_id) {
|
||||
this.getMember();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
componentDidUpdate=(prevState)=>{
|
||||
if(this.props.project_id && this.props.project_id !== prevState.project_id){
|
||||
const { page } = this.state;
|
||||
this.getMember(this.props.project_id,page);
|
||||
componentDidUpdate = (prevState) => {
|
||||
if (
|
||||
this.props.project_id &&
|
||||
this.props.project_id !== prevState.project_id
|
||||
) {
|
||||
this.getMember();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 获取项目协作者
|
||||
getMember=(project_id,page)=>{
|
||||
const url = `/projects/${project_id}/members.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
page,limit:LIMIT
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
getMember = () => {
|
||||
const { page, search, role } = this.state;
|
||||
console.log("search", search);
|
||||
console.log("role", role);
|
||||
const url = `/projects/${this.props.project_id}/members.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
page,
|
||||
search: search,
|
||||
role: role,
|
||||
limit: LIMIT,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
listData: result.data.members,
|
||||
isSpin: false,
|
||||
otherSpin: false,
|
||||
searchSpin: false,
|
||||
total_count: result.data.total_count,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
listData:result.data.members,
|
||||
isSpin:false,
|
||||
total_count:result.data.total_count
|
||||
})
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
isSpin: false,
|
||||
otherSpin: false,
|
||||
searchSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
// 输入用户
|
||||
changeInputUser=(e)=>{
|
||||
changeInputUser = (e) => {
|
||||
this.setState({
|
||||
searchKey: e
|
||||
})
|
||||
searchKey: e,
|
||||
});
|
||||
this.getUserList(e);
|
||||
}
|
||||
// 选择用户
|
||||
selectInputUser=(e,option)=>{
|
||||
};
|
||||
searchMember = (e) => {
|
||||
this.state.search = e;
|
||||
this.setState({
|
||||
user_id:e,
|
||||
searchKey: option.props.searchValue
|
||||
searchSpin: true,
|
||||
});
|
||||
this.getMember();
|
||||
};
|
||||
orderMember = (id, name) => {
|
||||
this.setState({
|
||||
isSpin: true
|
||||
})
|
||||
this.state.role = id;
|
||||
this.state.roleName = name;
|
||||
this.getMember();
|
||||
};
|
||||
// 选择用户
|
||||
selectInputUser = (e, option) => {
|
||||
this.setState({
|
||||
user_id: e,
|
||||
searchKey: option.props.searchValue,
|
||||
});
|
||||
this.getUserList(option.props.searchValue);
|
||||
}
|
||||
getUserList=(e)=>{
|
||||
};
|
||||
getUserList = (e) => {
|
||||
const url = `/users/list.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
search:e
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
userDataSource:result.data.users
|
||||
})
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
search: e,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
userDataSource: result.data.users,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 增加协作者
|
||||
addCollaborator=()=>{
|
||||
const { project_id } = this.props;
|
||||
addCollaborator = () => {
|
||||
// const { project_id } = this.props;
|
||||
this.setState({
|
||||
otherSpin: true,
|
||||
});
|
||||
const { user_id } = this.state;
|
||||
const url = `/projects/${project_id}/members.json`;
|
||||
axios.post(url,{
|
||||
user_id
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.getMember(project_id);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
const url = `/projects/${this.props.project_id}/members.json`;
|
||||
axios
|
||||
.post(url, {
|
||||
user_id,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
otherSpin: false,
|
||||
});
|
||||
this.getMember();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 修改权限
|
||||
changeOperaiton=(e,id)=>{
|
||||
const { project_id , page } = this.props;
|
||||
changeOperaiton = (e, id) => {
|
||||
// const { project_id, page } = this.state;
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
const url = `/projects/${project_id}/members/change_role.json`;
|
||||
axios.put(url,{
|
||||
user_id:id,
|
||||
role:e.key
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.props.showNotification('权限修改成功!');
|
||||
this.getMember(project_id,page);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
isSpin: true,
|
||||
});
|
||||
const url = `/projects/${this.props.project_id}/members/change_role.json`;
|
||||
axios
|
||||
.put(url, {
|
||||
user_id: id,
|
||||
role: e.key,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
this.props.showNotification("权限修改成功!");
|
||||
this.getMember();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 删除协作者
|
||||
deleteUser=(id)=>{
|
||||
deleteUser = (id) => {
|
||||
const { page } = this.state;
|
||||
this.props.confirm({
|
||||
content:"确认将此成员从项目中移除?",
|
||||
onOk:()=>{
|
||||
content: "确认将此成员从项目中移除?",
|
||||
onOk: () => {
|
||||
const { project_id } = this.props;
|
||||
const url = `/projects/${project_id}/members/remove.json`;
|
||||
axios.delete(url,{ data: {
|
||||
user_id:id
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.props.showNotification("成员删除成功!");
|
||||
this.getMember(project_id,page);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
changePage=(page)=>{
|
||||
axios
|
||||
.delete(url, {
|
||||
data: {
|
||||
user_id: id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
this.props.showNotification("成员删除成功!");
|
||||
this.getMember();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
changePage = (page) => {
|
||||
this.state.page = page;
|
||||
this.setState({
|
||||
page
|
||||
})
|
||||
const { project_id } = this.props;
|
||||
this.getMember(project_id,page);
|
||||
}
|
||||
render(){
|
||||
const { userDataSource , listData , isSpin , page , total_count,searchKey } = this.state;
|
||||
isSpin: true,
|
||||
});
|
||||
this.getMember();
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
userDataSource,
|
||||
listData,
|
||||
isSpin,
|
||||
page,
|
||||
total_count,
|
||||
searchKey,
|
||||
otherSpin,
|
||||
searchSpin,
|
||||
roleName,
|
||||
} = this.state;
|
||||
// 获取当前项目的拥有者
|
||||
const { author } = this.props;
|
||||
const menu =(id)=> (
|
||||
<Menu>
|
||||
{
|
||||
MENU_LIST.map((item,key)=>{
|
||||
return(
|
||||
<Menu.Item key={item.id} value={item.id} onClick={(e)=>this.changeOperaiton(e,id)}>{item.name}</Menu.Item>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Menu>
|
||||
)
|
||||
|
||||
const source = userDataSource && userDataSource.map((item,key)=>{
|
||||
return(
|
||||
<Option key={key} value={`${item.user_id}`} searchValue={`${item.username}`}>
|
||||
<img className="user_img radius" width="28" height="28" src={getImageUrl(`images/${item && item.image_url}`)} alt=""/>
|
||||
<span className="ml10" style={{'vertical-align':'middle'}}>
|
||||
{item.username}
|
||||
<span className="color-grey ml10">({item.login})</span>
|
||||
</span>
|
||||
</Option>
|
||||
)
|
||||
})
|
||||
return(
|
||||
<div>
|
||||
<div className="normalBox">
|
||||
<div className="normalBox-title font-16">
|
||||
协作者
|
||||
const get_color = (role) => {
|
||||
if (role === "Manager") {
|
||||
return "text-green";
|
||||
} else if (role === "Developer") {
|
||||
return "text-primary";
|
||||
} else {
|
||||
return "text-yellow";
|
||||
}
|
||||
};
|
||||
const member_roles = (item) => {
|
||||
const operation = MENU_LIST.filter((i) => i.id === item.role);
|
||||
return (
|
||||
<span>
|
||||
{author && author.login === item.login ? (
|
||||
<label className={get_color(item.role)}>
|
||||
{operation && operation[0].name}
|
||||
</label>
|
||||
) : (
|
||||
<Dropdown overlay={setRoles(`${item.id}`)} placement={"bottomCenter"}>
|
||||
<span className={get_color(item.role)}>
|
||||
{operation && operation[0].name}
|
||||
<Icon type="caret-down" className="ml2" size="13" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
const roleTitle = (
|
||||
<div><span className="mr3">角色</span>
|
||||
<Tooltip placement='bottom' title={<div>
|
||||
<div className="mb3">管理员:拥有仓库设置功能、代码库读、写操作</div>
|
||||
<div className="mb3">开发人员:只拥有代码库读、写操作</div>
|
||||
<div className="mb3">报告者:只拥有代码库读操作</div>
|
||||
</div>
|
||||
}>
|
||||
<Icon type="question-circle"></Icon>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
const columns = [
|
||||
{
|
||||
title: "头像",
|
||||
dataIndex: "image_url",
|
||||
render: (text, item) => (
|
||||
<span className="f-wrap-alignCenter">
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<img
|
||||
src={getImageUrl(`images/${text}`)}
|
||||
alt=""
|
||||
width="32px"
|
||||
height="32px"
|
||||
className="mr3 radius"
|
||||
/>
|
||||
</Link>
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "用户名",
|
||||
dataIndex: "name",
|
||||
render: (text, item) => (
|
||||
<Link to={`/users/${item.login}/projects`} className="show-user-link">
|
||||
{text}
|
||||
</Link>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "邮箱",
|
||||
dataIndex: "email",
|
||||
render: (text) => <span>{text}</span>,
|
||||
},
|
||||
{
|
||||
title: roleTitle,
|
||||
dataIndex: "role_name",
|
||||
render: (text, item) => member_roles(item),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: "action",
|
||||
render: (text, item) => (
|
||||
<span style={{ justifyContent: "center" }}>
|
||||
{author && author.login !== item.login && (
|
||||
<a
|
||||
className="text-delete"
|
||||
onClick={() => this.deleteUser(item.id)}
|
||||
>
|
||||
删除
|
||||
</a>
|
||||
)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
const roles = (id) => (
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
key={0}
|
||||
value={undefined}
|
||||
onClick={(e) => this.orderMember(undefined, "角色筛选")}
|
||||
>
|
||||
全部
|
||||
</Menu.Item>
|
||||
{MENU_LIST.map((item, key) => {
|
||||
return (
|
||||
<Menu.Item
|
||||
key={item.id}
|
||||
value={item.id}
|
||||
onClick={(e) => this.orderMember(item.id, item.name)}
|
||||
>
|
||||
{item.name}
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
</Menu>
|
||||
);
|
||||
const setRoles = (id) => (
|
||||
<Menu>
|
||||
{MENU_LIST.map((item, key) => {
|
||||
return (
|
||||
<Menu.Item
|
||||
key={item.id}
|
||||
value={item.id}
|
||||
onClick={(e) => this.changeOperaiton(e,id)}
|
||||
>
|
||||
{item.name}
|
||||
</Menu.Item>
|
||||
);
|
||||
})}
|
||||
</Menu>
|
||||
);
|
||||
|
||||
const source =
|
||||
userDataSource &&
|
||||
userDataSource.map((item, key) => {
|
||||
return (
|
||||
<Option
|
||||
key={key}
|
||||
value={`${item.user_id}`}
|
||||
searchValue={`${item.username}`}
|
||||
>
|
||||
<img
|
||||
className="user_img radius"
|
||||
width="28"
|
||||
height="28"
|
||||
src={getImageUrl(`images/${item && item.image_url}`)}
|
||||
alt=""
|
||||
/>
|
||||
<span className="ml10" style={{ "vertical-align": "middle" }}>
|
||||
{item.username}
|
||||
<span className="color-grey ml10">({item.login})</span>
|
||||
</span>
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<div className="flex-a-center baseForm bbr">
|
||||
<span className="font-18 fwb text-black">协作者管理</span>
|
||||
<div className="addPanel">
|
||||
<AutoComplete
|
||||
dataSource={source}
|
||||
|
@ -210,63 +425,64 @@ class Collaborator extends Component{
|
|||
style={{ width: 300 }}
|
||||
onChange={this.changeInputUser}
|
||||
onSelect={this.selectInputUser}
|
||||
placeholder="用户名或邮箱搜索..."
|
||||
placeholder="搜索需要添加的用户..."
|
||||
/>
|
||||
<a className="small_submitBtn ml20" onClick={this.addCollaborator}>增加协作者</a>
|
||||
<Button
|
||||
type="primary"
|
||||
ghost
|
||||
onClick={this.addCollaborator}
|
||||
className="ml15"
|
||||
loading={otherSpin}
|
||||
>
|
||||
<Icon type="plus" size="16"></Icon>
|
||||
添加成员
|
||||
</Button>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="collaboratorList">
|
||||
{
|
||||
listData && listData.map((item,key)=>{
|
||||
const operation = MENU_LIST.filter(i=>i.id === item.role);
|
||||
return(
|
||||
<div className="collaboratorItem">
|
||||
<span>
|
||||
<Link to={`/users/${item && item.login}/projects`} className="show-user-link">
|
||||
<img className="user_img radius" width="28" height="28" src={getImageUrl(`images/${item && item.image_url}`)} alt=""/>
|
||||
<span className="ml10" style={{'vertical-align':'middle'}}>
|
||||
{item.name}
|
||||
<span className="color-grey ml10">({item.login})</span>
|
||||
</span>
|
||||
|
||||
</Link>
|
||||
</span>
|
||||
<span>
|
||||
{
|
||||
author && author.login === item.login ?
|
||||
<label>{operation && operation[0].name}</label>
|
||||
:
|
||||
<Dropdown overlay={menu(`${item.id}`)} placement={"bottomCenter"}>
|
||||
<span>{operation && operation[0].name}<Icon type="down" /></span>
|
||||
</Dropdown>
|
||||
}
|
||||
|
||||
</span>
|
||||
<span style={{justifyContent:"center"}}>
|
||||
{
|
||||
author && author.login !== item.login &&
|
||||
<a className="red_btn" onClick={()=>this.deleteUser(item.id)}>删除</a>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
</Spin>
|
||||
|
||||
</div>
|
||||
{
|
||||
total_count && total_count > LIMIT ?
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
<Pagination showQuickJumper pageSize={LIMIT} current={page} total={total_count} onChange={this.changePage}></Pagination>
|
||||
<div className="grid-item-left baseForm">
|
||||
<Search
|
||||
placeholder="搜索项目成员..."
|
||||
enterButton="搜索"
|
||||
loading={searchSpin}
|
||||
onSearch={(value) => this.searchMember(value)}
|
||||
/>
|
||||
<Dropdown overlay={roles} placement={"bottomCenter"}>
|
||||
<a className="ml180 text-primary">
|
||||
{roleName ? roleName : "角色筛选"}
|
||||
<Icon type="caret-down" size="16"></Icon>
|
||||
</a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="collaboratorList baseForm">
|
||||
{listData ? (
|
||||
<Table
|
||||
pagination={false}
|
||||
columns={columns}
|
||||
dataSource={listData}
|
||||
rowKey={(record) => record.id}
|
||||
></Table>
|
||||
) : (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
)}
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
</Spin>
|
||||
{total_count && total_count > LIMIT ? (
|
||||
<div className="edu-txt-center mt20 mb20">
|
||||
<Pagination
|
||||
showQuickJumper
|
||||
pageSize={LIMIT}
|
||||
current={page}
|
||||
total={total_count}
|
||||
onChange={this.changePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
export default Collaborator;
|
||||
|
|
|
@ -1,67 +1,124 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link , Route , Switch } from 'react-router-dom';
|
||||
import React, { Component } from "react";
|
||||
import { Link, Route, Switch } from "react-router-dom";
|
||||
|
||||
import '../css/index.css';
|
||||
import './setting.css';
|
||||
import "../css/index.css";
|
||||
import "./setting.css";
|
||||
|
||||
import Loadable from 'react-loadable';
|
||||
import Loading from '../../Loading';
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../../Loading";
|
||||
|
||||
const Branch = Loadable({
|
||||
loader: () => import('./Branch'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Setting = Loadable({
|
||||
loader: () => import('./Setting'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Collaborator = Loadable({
|
||||
loader: () => import('./Collaborator'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Tags = Loadable({
|
||||
loader: () => import('./new_tags'),
|
||||
loader: () => import("./Branch"),
|
||||
loading: Loading,
|
||||
})
|
||||
class Index extends Component{
|
||||
render(){
|
||||
});
|
||||
const Setting = Loadable({
|
||||
loader: () => import("./Setting"),
|
||||
loading: Loading,
|
||||
});
|
||||
const Collaborator = Loadable({
|
||||
loader: () => import("./Collaborator"),
|
||||
loading: Loading,
|
||||
});
|
||||
const Tags = Loadable({
|
||||
loader: () => import("./new_tags"),
|
||||
loading: Loading,
|
||||
});
|
||||
class Index extends Component {
|
||||
render() {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { pathname } = this.props.history.location;
|
||||
|
||||
const flag = (pathname === `/projects/${projectsId}/setting`);
|
||||
return(
|
||||
<div>
|
||||
<ul className="settingNav">
|
||||
<li className={flag?"active":""}><Link to={`/projects/${projectsId}/setting`}>仓库</Link></li>
|
||||
<li className={pathname.indexOf('setting/collaborator')>-1?"active":""}><Link to={`/projects/${projectsId}/setting/collaborator`}>协作者</Link></li>
|
||||
<li className={pathname.indexOf('setting/tags')>-1?"active":""}><Link to={`/projects/${projectsId}/setting/tags`}>项目标签</Link></li>
|
||||
{/* <li className={pathname.indexOf('setting/branch')>-1?"active":""}><Link to={`/projects/${projectsId}/setting/branch`}>分支列表</Link></li> */}
|
||||
</ul>
|
||||
<div className="main">
|
||||
<Switch {...this.props}>
|
||||
{/* 协作者 */}
|
||||
<Route path="/projects/:projectsId/setting/collaborator"
|
||||
render={
|
||||
(props) => (<Collaborator {...this.props} {...props} {...this.state}/>)
|
||||
const flag = pathname === `/projects/${projectsId}/setting`;
|
||||
return (
|
||||
<div className="ProjectListIndex">
|
||||
<div className="list-left">
|
||||
<ul className="list-l-Menu">
|
||||
<li className={flag ? "active" : ""}>
|
||||
<p>
|
||||
<Link to={`/projects/${projectsId}/setting`} className="w-100">
|
||||
|
||||
<i className="iconfont icon-huabanfuben font-18 mr10"></i>基本设置
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
<li
|
||||
className={
|
||||
pathname.indexOf("setting/collaborator") > -1 ? "active" : ""
|
||||
}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
<Route path="/projects/:projectsId/setting/tags"
|
||||
render={
|
||||
(props) => (<Tags {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
<Route path="/projects/:projectsId/setting"
|
||||
render={
|
||||
(props) => (<Setting {...this.props} {...props} {...this.state}/>)
|
||||
>
|
||||
<p>
|
||||
<Link to={`/projects/${projectsId}/setting/collaborator`} className="w-100">
|
||||
<i className="iconfont icon-chengyuan font-18 mr10"></i>
|
||||
协作者管理
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
<li
|
||||
className={
|
||||
pathname.indexOf("setting/branch") > -1 ? "active" : ""
|
||||
}
|
||||
></Route>
|
||||
>
|
||||
<p>
|
||||
<Link to={`/projects/${projectsId}/setting/branch`} className="w-100">
|
||||
<i className="iconfont icon-fenzhi font-20 mr10"></i>
|
||||
分支设置
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
<li
|
||||
className={pathname.indexOf("setting/tags") > -1 ? "active" : ""}
|
||||
>
|
||||
<p>
|
||||
<Link to={`/projects/${projectsId}/setting/tags`} className="w-100">
|
||||
<i className="iconfont icon-biaoqian3 font-18 mr10"></i>
|
||||
项目标签
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
</Switch>
|
||||
<li
|
||||
className={
|
||||
pathname.indexOf("setting/hooks") > -1 ? "active" : ""
|
||||
}
|
||||
>
|
||||
<p>
|
||||
<Link to={`/projects/${projectsId}/setting/hooks`} className="w-100">
|
||||
<i className="iconfont icon-zhongqingdianxinicon10 font-18 mr10"></i>
|
||||
管理Web钩子
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="list-right">
|
||||
<div>
|
||||
<Switch {...this.props}>
|
||||
{/* 协作者 */}
|
||||
<Route
|
||||
path="/projects/:projectsId/setting/collaborator"
|
||||
render={(props) => (
|
||||
<Collaborator {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
<Route
|
||||
path="/projects/:projectsId/setting/tags"
|
||||
render={(props) => (
|
||||
<Tags {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
<Route
|
||||
path="/projects/:projectsId/setting"
|
||||
render={(props) => (
|
||||
<Setting {...this.props} {...props} {...this.state} />
|
||||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
export default Index;
|
||||
export default Index;
|
||||
|
|
|
@ -1,196 +1,212 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Form , Input , Checkbox , Select } from 'antd';
|
||||
import React, { Component } from "react";
|
||||
import { Form, Input, Checkbox, Select } from "antd";
|
||||
|
||||
import axios from 'axios';
|
||||
import axios from "axios";
|
||||
const { TextArea } = Input;
|
||||
const { Option } = Select;
|
||||
class Setting extends Component{
|
||||
constructor(props){
|
||||
class Setting extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
CategoryList:undefined,
|
||||
LanguageList:undefined,
|
||||
private_check:undefined
|
||||
}
|
||||
this.state = {
|
||||
CategoryList: undefined,
|
||||
LanguageList: undefined,
|
||||
private_check: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
componentDidMount = () => {
|
||||
this.getCategory();
|
||||
this.getLanguage();
|
||||
this.getInfo();
|
||||
}
|
||||
getLanguage=()=>{
|
||||
const url = `/project_languages.json`
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
let LanguageList = this.setOptionsList(result.data.project_languages)
|
||||
this.setState({
|
||||
LanguageList
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
};
|
||||
getLanguage = () => {
|
||||
const url = `/project_languages.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
let LanguageList = this.setOptionsList(result.data.project_languages);
|
||||
this.setState({
|
||||
LanguageList,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {});
|
||||
};
|
||||
|
||||
getInfo=()=>{
|
||||
getInfo = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/repositories/${projectsId}/edit.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.props.form.setFieldsValue({
|
||||
...result.data
|
||||
})
|
||||
this.setState({
|
||||
private_check:result.data.private
|
||||
})
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
getCategory=()=>{
|
||||
const url = `/project_categories.json`
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
let CategoryList = this.setOptionsList(result.data.project_categories)
|
||||
this.setState({
|
||||
CategoryList
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
|
||||
setOptionsList = (data) =>{
|
||||
let list = undefined;
|
||||
if(data && data.length > 0){
|
||||
list = data.map((item,key)=>{
|
||||
return(
|
||||
<Option key={item.id} value={item.id}>{item.name}</Option>
|
||||
)
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.form.setFieldsValue({
|
||||
...result.data,
|
||||
});
|
||||
this.setState({
|
||||
private_check: result.data.private,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
getCategory = () => {
|
||||
const url = `/project_categories.json`;
|
||||
axios
|
||||
.get(url)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
let CategoryList = this.setOptionsList(
|
||||
result.data.project_categories
|
||||
);
|
||||
this.setState({
|
||||
CategoryList,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {});
|
||||
};
|
||||
|
||||
setOptionsList = (data) => {
|
||||
let list = undefined;
|
||||
if (data && data.length > 0) {
|
||||
list = data.map((item, key) => {
|
||||
return (
|
||||
<Option key={item.id} value={item.id}>
|
||||
{item.name}
|
||||
</Option>
|
||||
);
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
};
|
||||
|
||||
// 更新仓库设置
|
||||
resetSetting=()=>{
|
||||
this.props.form.validateFields((err,values)=>{
|
||||
if(!err){
|
||||
resetSetting = () => {
|
||||
this.props.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
const { project_id } = this.props;
|
||||
const { private_check } = this.state;
|
||||
const url = `/projects/${project_id}.json`;
|
||||
axios.put(url,{
|
||||
name:values.project_name,
|
||||
description:values.project_description,
|
||||
private:private_check,
|
||||
...values
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification(`仓库信息修改成功!`);
|
||||
const { getDetail } = this.props;
|
||||
getDetail && getDetail();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
axios
|
||||
.put(url, {
|
||||
name: values.project_name,
|
||||
description: values.project_description,
|
||||
private: private_check,
|
||||
...values,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.showNotification(`仓库信息修改成功!`);
|
||||
const { getDetail } = this.props;
|
||||
getDetail && getDetail();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 删除本仓库
|
||||
deleteProject=()=>{
|
||||
deleteProject = () => {
|
||||
this.props.confirm({
|
||||
content:"删除后无法恢复,是否确认删除本仓库?",
|
||||
onOk:()=>{
|
||||
content: "删除后无法恢复,是否确认删除本仓库?",
|
||||
onOk: () => {
|
||||
const { project_id } = this.props;
|
||||
const url = `/projects/${project_id}.json`;
|
||||
axios.delete(url).then(result=>{
|
||||
this.props.showNotification("仓库删除成功!");
|
||||
this.props.history.push("/projects");
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
changePrivate=(e)=>{
|
||||
axios
|
||||
.delete(url)
|
||||
.then((result) => {
|
||||
this.props.showNotification("仓库删除成功!");
|
||||
this.props.history.push("/projects");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
changePrivate = (e) => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
private_check:e.target.checked
|
||||
})
|
||||
}
|
||||
private_check: e.target.checked,
|
||||
});
|
||||
};
|
||||
|
||||
render(){
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const { CategoryList , LanguageList , private_check } = this.state;
|
||||
return(
|
||||
const { CategoryList, LanguageList, private_check } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<div className="normalBox">
|
||||
<div className="normalBox-title font-16">
|
||||
基本设置
|
||||
</div>
|
||||
<div className="normalBox-title font-16">基本设置</div>
|
||||
<Form className="baseForm">
|
||||
<Form.Item
|
||||
label="项目名称"
|
||||
>
|
||||
{getFieldDecorator('project_name', {
|
||||
rules: [{
|
||||
required: true, message: '请输入项目名称'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="请输入项目名称"/>
|
||||
)}
|
||||
</Form.Item >
|
||||
<div className="df" style={{alignItems:"center"}}>
|
||||
<Form.Item label="项目名称">
|
||||
{getFieldDecorator("project_name", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入项目名称",
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="请输入项目名称" />)}
|
||||
</Form.Item>
|
||||
<div className="df" style={{ alignItems: "center" }}>
|
||||
<span className="mr20 mb15 font-16">可见性</span>
|
||||
<Form.Item
|
||||
label=""
|
||||
>
|
||||
{getFieldDecorator('private', {
|
||||
<Form.Item label="">
|
||||
{getFieldDecorator("private", {
|
||||
rules: [],
|
||||
})(
|
||||
<Checkbox checked={private_check} onChange={this.changePrivate}>将仓库设为私有</Checkbox>
|
||||
<Checkbox
|
||||
checked={private_check}
|
||||
onChange={this.changePrivate}
|
||||
>
|
||||
将仓库设为私有
|
||||
</Checkbox>
|
||||
)}
|
||||
</Form.Item >
|
||||
</Form.Item>
|
||||
</div>
|
||||
<Form.Item
|
||||
label="仓库描述"
|
||||
>
|
||||
{getFieldDecorator('project_description', {
|
||||
rules: [],
|
||||
})(
|
||||
<TextArea placeholder="请输入仓库描述" style={{height:"80px"}}/>
|
||||
)}
|
||||
</Form.Item >
|
||||
<Form.Item
|
||||
label="项目类别"
|
||||
>
|
||||
{getFieldDecorator('project_category_id', {
|
||||
rules: [{
|
||||
required: true, message: '请选择大类别'
|
||||
}],
|
||||
<Form.Item label="仓库描述">
|
||||
{getFieldDecorator("project_description", {
|
||||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
{CategoryList}
|
||||
</Select>
|
||||
<TextArea
|
||||
placeholder="请输入仓库描述"
|
||||
style={{ height: "80px" }}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="项目语言"
|
||||
>
|
||||
{getFieldDecorator('project_language_id', {
|
||||
rules: [{
|
||||
required: true, message: '请选择项目语言'
|
||||
}],
|
||||
})(
|
||||
<Select>
|
||||
{LanguageList}
|
||||
</Select>
|
||||
)}
|
||||
<Form.Item label="项目类别">
|
||||
{getFieldDecorator("project_category_id", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择大类别",
|
||||
},
|
||||
],
|
||||
})(<Select>{CategoryList}</Select>)}
|
||||
</Form.Item>
|
||||
<Form.Item label="项目语言">
|
||||
{getFieldDecorator("project_language_id", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择项目语言",
|
||||
},
|
||||
],
|
||||
})(<Select>{LanguageList}</Select>)}
|
||||
</Form.Item>
|
||||
<p className="clearfix">
|
||||
<a className="submitBtn" onClick={this.resetSetting}>更新仓库设置</a>
|
||||
<a className="submitBtn" onClick={this.resetSetting}>
|
||||
更新仓库设置
|
||||
</a>
|
||||
</p>
|
||||
</Form>
|
||||
</div>
|
||||
|
@ -199,14 +215,19 @@ class Setting extends Component{
|
|||
<div className="flex-a-center padding15-10">
|
||||
<div>
|
||||
<p className="font-bd font-16">删除本仓库</p>
|
||||
<p className="mt10">删除仓库是永久性的, 无法撤消,且删除后,与仓库关联的项目/任务/合并请求/版本发布等,均会被删除</p>
|
||||
<p className="mt10">
|
||||
删除仓库是永久性的,
|
||||
无法撤消,且删除后,与仓库关联的项目/任务/合并请求/版本发布等,均会被删除
|
||||
</p>
|
||||
</div>
|
||||
<a onClick={this.deleteProject} className="red_deleteBtn">删除本仓库</a>
|
||||
<a onClick={this.deleteProject} className="red_deleteBtn">
|
||||
删除本仓库
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
const WrappedSettingIndexForm = Form.create({ name: 'settingForm' })(Setting);
|
||||
export default WrappedSettingIndexForm;
|
||||
const WrappedSettingIndexForm = Form.create({ name: "settingForm" })(Setting);
|
||||
export default WrappedSettingIndexForm;
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
.addPanel{
|
||||
display: flex;
|
||||
padding:15px;
|
||||
/* padding:15px; */
|
||||
}
|
||||
.red_btn{
|
||||
display: block;
|
||||
|
@ -101,4 +101,17 @@
|
|||
}
|
||||
.padding15-10{
|
||||
padding:15px 10px;
|
||||
}
|
||||
}
|
||||
.w-100{width: 100%;}
|
||||
.fwb{font-weight: 600;}
|
||||
.text-black{color: #333;}
|
||||
.bbr{border-bottom: 1px solid #f6f6f6;}
|
||||
.ant-input-group-addon{border: 0 !important;}
|
||||
.grid-item-left{display: grid; align-items: center; grid-template-columns: 1fr max-content;}
|
||||
.text-primary{color: #1890ff !important;}
|
||||
.ant-dropdown-menu{min-width: 90px ; text-align: center !important;}
|
||||
.text-green{color: #28BD6C !important;}
|
||||
.text-yellow{color: #FF6E21 !important;}
|
||||
.text-delete{color: #BBBBBB; }
|
||||
.text-delete:hover{color: #db2828; }
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Spin, Pagination } from "antd";
|
||||
import "./list.css";
|
||||
import NoneData from "../Nodata";
|
||||
import FocusButton from "./focus_button";
|
||||
class CommonUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
user_type: this.props.user_type,
|
||||
type_title: this.props.type_title,
|
||||
project_id: this.props.project_id,
|
||||
users: null,
|
||||
count: 0,
|
||||
limit: 20,
|
||||
page: 1,
|
||||
isSpin: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.getUsersList();
|
||||
};
|
||||
|
||||
getUsersList = (page, limit) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
const { user_type, project_id } = this.state;
|
||||
|
||||
const url = `/projects/${project_id}/${user_type}.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
page,
|
||||
limit,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
count: result.data.count,
|
||||
users: result.data.users,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 翻页
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page,
|
||||
isSpin: true,
|
||||
});
|
||||
const { limit } = this.state;
|
||||
this.getUsersList(page, limit);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { users, count, page, limit, isSpin, type_title } = this.state;
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
{count > limit ? (
|
||||
<div className="mt50 mb30 edu-txt-center">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={page}
|
||||
total={count}
|
||||
pageSize={limit}
|
||||
onChange={this.ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
const renderList = () => {
|
||||
if (users && users.length > 0) {
|
||||
return users.map((item, key) => {
|
||||
return (
|
||||
<div className="w-25 pull-left" key={key}>
|
||||
<div className="pbt25 grid-item mlr10 border-b-line">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<img
|
||||
className="avatar-60"
|
||||
src={getImageUrl(`images/${item.image_url}`)}
|
||||
alt=""
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml12">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="font-16 text-primary hide-1 task-hide max-w-200"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="font-12 text-gray grid-item pb5">
|
||||
<i className="iconfont icon-shijian user-join-time"></i>
|
||||
<span className="ml4">加入时间:{item.format_time}</span>
|
||||
</div>
|
||||
<FocusButton is_watch={item.is_watch} id={item.login} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="background-g pbt15">
|
||||
<div className="main background-f">
|
||||
<div className="plr-20 user-list-items">
|
||||
<div className="font-18 pb-10 border-b-line">{type_title}</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="w-100 inline-block">
|
||||
{count === 0 ? (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
) : (
|
||||
renderList()
|
||||
)}
|
||||
</div>
|
||||
</Spin>
|
||||
{Paginations}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CommonUsers;
|
|
@ -0,0 +1,73 @@
|
|||
import React, { Component } from "react";
|
||||
import axios from "axios";
|
||||
import { Spin, Button } from "antd";
|
||||
import "./list.css";
|
||||
|
||||
class FocusButton extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
is_watch: false,
|
||||
id: "",
|
||||
isSpin: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.set_watch();
|
||||
};
|
||||
|
||||
set_watch = () => {
|
||||
this.setState({
|
||||
is_watch: this.props.is_watch,
|
||||
id: this.props.id,
|
||||
isSpin: false,
|
||||
});
|
||||
};
|
||||
|
||||
// 关注和取消关注
|
||||
focusFunc = (flag) => {
|
||||
const { id } = this.state;
|
||||
this.setState({ isSpin: true });
|
||||
axios({
|
||||
method: flag ? "delete" : "post",
|
||||
url: `/watchers/${flag ? "unfollow" : "follow"}.json`,
|
||||
params: {
|
||||
target_type: "user",
|
||||
id: id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.setState({
|
||||
is_watch: result.data.watched,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { is_watch, isSpin } = this.state;
|
||||
return (
|
||||
<Button loading={isSpin} onClick={() => this.focusFunc(is_watch)}>
|
||||
{is_watch ? (
|
||||
<span className="">
|
||||
<i className="iconfont icon-shixing font-15 text-yellow mr-4"></i>
|
||||
<span className="font-12">已关注</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="">
|
||||
<i className="iconfont icon-kongxing font-15"></i>
|
||||
<span className="font-12">关注</span>
|
||||
</span>
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default FocusButton;
|
|
@ -0,0 +1,144 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Spin, Pagination } from "antd";
|
||||
import "./list.css";
|
||||
import NoneData from "../Nodata";
|
||||
// import FocusButton from "./focus_button";
|
||||
class ForkUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
users: null,
|
||||
count: 0,
|
||||
limit: 20,
|
||||
page: 1,
|
||||
isSpin: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.getUsersList();
|
||||
};
|
||||
|
||||
getUsersList = (page, limit) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const url = `/projects/${projectsId}/fork_users.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
page,
|
||||
limit,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
count: result.data.count,
|
||||
users: result.data.users,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 翻页
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page,
|
||||
isSpin: true,
|
||||
});
|
||||
const { limit } = this.state;
|
||||
this.getUsersList(page, limit);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { users, count, page, limit, isSpin } = this.state;
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
{count > limit ? (
|
||||
<div className="mt50 mb30 edu-txt-center">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={page}
|
||||
total={count}
|
||||
pageSize={limit}
|
||||
onChange={this.ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
const renderList = () => {
|
||||
if (users && users.length > 0) {
|
||||
return users.map((item, key) => {
|
||||
return (
|
||||
<div className="w-25 pull-left" key={key}>
|
||||
<div className="pbt25 grid-item mlr10 border-b-line">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<img
|
||||
className="avatar-60"
|
||||
src={getImageUrl(`images/${item.image_url}`)}
|
||||
alt=""
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml12">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="font-16 text-primary hide-1 task-hide max-w-200"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="font-12 text-gray grid-item pb5">
|
||||
<i className="iconfont icon-shijian user-join-time"></i>
|
||||
<span className="ml4">fork时间:{item.format_time}</span>
|
||||
</div>
|
||||
{/* <FocusButton is_watch={item.is_watch} id={item.login} /> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="background-g pbt15">
|
||||
<div className="main background-f">
|
||||
<div className="plr-20 user-list-items">
|
||||
<div className="font-18 pb-10 border-b-line">Fork列表</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="w-100 inline-block">
|
||||
{count === 0 ? (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
) : (
|
||||
renderList()
|
||||
)}
|
||||
</div>
|
||||
</Spin>
|
||||
{Paginations}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ForkUsers;
|
|
@ -0,0 +1,101 @@
|
|||
.background-f {
|
||||
background: #fff;
|
||||
}
|
||||
.newMain{background: transparent!important;}
|
||||
.background-g {
|
||||
background: #fafafa;
|
||||
}
|
||||
.pt-15 {
|
||||
padding-top: 15px;
|
||||
}
|
||||
.mr-4{margin-right: 4px;}
|
||||
.pb-10 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.plr-20 {
|
||||
padding: 0 20px;
|
||||
}
|
||||
.font-18 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.font-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
.font-15 {
|
||||
font-size: 15px;
|
||||
}
|
||||
.border-b-line {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.list-item {
|
||||
width: 100%;
|
||||
}
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
.w-25 {
|
||||
width: 25%;
|
||||
}
|
||||
.p-10 {
|
||||
padding: 10px;
|
||||
}
|
||||
.pd-105 {
|
||||
padding: 15px 10px;
|
||||
}
|
||||
.grid-item {
|
||||
display: grid !important;
|
||||
align-items: center;
|
||||
grid-template-columns: max-content 1fr;
|
||||
}
|
||||
.avatar-60 {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.text-primary {
|
||||
color: #5091ff !important;
|
||||
}
|
||||
.text-primary:hover {
|
||||
color: #2878ff !important;
|
||||
}
|
||||
.text-yellow{
|
||||
color: #FFA802 !important
|
||||
}
|
||||
.text-gray {
|
||||
color: #888888;
|
||||
}
|
||||
.ml12 {
|
||||
margin-left: 12px;
|
||||
}
|
||||
.user-join-time {
|
||||
font-size: 14px !important;
|
||||
color: #60b25e;
|
||||
}
|
||||
.btn-cir-grey {
|
||||
background: rgba(250, 250, 250, 1);
|
||||
color: #888888;
|
||||
font-weight: normal;
|
||||
border: 1px solid rgba(238, 238, 238, 1);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.wd-75 {
|
||||
width: 75px;
|
||||
}
|
||||
.pbt15 {
|
||||
padding: 15px 0;
|
||||
}
|
||||
.pbt25 {
|
||||
padding: 25px 0;
|
||||
}
|
||||
.mlr10 {
|
||||
margin: 0 15px;
|
||||
}
|
||||
.user-list-items {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.max-w-200{max-width: 200px;}
|
||||
.inline-block{display: inline-block;}
|
|
@ -0,0 +1,32 @@
|
|||
import React, { Component } from "react";
|
||||
import CommonUsers from "./common_users"
|
||||
class PraiseUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
projectId: null
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.get_projectId();
|
||||
};
|
||||
|
||||
get_projectId = () => {
|
||||
this.setState({
|
||||
projectId: this.props.match.params.projectsId
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
const { projectId } = this.state;
|
||||
return (
|
||||
<div>
|
||||
{projectId && <CommonUsers user_type="praise_users" type_title="点赞列表" project_id={projectId} />}
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PraiseUsers;
|
|
@ -0,0 +1,32 @@
|
|||
import React, { Component } from "react";
|
||||
import CommonUsers from "./common_users"
|
||||
class WatchUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
projectId: null
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.get_projectId();
|
||||
};
|
||||
|
||||
get_projectId = () => {
|
||||
this.setState({
|
||||
projectId: this.props.match.params.projectsId
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
const { projectId } = this.state;
|
||||
return (
|
||||
<div>
|
||||
{projectId && <CommonUsers user_type="watch_users" type_title="关注列表" project_id={projectId} />}
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default WatchUsers;
|
|
@ -112,4 +112,4 @@ ul,ol,dl{
|
|||
.normal{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -921,6 +921,9 @@ class NewHeader extends Component {
|
|||
</img>
|
||||
</a>
|
||||
<ul className="edu-menu-list" style={{ top: '46px', 'textAlign': 'center' }}>
|
||||
<li className="bor-bottom-greyE">
|
||||
<a href="javascript:void(0)" className="fs12 hide-1 task-hide edu-txt-w80">{user.username}</a>
|
||||
</li>
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.edit_account &&
|
||||
<li><a href={`${mygetHelmetapi2.new_course.edit_account}`} target="_blank">修改资料</a></li>
|
||||
|
|
Loading…
Reference in New Issue