This commit is contained in:
caishi 2021-02-05 16:19:35 +08:00
parent 03cd10f599
commit 98d40482f3
14 changed files with 165 additions and 223 deletions

View File

@ -32,6 +32,8 @@ const I = styled.i`{
font-size:13px!important;
color:#60B25E;
margin-right:2px;
height:17px;
line-height:17px;
}`
const Div = styled.div`{
margin-bottom: 18px;

View File

@ -31,6 +31,7 @@ class Index extends Component {
license_id: undefined,
ignore_id: undefined,
owners_id:undefined,
owners_name:undefined,
project_language_list: undefined,
project_category_list: undefined,
@ -75,8 +76,9 @@ class Index extends Component {
this.props.form.setFieldsValue({
user_id:OIdentifier
})
this.setState({
owners_id:owner && owner[0].id
owner && this.setState({
owners_id:owner[0].id,
owners_name:owner[0].name
})
}
this.setOptionsList(owner, 'owners');
@ -159,9 +161,8 @@ class Index extends Component {
this.setState({
isSpin: true
})
const { current_user } = this.props;
const { projectsType , OIdentifier } = this.props.match.params;
const { project_language_id, project_category_id, license_id, ignore_id , owners_id } = this.state;
const { projectsType } = this.props.match.params;
const { project_language_id, project_category_id, license_id, ignore_id , owners_id , owners_name } = this.state;
const decoderPass = Base64.encode(values.password);
const url = projectsType === "deposit" ? "/projects.json" : "/projects/migrate.json";
axios.post(url, {
@ -179,7 +180,7 @@ class Index extends Component {
isSpin: false
})
this.props.showNotification(`${projectsType === "deposit" ? "托管" : "镜像"}项目创建成功!`);
this.props.history.push(`/projects/${OIdentifier ? OIdentifier :(current_user && current_user.login)}/${result.data.identifier}`);
this.props.history.push(`/projects/${owners_name}/${result.data.identifier}`);
}
}
}).catch((error) => {
@ -287,6 +288,8 @@ class Index extends Component {
{getFieldDecorator('user_id', {
rules: [{
required: true, message: '请选择拥有者'
},{
validator:(rule, value, callback) => this.checkId(rule, value, callback, OwnerList, '拥有者')
}],
})(
<AutoComplete

View File

@ -282,7 +282,7 @@ class MilepostDetail extends Component {
</div>
{
search_count > limit?
<div className="mt30 mb10 edu-txt-center">
<div className="mt30 pb30 edu-txt-center">
<Pagination simple current={page} total={search_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
</div>:""
}

View File

@ -4,19 +4,14 @@ import Modals from './Modals';
const ALink = styled.a`{
border:1px solid #F73030;
color:#F73030!important;
height:30px;
line-height:30px;
padding:0px 15px;
border-radius:5px;
}`
function LeaveTeam({teamID , onOk }){
function LeaveTeam({ teamID , onOk , className }){
const [ visible , setVisible ] = useState(false);
return(
<React.Fragment>
<ALink onClick={()=>setVisible(true)}>离开团队</ALink>
<ALink className={className} onClick={()=>setVisible(true)}>离开团队</ALink>
<Modals visible={visible} okText={"确定"} cancelText={"取消"} onCancel={()=>setVisible(false)} onOk={()=>onOk(teamID)}>
<p className="font-16 edu-txt-center">确定要离开当前团队吗</p>
</Modals>

View File

@ -31,7 +31,7 @@ export default (({projects}) => {
return (
<Div>
<Imgs src={item.project && getImageUrl(`images/${item.project.owner_image_url}`)}/>
<Link to={`/projects/${item.project.owner_name}/${item.project.name}`}>{item.project.name}</Link>
<Link to={`/projects/${item.project.owner_name}/${item.project.identifier}`}>{item.project.name}</Link>
</Div>
)
})

View File

@ -168,7 +168,7 @@ export default Form.create()(
'',
"can_create_org_project",
[],
<Checkbox checked={check_box} onChange={change_check_box_status} style={OptionStyle}>新建项目<span className="color-grey-8 ml10">(成员可以在组织中新建项目创建者将自动获得新建的项目的管理员权限)</span></Checkbox>, false
<Checkbox checked={check_box} onChange={change_check_box_status} style={OptionStyle}>新建项目<span className="color-grey-8 ml10">(成员可以在组织中新建项目创建者将自动获得新建的项目的管理员权限)</span></Checkbox>, false
)}
{helper(
'权限:',

View File

@ -202,8 +202,20 @@
justify-content: left;
}
.g-body{
padding:15px 25px;
padding:15px 15px;
min-height: 84px;
display: flex;
align-items: center;
.moreMember {
margin:0px 10px;
i{
height: 44px;
width: 44px;
line-height: 44px;
color: #ddd!important;
font-size: 44px!important;
}
}
}
}
&>div:nth-child(2n){

View File

@ -103,14 +103,6 @@ export default Form.create()(
[],
<Checkbox value="1" key={1}>项目管理员可以添加或移除团队的访问权限</Checkbox>,false
)}
{helper(
<span>最大仓库数<span className="color-grey-8">设置为-1表示使用全局默认值</span></span>,
"max_repo_creation",
[],
<InputNumber
placeholder="最大仓库数" style={{width:"100px"}}
/>,false
)}
</Form>
</div>
<p className="mt20">

View File

@ -1,113 +1,14 @@
import React , { useEffect , useState } from 'react';
import { WhiteBack , Banner , Blueline } from '../../Component/layout';
import styled from 'styled-components';
import axios from 'axios';
import { Pagination } from 'antd';
import { getImageUrl } from 'educoder';
import LeaveTeam from '../Component/LeaveTeam';
import { Link } from 'react-router-dom';
import React from 'react';
import { WhiteBack , Banner } from '../../Component/layout';
import GroupItems from '../TeamGroupItems';
const SpanName = styled.span`{
font-size:16px;
color:#333;
}`
const SpanFoot = styled.span`{
margin-right:5px;
color:#333
}`
const ImgContent = styled.img`{
height:44px;
width:44px;
border-radius:50%;
margin:5px 20px 5px 0px;
}`
const limit = 8;
function TeamSettingGroup({organizeDetail,history}){
const [ list ,setList ] = useState(undefined);
const [ page ,setPage ] = useState(1);
const [ total ,setTotal ] = useState(0);
useEffect(()=>{
if(organizeDetail){
getData();
}
},[organizeDetail,page]);
function getData(){
const url = `/organizations/${organizeDetail.id}/teams.json`;
axios.get(url,{
params:{
page,limit
}
}).then(result=>{
if(result && result.data){
setList(result.data.teams);
setTotal(result.data.total_count);
}
}).catch(error=>{})
}
//
function removeMember(teamid){
const url = `/organizations/${organizeDetail.id}/teams/${teamid}/team_users/quit.json`;
axios.delete(url).then(result=>{
if(result && result.data){
getData();
}
}).catch(error=>{})
}
//
function toGroupSetting(id){
history.push(`/organize/${organizeDetail && organizeDetail.name}/group/${id}/setting`);
}
return(
<WhiteBack>
<Banner>组织团队管理</Banner>
{
list && list.length > 0 ?
<div className="groupBox">
{
list.map((item,key)=>{
return(
<div>
<p className="g-head">
<Link to={`/organize/${organizeDetail && organizeDetail.name}/group/${item.id}`}><SpanName>{item.name}</SpanName></Link>
<span className="df">
{ item.is_member &&
<LeaveTeam teamID={item.id} onOk={removeMember}/>
}
{ item.is_admin && <Blueline className="ml15" onClick={()=>toGroupSetting(item.id)}>团队设置</Blueline> }
</span>
</p>
<div className="g-body">
{
item.users && item.users.map((i,k)=>{
return(
<Link to={`/users/${i.login}`}><ImgContent title={i.name} key={k} src={getImageUrl(`images/${i.image_url}`)}/></Link>
)
})
}
</div>
<p className="g-foot">
<SpanFoot>{item.num_users}&nbsp;名成员</SpanFoot>
<SpanFoot>{item.num_projects}&nbsp;个项目</SpanFoot>
</p>
</div>
)
})
}
</div>
:""
}
{
total > limit &&
<div className="mt20 pb20 edu-txt-center">
<Pagination current={page} total={total} simple onChange={(page)=>setPage(page)} />
</div>
}
</WhiteBack>
<GroupItems limit={limit} organizeDetail={organizeDetail} count={4} history={history}/>
</WhiteBack>
)
}
export default TeamSettingGroup;

View File

@ -1,94 +1,13 @@
import React , { useEffect , useState } from 'react';
import React from 'react';
import { Banner } from '../Component/layout';
import styled from 'styled-components';
import axios from 'axios';
import { getImageUrl } from 'educoder';
import Nodata from '../Nodata';
import { Pagination } from 'antd';
import { Link } from 'react-router-dom';
import LeaveTeam from './Component/LeaveTeam';
import GroupItems from './TeamGroupItems';
const SpanFoot = styled.span`{
margin-right:5px;
color:#333
}`
const ImgContent = styled.img`{
height:44px;
width:44px;
border-radius:50%;
margin:5px 20px 5px 0px;
}`
const limit = 14;
function TeamGroup({organizeDetail,current_user}){
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
const [ list , setList ] = useState(undefined);
useEffect(()=>{
if(organizeDetail){
getData();
}
},[organizeDetail]);
function getData(){
const url = `/organizations/${organizeDetail.id}/teams.json`;
axios.get(url,{
params:{ page ,limit}
}).then(result=>{
if(result && result.data){
setList(result.data.teams);
setTotal(result.data.total_count);
}
})
}
//
function outTeam(id){
const url = `/organizations/${organizeDetail.id}/teams/${id}/team_users/quit.json`;
axios.delete(url).then(result =>{
if(result && result.data){
getData();
}
}).catch(error=>{})
}
function TeamGroup({organizeDetail,history}){
return(
<div style={{background:"#fff",marginBottom:"30px"}}>
<Banner>组织团队</Banner>
{
list && list.length > 0 ?
<div className="groupBox">
{
list.map((item,key)=>{
return(
<div key={key}>
<p className="g-head">
<Link to={`/organize/${organizeDetail.name}/group/${item.id}`} className="color-grey-3 font-16">{item.name}</Link>
{item.is_member && <LeaveTeam teamID={item.id} onOk={outTeam}/>}
</p>
<div className="g-body">
{
item.users && item.users.map((i,k)=>{
return(
<Link to={`/users/${i.login}`}><ImgContent src={getImageUrl(`images/${i.image_url}`)} title={i.name}/></Link>
)
})
}
</div>
<p className="g-foot">
<SpanFoot>{item.num_users}&nbsp;名成员</SpanFoot>
<SpanFoot>{item.num_projects}&nbsp;个项目</SpanFoot>
</p>
</div>
)
})
}
</div>:<Nodata _html="暂无数据"/>
}
{
total > limit &&
<div className="mt20 pb20 edu-txt-center">
<Pagination simple current={page} total={total} pageSize={limit} onChange={(page)=>setPage(page)}/>
</div>
}
<GroupItems limit={limit} organizeDetail={organizeDetail} count={7} history={history}/>
</div>
)
}

View File

@ -0,0 +1,118 @@
import React , { useEffect , useState } from 'react';
import Nodata from '../Nodata';
import axios from 'axios';
import { getImageUrl } from 'educoder';
import { Pagination , Popconfirm , Spin } from 'antd';
import { Link } from 'react-router-dom';
import LeaveTeam from './Component/LeaveTeam';
import styled from 'styled-components';
const SpanFoot = styled.span`{
margin-right:5px;
color:#333
}`
const ImgContent = styled.img`{
height:44px;
width:44px;
border-radius:50%;
margin:5px 10px;
}`
function TeamGroupItems({organizeDetail,limit, count , history}){
const [ page , setPage ] = useState(1);
const [ isSpin , setIsSpin ] = useState(false);
const [ total , setTotal ] = useState(0);
const [ list , setList ] = useState(undefined);
useEffect(()=>{
if(organizeDetail){
getData();
}
},[organizeDetail]);
function getData(){
const url = `/organizations/${organizeDetail.id}/teams.json`;
axios.get(url,{
params:{ page ,limit}
}).then(result=>{
if(result && result.data){
setList(result.data.teams);
setTotal(result.data.total_count);
setIsSpin(false);
}
})
}
//
function outTeam(id){
setIsSpin(true);
const url = `/organizations/${organizeDetail.id}/teams/${id}/team_users/quit.json`;
axios.delete(url).then(result =>{
if(result && result.data){
getData();
}
}).catch(error=>{})
}
//
function toGroupSetting(id){
history.push(`/organize/${organizeDetail && organizeDetail.name}/group/${id}/setting`);
}
//
function disMissGroup(id){
setIsSpin(true);
const url = `/organizations/${organizeDetail.id}/teams/${id}.json`;
axios.delete(url).then(result=>{
if(result && result.data){
getData();
}
}).catch(error=>{})
}
return(
<Spin spinning={isSpin}>
{
list && list.length > 0 ?
<div className="groupBox">
{
list.map((item,key)=>{
return(
<div key={key}>
<p className="g-head">
<Link to={`/organize/${organizeDetail.name}/group/${item.id}`} className="color-grey-3 font-16">{item.name}</Link>
<span>
{ item.is_admin && item.authorize!=="owner" && <Popconfirm title={`确定解散团队${item.name}?`} okText="是" cancelText="否" onConfirm={()=>disMissGroup(item.id)}><a className="color-red">解散团队</a></Popconfirm>}
{ item.is_member && <LeaveTeam className="ml15" teamID={item.id} onOk={outTeam}/>}
{ item.is_admin && <a className="ml15 color-blue" onClick={()=>toGroupSetting(item.id)}>团队设置</a> }
</span>
</p>
<div className="g-body">
{
item.users && item.users.map((i,k)=>{
return(
k < count ? <Link to={`/users/${i.login}`}><ImgContent title={i.name} key={k} src={getImageUrl(`images/${i.image_url}`)}/></Link>
:
k === count ?
<Link to={`/organize/${organizeDetail && organizeDetail.name}/group/${item.id}`} className="moreMember" title="查看更多" ><i className="iconfont icon-zhunbeizhong"></i></Link>
:""
)
})
}
</div>
<p className="g-foot">
<SpanFoot>{item.num_users}&nbsp;名成员</SpanFoot>
<SpanFoot>{item.num_projects}&nbsp;个项目</SpanFoot>
</p>
</div>
)
})
}
</div>
:<Nodata _html="暂无数据"/>
}
{
total > limit &&
<div className="mt20 pb20 edu-txt-center">
<Pagination simple current={page} total={total} pageSize={limit} onChange={(page)=>setPage(page)}/>
</div>
}
</Spin>
)
}
export default TeamGroupItems;

View File

@ -1,13 +1,12 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { getImageUrl } from 'educoder';
function TeamItem({item}){
function TeamItem({item,history}){
return(
<div>
<div onClick={()=>{history.push(`/organize/${item.name}`)}} style={{cursor:"pointer"}}>
<img alt="" src={getImageUrl(`images/${item.avatar_url}`)}/>
<div style={{flex:'1'}}>
<Link to={`/organize/${item.name}`} className="mb5 font-18 color-grey-3 task-hide">{item.name}</Link>
<span className="mb5 font-18 color-grey-3 task-hide">{item.name}</span>
<div className="task-hide-2">
{item.description}
</div>

View File

@ -66,7 +66,7 @@ function Team(props){
{
list.map((item,key)=>{
return(
<Item item={item}/>
<Item item={item} history={props.history}/>
)
})
}

View File

@ -761,10 +761,11 @@ class NewHeader extends Component {
<div className="overPart"></div>
{
coursestypes === true && this.props.user && this.props.user.main_site === false ? "" :
<ul className="edu-txt-center">
<li><Link to={"/projects/mirror/new"}>新建镜像项目</Link></li>
<li><Link to={"/projects/deposit/new"}>新建托管项目</Link></li>
</ul>
<ul className="edu-txt-center">
<li><Link to={"/projects/mirror/new"}>新建镜像项目</Link></li>
<li><Link to={"/projects/deposit/new"}>新建托管项目</Link></li>
<li><Link to={"/organize/new"}>新建组织</Link></li>
</ul>
}
</div>
</div>