forked from Gitlink/forgeplus-react
279 lines
7.5 KiB
JavaScript
279 lines
7.5 KiB
JavaScript
import React, { useEffect, useState } from 'react';
|
||
import { Dropdown, Menu, Icon , Input , Spin , Table , Tooltip , Pagination , Popconfirm } from "antd";
|
||
import axios from 'axios';
|
||
import NoneData from "../Nodata";
|
||
import { Link } from "react-router-dom";
|
||
import { getImageUrl } from "educoder";
|
||
|
||
const { Search } = Input;
|
||
const LIMIT = 15;
|
||
const MENU_LIST = [
|
||
{id: "Manager",name: "管理员"},
|
||
{id: "Developer",name: "开发者"},
|
||
{id: "Reporter",name: "报告者"}
|
||
];
|
||
function CollaboratorMember({projectsId,owner,project_id,author,showNotification,newId}){
|
||
const [ roleName , setRoleName ] = useState(undefined);
|
||
const [ search , setSearch ] = useState(undefined);
|
||
const [ page , setPage ] = useState(1);
|
||
const [ isSpin , setIsSpin ] = useState(true);
|
||
const [ role , setRole ] = useState(undefined);
|
||
const [ listData , setListData ] = useState(undefined);
|
||
const [ total , setTotal ] = useState(0);
|
||
useEffect(()=>{
|
||
if(newId){
|
||
addCollaborator(newId);
|
||
}
|
||
},[newId])
|
||
// 增加协作者
|
||
function addCollaborator(id){
|
||
if(id){
|
||
const url = `/${owner}/${projectsId}/collaborators.json`;
|
||
axios.post(url, {
|
||
user_id:id,
|
||
})
|
||
.then((result) => {
|
||
if (result) {
|
||
getMember();
|
||
}
|
||
})
|
||
.catch((error) => {});
|
||
}
|
||
};
|
||
|
||
useEffect(()=>{
|
||
if(project_id && projectsId && owner) {
|
||
getMember();
|
||
}
|
||
},[project_id,search,page,role])
|
||
|
||
// 获取项目协作者
|
||
function getMember(){
|
||
setIsSpin(true);
|
||
const url = `/${owner}/${projectsId}/collaborators.json`;
|
||
axios.get(url, {
|
||
params: {
|
||
page,search,role,limit: LIMIT,
|
||
},
|
||
})
|
||
.then((result) => {
|
||
if (result) {
|
||
if(page > 1 && ( listData && listData.length === 1)){
|
||
setPage(page-1);
|
||
}else{
|
||
setListData(result.data.members);
|
||
setTotal(result.data.total_count);
|
||
}
|
||
setIsSpin(false);
|
||
}
|
||
})
|
||
.catch((error) => {setIsSpin(false);});
|
||
};
|
||
|
||
function orderMember(id, name){
|
||
setRole(id);
|
||
setRoleName(name);
|
||
};
|
||
const roles = (id) => (
|
||
<Menu>
|
||
<Menu.Item
|
||
key={0}
|
||
value={undefined}
|
||
onClick={(e) => orderMember(undefined, "角色筛选")}
|
||
>
|
||
全部
|
||
</Menu.Item>
|
||
{MENU_LIST.map((item, key) => {
|
||
return (
|
||
<Menu.Item
|
||
key={item.id}
|
||
value={item.id}
|
||
onClick={(e) => orderMember(item.id, item.name)}
|
||
>
|
||
{item.name}
|
||
</Menu.Item>
|
||
);
|
||
})}
|
||
</Menu>
|
||
);
|
||
|
||
// 修改权限
|
||
function changeOperaiton(e, id){
|
||
const url = `/${owner}/${projectsId}/collaborators/change_role.json`;
|
||
axios.put(url, {
|
||
user_id: id,
|
||
role: e.key,
|
||
}).then((result) => {
|
||
if (result) {
|
||
showNotification("权限修改成功!");
|
||
getMember();
|
||
}
|
||
})
|
||
.catch((error) => {});
|
||
};
|
||
// 删除协作者
|
||
function deleteUser(id){
|
||
const url = `/${owner}/${projectsId}/collaborators/remove.json`;
|
||
axios.delete(url, {
|
||
data: {user_id: id,},
|
||
})
|
||
.then((result) => {
|
||
if (result) {
|
||
showNotification("成员删除成功!");
|
||
getMember();
|
||
}
|
||
}).catch((error) => {});
|
||
};
|
||
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 get_color = (role) => {
|
||
if (role === "Manager") {
|
||
return "text-green";
|
||
} else if (role === "Developer") {
|
||
return "text-primary";
|
||
} else {
|
||
return "text-yellow";
|
||
}
|
||
};
|
||
const setRoles = (id) => (
|
||
<Menu>
|
||
{MENU_LIST.map((item, key) => {
|
||
return (
|
||
<Menu.Item
|
||
key={item.id}
|
||
value={item.id}
|
||
onClick={(e) => changeOperaiton(e,id)}
|
||
>
|
||
{item.name}
|
||
</Menu.Item>
|
||
);
|
||
})}
|
||
</Menu>
|
||
);
|
||
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 columns = [
|
||
{
|
||
title: "头像",
|
||
dataIndex: "image_url",
|
||
render: (text, item) => (
|
||
<span className="f-wrap-alignCenter">
|
||
<Link
|
||
to={`/users/${item.login}`}
|
||
className="show-user-link"
|
||
>
|
||
<img
|
||
src={getImageUrl(`/${text}`)}
|
||
alt=""
|
||
width="32px"
|
||
height="32px"
|
||
className="mr3 radius"
|
||
/>
|
||
</Link>
|
||
</span>
|
||
),
|
||
},
|
||
{
|
||
title: "用户名",
|
||
dataIndex: "name",
|
||
render: (text, item) => (
|
||
<Link to={`/users/${item.login}`} 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 && (
|
||
<Popconfirm title="确认将此成员从项目中移除?" okText="是" cancelText="否" onConfirm={() => deleteUser(item.id)}>
|
||
<a className="text-delete">删除</a>
|
||
</Popconfirm>
|
||
)}
|
||
</span>
|
||
),
|
||
},
|
||
];
|
||
return(
|
||
<React.Fragment>
|
||
<div className="baseForm" style={{display:'flex',justifyContent:"space-between",alignItems:"center"}}>
|
||
<Dropdown overlay={roles} placement={"bottomCenter"}>
|
||
<a className="text-primary">
|
||
{roleName || "角色筛选"}
|
||
<Icon type="caret-down" size="16"></Icon>
|
||
</a>
|
||
</Dropdown>
|
||
<Search
|
||
placeholder="搜索项目成员..."
|
||
enterButton="搜索"
|
||
onSearch={setSearch}
|
||
style={{width:300}}
|
||
/>
|
||
</div>
|
||
<Spin spinning={isSpin}>
|
||
<div className="collaboratorList baseForm">
|
||
{ listData && listData.length>0 &&
|
||
<Table
|
||
pagination={false}
|
||
columns={columns}
|
||
dataSource={listData}
|
||
rowKey={(record) => record.id}
|
||
></Table>
|
||
}
|
||
{ listData && listData.length === 0 && <NoneData _html="暂时还没有相关数据!" />}
|
||
</div>
|
||
</Spin>
|
||
{total > LIMIT ?
|
||
<div className="edu-txt-center mt20 pb20">
|
||
<Pagination
|
||
simple
|
||
pageSize={LIMIT}
|
||
current={page}
|
||
total={total}
|
||
onChange={(page)=>setPage(page)}
|
||
></Pagination>
|
||
</div>
|
||
:""}
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
export default CollaboratorMember; |