forgeplus-react/src/forge/Settings/CollaboratorMember.jsx

277 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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

import React, { useEffect, useState } 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(undefined);
const [ isSpin , setIsSpin ] = useState(false);
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) {
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(`images/${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 mb20">
<Pagination
showQuickJumper
pageSize={LIMIT}
current={page}
total={total}
onChange={()=>setPage(page)}
></Pagination>
</div>
:""}
</React.Fragment>
)
}
export default CollaboratorMember;