forked from Gitlink/forgeplus-react
邀请用户链接页面
This commit is contained in:
parent
c30e229f73
commit
cb241bece3
|
@ -80,7 +80,7 @@ function AddMember({getID,login,showNotification}){
|
|||
<AutoComplete
|
||||
dataSource={source}
|
||||
value={searchKey}
|
||||
style={{ width: 300 }}
|
||||
style={{ width: 250 }}
|
||||
onChange={changeInputUser}
|
||||
onSelect={selectInputUser}
|
||||
placeholder="搜索需要添加的用户..."
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Modal, Button } from 'antd';
|
||||
import { Base64 } from 'js-base64';
|
||||
import './index.scss';
|
||||
|
||||
function Invite({history,current_user}) {
|
||||
if(!current_user.login){
|
||||
let {pathname,search}=window.location;
|
||||
window.location.href=`/login?go_page=/${pathname}${search}`;
|
||||
}
|
||||
let inviteString=window.location.search&&window.location.search.split('?invite=')[1];
|
||||
let inviteParams=inviteString&&JSON.parse(Base64.decode(inviteString));
|
||||
console.log(inviteParams)
|
||||
const [visible, setVisible] = useState(true);
|
||||
|
||||
function accept() {
|
||||
|
||||
}
|
||||
return (
|
||||
<div className="">
|
||||
<Modal
|
||||
visible={visible}
|
||||
className="invite_development"
|
||||
title="提示"
|
||||
width="548px"
|
||||
closable={true}
|
||||
onCancel={() => setVisible(false)}
|
||||
centered
|
||||
okText={'接受'}
|
||||
cancelText={'拒绝'}
|
||||
onOk={accept}
|
||||
>
|
||||
<div className="">
|
||||
{/* <Button type="primary" onClick={accept}>接受</Button> */}
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default Invite;
|
|
@ -0,0 +1,31 @@
|
|||
.invite_development {
|
||||
height: 366px;
|
||||
background-image: linear-gradient(
|
||||
359.37deg,
|
||||
#ebf3ff 0%,
|
||||
#eff5ff 55.01%,
|
||||
#cfdeff 100%
|
||||
);
|
||||
border: 1.5px solid #ffffff;
|
||||
border-radius: 4px;
|
||||
|
||||
.ant-modal-content{
|
||||
background-color: inherit;
|
||||
}
|
||||
.ant-modal-header{
|
||||
background: inherit;
|
||||
border:0;
|
||||
}
|
||||
.ant-modal-footer {
|
||||
text-align: center;
|
||||
border: 0;
|
||||
padding-bottom: 55px;
|
||||
button {
|
||||
width: 150px;
|
||||
height: 42px;
|
||||
& + button {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -145,6 +145,10 @@ const WikiEdit = Loadable({
|
|||
loader: () => import('../Wiki/EditWiki'),
|
||||
loading: Loading,
|
||||
});
|
||||
const Invite = Loadable({
|
||||
loader: () => import('../Invite/Index'),
|
||||
loading: Loading,
|
||||
});
|
||||
/**
|
||||
* permission:Manager:管理员,Reporter:报告人员(只有读取权限),Developer:开发人员(除不能设置仓库信息外)
|
||||
*/
|
||||
|
@ -174,7 +178,7 @@ function checkPathname(projectsId, owner, pathname) {
|
|||
name = "wiki"
|
||||
} else if (url.indexOf(`/server`) > -1) {
|
||||
name = "server"
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
@ -227,12 +231,12 @@ class Detail extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
clearIssueCookies=(history)=>{
|
||||
clearIssueCookies = (history) => {
|
||||
const { pathname } = history;
|
||||
const { projectsId , owner } = this.props.match.params;
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
let currentIssue = pathname.indexOf(`/${owner}/${projectsId}/issues`) === -1;
|
||||
if (currentIssue) {
|
||||
cookie.save('states', undefined,{ expires: 0,path:`/` });
|
||||
cookie.save('states', undefined, { expires: 0, path: `/` });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,15 +308,15 @@ class Detail extends Component {
|
|||
},
|
||||
disconnected: () => {
|
||||
console.log("###### cannot connected! ######");
|
||||
},
|
||||
},
|
||||
received: data => {
|
||||
console.log(`###### ---received data--- ######`);
|
||||
console.log(data);
|
||||
if (data) {
|
||||
if(deleteFlag){
|
||||
if (deleteFlag) {
|
||||
this.props.showNotification("镜像同步成功!");
|
||||
window.location.reload();
|
||||
}else{
|
||||
} else {
|
||||
if (data.project && data.project.mirror_status === 2) {
|
||||
this.deleteProjectBack();
|
||||
}
|
||||
|
@ -326,20 +330,20 @@ class Detail extends Component {
|
|||
cable.subscriptions.consumer.disconnect();
|
||||
}
|
||||
},
|
||||
onerror:()=>{
|
||||
onerror: () => {
|
||||
console.log("###### cannot connected! ######");
|
||||
}
|
||||
});
|
||||
|
||||
this.timerChannel = setTimeout(this.reloadDetail,5000);
|
||||
this.timerChannel = setTimeout(this.reloadDetail, 5000);
|
||||
}
|
||||
|
||||
reloadDetail=()=>{
|
||||
if(this.state.firstSync||this.state.secondSync){
|
||||
reloadDetail = () => {
|
||||
if (this.state.firstSync || this.state.secondSync) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
deleteProjectBack = () => {
|
||||
const { history } = this.props;
|
||||
|
@ -464,7 +468,7 @@ class Detail extends Component {
|
|||
const url = `/${owner}/${projectsId}/forks.json`;
|
||||
axios.post(url).then(result => {
|
||||
if (result && result.data.status === 0) {
|
||||
if(result.data.message === "fork失败,你已拥有了这个项目"){
|
||||
if (result.data.message === "fork失败,你已拥有了这个项目") {
|
||||
this.props.history.push(`/${current_user && current_user.login}/${projectsId}`);
|
||||
return;
|
||||
}
|
||||
|
@ -490,7 +494,7 @@ class Detail extends Component {
|
|||
axios.post(url).then(result => {
|
||||
if (result && result.data && result.data.status === 0) {
|
||||
this.setState({
|
||||
secondSync:true
|
||||
secondSync: true
|
||||
})
|
||||
this.canvasChannel(true);
|
||||
} else {
|
||||
|
@ -530,7 +534,7 @@ class Detail extends Component {
|
|||
|
||||
const common = {
|
||||
getDetail: this.getDetail,
|
||||
getBanner:this.getBanner,
|
||||
getBanner: this.getBanner,
|
||||
changeOpenDevops: this.changeOpenDevops,
|
||||
defaultBranch
|
||||
}
|
||||
|
@ -549,7 +553,7 @@ class Detail extends Component {
|
|||
<Link to={`/${owner}/${projectsId}`} className="projectN mt6">{projectDetail && projectDetail.name}</Link>
|
||||
</div>
|
||||
{projectDetail && projectDetail.private && <span className="privateTag mt6">私有</span>}
|
||||
{ !platform && <span className="privateTag red mt6">只读</span> }
|
||||
{!platform && <span className="privateTag red mt6">只读</span>}
|
||||
</AlignTop>
|
||||
<div className="mt8">
|
||||
{
|
||||
|
@ -718,7 +722,7 @@ class Detail extends Component {
|
|||
(props) => (<Setting {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
|
||||
{/*修改里程碑*/}
|
||||
<Route path="/:owner/:projectsId/milestones/:meilid/edit"
|
||||
render={
|
||||
|
@ -758,18 +762,18 @@ class Detail extends Component {
|
|||
{/* 修改详情 edit*/}
|
||||
<Route path="/:owner/:projectsId/issues/:orderId/edit"
|
||||
render={
|
||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} form_type={"edit"}/>)
|
||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} form_type={"edit"} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 复制详情 copyetail*/}
|
||||
<Route path="/:owner/:projectsId/issues/:orderId/copyetail"
|
||||
render={
|
||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} form_type={"copy"}/>)
|
||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} form_type={"copy"} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* 任务详情 */}
|
||||
<Route path="/:owner/:projectsId/issues/:orderId"
|
||||
|
||||
{/* 任务详情 */}
|
||||
<Route path="/:owner/:projectsId/issues/:orderId"
|
||||
render={
|
||||
(props) => (<OrderDetail {...this.props} {...this.state} {...props} {...common} />)
|
||||
}
|
||||
|
@ -861,6 +865,12 @@ class Detail extends Component {
|
|||
(props) => (<CoderDepot {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 邀请 */}
|
||||
<Route path="/:owner/:projectsId/invite"
|
||||
render={
|
||||
(props) => (<Invite {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/:owner/:projectsId/:subIndex"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useEffect, useState , useImperativeHandle , forwardRef } from 'react';
|
||||
import { Select, Checkbox, Button , Input , Spin , Table , Tooltip , Pagination , Popconfirm } from "antd";
|
||||
import axios from 'axios';
|
||||
import React, { useEffect, useState, useImperativeHandle, forwardRef } from 'react';
|
||||
import { Select, Checkbox, Button, Input, Spin, Table, Tooltip, Pagination, Popconfirm } from "antd";
|
||||
import axios from 'axios';
|
||||
import { Base64 } from 'js-base64';
|
||||
import NoneData from "../Nodata";
|
||||
import { Link } from "react-router-dom";
|
||||
import { getImageUrl } from "educoder";
|
||||
|
@ -8,28 +9,70 @@ import { getImageUrl } from "educoder";
|
|||
const { Search } = Input;
|
||||
const LIMIT = 15;
|
||||
const optionList = [
|
||||
{value: "manager",name: "管理员 - 拥有仓库设置功能、代码库读、写操作权限"},
|
||||
{value: "developer",name: "开发人员 - 拥有代码库读、写操作权限"},
|
||||
{value: "reporter",name: "报告者 - 拥有代码库读操作权限"}
|
||||
{ value: "manager", name: "管理员 - 拥有仓库设置功能、代码库读、写操作权限" },
|
||||
{ value: "developer", name: "开发人员 - 拥有代码库读、写操作权限" },
|
||||
{ value: "reporter", name: "报告者 - 拥有代码库读操作权限" }
|
||||
];
|
||||
function CollaboratorMemberByLink({projectsId,owner,project_id,author,showNotification,newId,flag}){
|
||||
function CollaboratorMemberByLink({ projectsId, owner, project_id, author, showNotification, newId, flag }) {
|
||||
|
||||
return(
|
||||
const [role, setRole] = useState('developer');
|
||||
const [is_apply, setIs_apply] = useState(true);
|
||||
const [inviteUrl, setinviteUrl] = useState('dddd');
|
||||
const [copy,setCopy]=useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const url = `/${owner}/${projectsId}/project_invite_links/generate_link.json`;
|
||||
axios.post(url, {
|
||||
role,
|
||||
is_apply
|
||||
}).then(res => {
|
||||
if (res&&res.data) {
|
||||
console.log(res.data);
|
||||
let urlParams=JSON.stringify(res.data);
|
||||
let content=Base64.encode(urlParams);
|
||||
|
||||
setinviteUrl(`${window.location.origin}/${owner}/${projectsId}/invite?invite=${content}`);
|
||||
setCopy(false);
|
||||
}
|
||||
}).catch(error => { })
|
||||
}, [role,is_apply]);
|
||||
|
||||
function inviteClick(){
|
||||
const copyEle = document.querySelector('#inviteUrl'); // 获取要复制的节点
|
||||
if (!copyEle) {
|
||||
console.error("您的CopyTool未设置正确的inputId");
|
||||
return;
|
||||
}
|
||||
copyEle.select(); // 执行选中元素
|
||||
if (document.execCommand('copy')) {
|
||||
document.execCommand('copy');
|
||||
setCopy(true);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='addMemByLinkBox'>
|
||||
<div className='font-16 mt20 mb5'>请选择邀请用户权限</div>
|
||||
<Select className='selectBox' defaultValue="developer">
|
||||
{optionList.map(item=>{
|
||||
return <Select.Option value={item.value}>{item.name}</Select.Option>
|
||||
<div className='font-16 mt20 mb10'>请选择邀请用户权限</div>
|
||||
<Select className='selectBox' defaultValue="developer" onChange={(v) => { setRole(v) }}>
|
||||
{optionList.map(item => {
|
||||
return <Select.Option value={item.value} key={item.value}>{item.name}</Select.Option>
|
||||
})}
|
||||
</Select>
|
||||
<Checkbox className='font-15 checkBox'>是否需要管理员审核</Checkbox>
|
||||
<div className='font-16 mt10 mb5'>邀请链接</div>
|
||||
<Input addonAfter={<Button type='primary'>复制链接</Button>} className='linkBox'/>
|
||||
<div className='tipBox mt20'>
|
||||
|
||||
<Checkbox className='font-15 checkBox' onChange={e => { setIs_apply(e.target.checked) }}>是否需要管理员审核</Checkbox>
|
||||
|
||||
<div className='font-16 mt25 mb10'>邀请链接</div>
|
||||
<Input
|
||||
id="inviteUrl"
|
||||
value={inviteUrl}
|
||||
readOnly
|
||||
addonAfter={<Button type='primary' onClick={ inviteClick}>{copy?'复制成功':'复制链接'}</Button>} className='linkBox'
|
||||
/>
|
||||
<div className='tipBox mt25'>
|
||||
<div>注: </div>
|
||||
<div className='ml5'>
|
||||
1、管理员可通过分享邀请链接的方式,邀请其他成员加入项目<br/>
|
||||
2、若已勾选管理员审核选项,用户接收邀请后管理员可在个人主页中“待办事项”窗口审核成员审核信息,若不需要管理员审核,成员接收邀请后,将直接加入项目
|
||||
1、管理员可通过分享邀请链接的方式,邀请其他成员加入项目<br />
|
||||
2、若已勾选管理员审核选项,用户接收邀请后管理员可在个人主页中“待办事项”窗口审核成员审核信息,若不需要管理员审核,成员接收邀请后,将直接加入项目
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -249,7 +249,7 @@
|
|||
.selectBox {
|
||||
width: 55%;
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.checkBox{
|
||||
color:#151d40;
|
||||
|
|
|
@ -242,6 +242,7 @@ form{
|
|||
cursor: pointer;
|
||||
padding-right: 20px;
|
||||
margin:0px;
|
||||
border-bottom: 1px solid #eee;
|
||||
a{
|
||||
width:100%;
|
||||
color: #202d40;
|
||||
|
|
Loading…
Reference in New Issue