项目转移--整体数据绑定

This commit is contained in:
caishi 2021-04-26 14:59:19 +08:00
parent 09065383c1
commit 4e48b0b363
7 changed files with 241 additions and 103 deletions

View File

@ -25,7 +25,7 @@ if (isDev) {
}
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'student'
}
window._debugType = debugType;
export function initAxiosInterceptors(props) {

View File

@ -1,27 +1,66 @@
import React ,{ forwardRef, useEffect, useState } from 'react';
import { Modal , Form , Input , Radio , Select } from 'antd';
import './Index.scss';
import Axios from 'axios';
const { Option } = Select;
function DivertModal({form , visible , onSuccess , onCancel}){
function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
const { getFieldDecorator, validateFields , setFieldsValue } = form;
const [ cate , setCate ] = useState(0);
const [ organizations , setOrganizations ] = useState(undefined);
useEffect(()=>{
setFieldsValue({goal:cate})
},[])
useEffect(()=>{
if(owner && repo && visible===true){
getTeam();
}
},[repo,owner,visible])
function getTeam(){
const url = `/${owner}/${repo}/applied_transfer_projects/organizations.json`;
Axios.get(url).then(result=>{
if(result){
setOrganizations(result.data.organizations);
}
}).catch(error=>{})
}
//
function onOk(){
validateFields((error,values)=>{
if(!error){
onSuccess();
const url = `/${owner}/${repo}/applied_transfer_projects.json`;
Axios.post(url,{
...values
}).then(result=>{
if(result){
onSuccess();
}
}).catch(error=>{})
}
})
}
function changeType(e){
setCate(e.target.value);
setFieldsValue({
owner_name:undefined
})
}
function checkIdentifier(rule, value, callback){
if(!value){
callback();
}
if (repo && value !== repo) {
callback("请输入当前项目的标识!");
}
callback();
}
const layout = {
labelCol: { span: 5 },
wrapperCol: { span: 18 },
@ -33,7 +72,7 @@ function DivertModal({form , visible , onSuccess , onCancel}){
title="转移仓库"
onCancel={onCancel}
onOk={onOk}
okText="转移"
okText="确认转移"
cancelText={"取消"}
centered
>
@ -63,27 +102,47 @@ function DivertModal({form , visible , onSuccess , onCancel}){
</Radio.Group>
)}
</Form.Item>
<Form.Item label=" " style={{display:cate === 0 ? "block":"none"}}>
{getFieldDecorator("username",{
rules:[{required:true,message:"请输入目标用户名"}]
})(
<Input placeholder="请输入要转移的目标用户名" autoComplete={"off"}/>
)}
</Form.Item>
<Form.Item label=" " style={{display:cate ===1 ? "block" : "none"}}>
{getFieldDecorator("identitfy",
{rules:[{required:true,message:"请输入目标组织"}]}
)(
<Select placeholder="请选择要转移的目标组织" >
<Option value="组织kkk">组织kkk</Option>
<Option value="组织kkk1">组织kkk1</Option>
<Option value="组织kkk2">组织kkk2</Option>
</Select>
)}
</Form.Item>
{
cate === 0 &&
<Form.Item label=" ">
{getFieldDecorator("owner_name",{
rules:[{required:true,message:"请输入目标用户名"}]
})(
<Input placeholder="请输入目标用户" autoComplete={"off"}/>
)}
</Form.Item>
}
{
cate === 1 &&
<Form.Item label=" ">
{getFieldDecorator("owner_name",
{rules:[{required:true,message:"请选择目标组织"}]}
)(
<Select placeholder="请选择目标组织" >
{
organizations && organizations.length > 0 ?
organizations.map((i,k)=>{
return(
<Option value={i.name}>{i.nickname}</Option>
)
})
:""
}
</Select>
)}
</Form.Item>
}
<Form.Item label="仓库标识:">
{getFieldDecorator("username",
{rules:[{required:true,message:"请输入仓库标识"}]}
{getFieldDecorator("identifier",
{
rules:[
{required:true,message:"请输入仓库标识"},
{
validator:checkIdentifier
}
]
}
)(
<Input placeholder="请输入仓库标识" autoComplete={"off"}/>
)}

View File

@ -1,4 +1,5 @@
.noticeMenu{
padding:0px 20px;
.ant-menu-item{
font-size: 16px;
padding:0px;

View File

@ -1,28 +1,36 @@
import React, { useEffect, useState } from "react";
import Nodata from '../Nodata';
import { Skeleton , Pagination } from 'antd';
import {Pagination } from 'antd';
import { Link } from 'react-router-dom';
import { getImageUrl } from 'educoder';
import Axios from "axios";
let l= [
{
name:"创新使者",image_url:"system/lets/letter_avatars/2/D/169_162_140/120.png",
type:"moving",time:"几分钟前",login:"innov"
},
{
name:"创新使者",image_url:"system/lets/letter_avatars/2/D/169_162_140/120.png",
type:"moving",time:"几分钟前",login:"innov"
}
]
const limit = 15;
function Notify(props){
const username = props.match.params.username;
const [ list , setList ] = useState(undefined);
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
useEffect(()=>{
setList(l);
},[])
if(username){
getList();
}
},[username,page])
function getList(){
const url = `/users/${username}/applied_messages.json`;
Axios.get(url,{
params:{
page,per_page:limit
}
}).then(result=>{
if(result){
setList(result.data.applied_messages);
setTotal(result.data.total_count);
}
}).catch(error=>{})
}
return(
<div>
@ -34,13 +42,13 @@ function Notify(props){
list.map((i,k)=>{
return(
<li>
<Link to={`/users/${i.login}`}><img src={getImageUrl(i.image_url)} alt="" className="notifyImg"/></Link>
<Link to={`/users/${i.login}`}><img src={getImageUrl(i.applied_user && i.applied_user.image_url)} alt="" className="notifyImg"/></Link>
<div className="notifyFlex">
<p className="notifyInfos">
<Link to={`/users/${i.login}`} className="font-15 mr20">{i.name}</Link>
<span className="color-grey-9">{i.time}</span>
<Link to={`/users/${i.applied_user && i.applied_user.login}`} className="font-15 mr20">{i.applied_user && i.applied_user.name}</Link>
<span className="color-grey-9">{i.time_ago}</span>
</p>
<p>正在将仓库转移给某某某</p>
<p>{i.name}</p>
</div>
</li>
)
@ -49,9 +57,9 @@ function Notify(props){
</ul>
</div>
:
<Skeleton />
""
}
{list && list.length === 0 && <Nodata _html="暂无数组" /> }
{list && list.length === 0 && <Nodata _html="暂无数组" />}
{
total > limit &&
<div className="edu-txt-center pt20 pb20">

View File

@ -1,38 +1,57 @@
import React, { useEffect, useState } from "react";
import Nodata from '../Nodata';
import { FlexAJ } from '../Component/layout';
import { Skeleton , Pagination } from 'antd';
import { Pagination , Popconfirm } from 'antd';
import { Link } from 'react-router-dom';
import { getImageUrl } from 'educoder';
import Axios from 'axios';
let l= [
{
name:"创新使者",image_url:"system/lets/letter_avatars/2/D/169_162_140/120.png",
type:"moving",time:"几分钟前",login:"innov"
},
{
name:"创新使者",image_url:"system/lets/letter_avatars/2/D/169_162_140/120.png",
type:"moving",time:"几分钟前",login:"innov"
}
]
const limit = 15;
function UndoEvent(props){
const username = props.match.params.username;
const [ list , setList ] = useState(undefined);
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
useEffect(()=>{
setList(l);
},[])
if(username){
getList();
}
},[username,page])
function getList(){
const url = `/users/${username}/applied_transfer_projects.json`;
Axios.get(url,{
params:{
page,per_page:limit
}
}).then(result=>{
if(result){
setList(result.data.applied_transfer_projects);
setTotal(result.data.total_count);
}
}).catch(error=>{})
}
//
function acceptDivert(){
function acceptDivert(id){
const url = `/users/${username}/applied_transfer_projects/${id}/accept.json`;
Axios.post(url).then(result=>{
if(result && result.data){
getList();
}
}).catch(error=>{})
}
//
function revertDivert(){
function revertDivert(id){
const url = `/users/${username}/applied_transfer_projects/${id}/refuse.json`;
Axios.post(url).then(result=>{
if(result && result.data){
getList();
}
}).catch(error=>{})
}
return(
@ -45,18 +64,34 @@ function UndoEvent(props){
list.map((i,k)=>{
return(
<li>
<Link to={`/users/${i.login}`}><img src={getImageUrl(i.image_url)} alt="" className="notifyImg"/></Link>
<Link to={`/users/${i.user && i.user.login}`}><img src={getImageUrl(i.user && i.user.image_url)} alt="" className="notifyImg"/></Link>
<div className="notifyFlex">
<p className="notifyInfos">
<Link to={`/users/${i.login}`} className="font-15 mr20">{i.name}</Link>
<span className="color-grey-9">{i.time}</span>
<Link to={`/users/${i.login}`} className="font-15 mr20">{i.user && i.user.name}</Link>
<span className="color-grey-9">{i.time_ago}</span>
</p>
<FlexAJ>
<p>请求将仓库转移给用户名,是否接受</p>
<span>
<a className="color-grey-3" onClick={acceptDivert}>接受</a>
<a className="color-red ml20" onClick={revertDivert}>拒绝</a>
</span>
<p>请求将仓库转移给{i.owner && i.owner.name},是否接受</p>
{
i.status === "common" &&
<span>
<Popconfirm title={`确定接受仓库${i.project && i.project.name}`} okText="确定" cancelText="取消" onConfirm={()=>acceptDivert(i.id)}>
<a className="color-blue">接受</a>
</Popconfirm>
<Popconfirm title={`确定拒绝接受仓库${i.project && i.project.name}`} okText="确定" cancelText="取消" onConfirm={()=>revertDivert(i.id)}>
<a className="color-red ml20">拒绝</a>
</Popconfirm>
</span>
}
{
i.status === "canceled" && <span className="color-grey-9">对方已取消转移</span>
}
{
i.status === "accept" && <span className="color-grey-9">已接受</span>
}
{
i.status === "refused" && <span className="color-grey-9">已拒绝</span>
}
</FlexAJ>
</div>
</li>
@ -66,9 +101,9 @@ function UndoEvent(props){
</ul>
</div>
:
<Skeleton />
""
}
{list && list.length === 0 && <Nodata _html="暂无数组" /> }
{list && list.length === 0 && <Nodata _html="暂无数组" />}
{
total > limit &&
<div className="edu-txt-center pt20 pb20">

View File

@ -27,7 +27,9 @@ class Setting extends Component {
private_check: undefined,
loading:true,
project_units:['home',"activity","code"],
divertVisible:false
divertVisible:false,
is_transfering:undefined,
permission:undefined
};
}
@ -75,7 +77,9 @@ class Setting extends Component {
this.setState({
private_check: result.data.private,
loading:false,
project_units:units
project_units:units,
is_transfering:result.data.is_transfering,
permission:result.data.permission
});
}
})
@ -196,20 +200,44 @@ class Setting extends Component {
}
// 取消仓库转移
CancelDivertProject=()=>{
this.props.confirm({
content: "是否确认取消将此项目转移给他人?",
onOk: () => {
const { projectsId , owner } = this.props.match.params;
const url = `/${owner}/${projectsId}/applied_transfer_projects/cancel.json`;
axios.post(url).then(result=>{
if(result && result.data){
this.setState({
is_transfering:false
})
}
}).catch(error=>{})
},
});
}
// 确定转移仓库
onSuccess=()=>{
this.setState({
is_transfering:true,
divertVisible:false
})
}
render() {
const { getFieldDecorator } = this.props.form;
const { projectsId , owner } = this.props.match.params;
const { CategoryList, LanguageList, private_check ,loading , divertVisible } = this.state;
const { CategoryList, LanguageList, private_check ,loading , divertVisible , permission , is_transfering } = this.state;
return (
<div>
<DivertModal visible={divertVisible} onSuccess={this.onSuccess} onCancel={()=>{this.setState({divertVisible:false})}}/>
<DivertModal
owner={owner}
repo={projectsId}
visible={divertVisible}
onSuccess={this.onSuccess}
onCancel={()=>{this.setState({divertVisible:false})}}
/>
<Spin spinning={loading}>
<WhiteBack>
<Title>基本设置</Title>
@ -297,32 +325,41 @@ class Setting extends Component {
{/* 镜像设置部分,暂无接口,先不显示 */}
{/* <Mirror /> */}
</WhiteBack>
<WhiteBack className="dangerousBox mb20">
<div>
<div className="dangerousTitle">危险操作区</div>
<div className="flex-a-center padding15-10" style={{borderBottom:"1px solid #f9edbe"}}>
{
permission && (permission === "Admin" || permission === "Owner")?
<WhiteBack className="dangerousBox mb20">
<div>
<p className="font-bd font-16">转移仓库</p>
<p className="mt10">
将此仓库转移给其他用户或组织
</p>
<div className="dangerousTitle">危险操作区</div>
<div className="flex-a-center padding15-10" style={{borderBottom:"1px solid #f9edbe"}}>
<div>
<p className="font-bd font-16">转移仓库</p>
<p className="mt10">
将此仓库转移给其他用户或组织
</p>
</div>
{
is_transfering ?
<a onClick={this.CancelDivertProject} className="red_deleteBtn">取消转移</a>
:
<a onClick={this.DivertProject} className="red_deleteBtn">转移</a>
}
</div>
<div className="flex-a-center padding15-10">
<div>
<p className="font-bd font-16">删除本仓库</p>
<p className="mt10">
删除仓库是永久性的,
无法撤消且删除后与仓库关联的项目/任务/合并请求/版本发布等均会被删除
</p>
</div>
<a onClick={this.deleteProject} className="red_deleteBtn">
删除本仓库
</a>
</div>
</div>
<a onClick={this.DivertProject} className="red_deleteBtn">转移</a>
</div>
<div className="flex-a-center padding15-10">
<div>
<p className="font-bd font-16">删除本仓库</p>
<p className="mt10">
删除仓库是永久性的,
无法撤消且删除后与仓库关联的项目/任务/合并请求/版本发布等均会被删除
</p>
</div>
<a onClick={this.deleteProject} className="red_deleteBtn">
删除本仓库
</a>
</div>
</div>
</WhiteBack>
</WhiteBack>
:""
}
</Spin>
</div>
);

View File

@ -213,7 +213,7 @@ class Infos extends Component {
</div>
</div>
</div>
{current_user && user && current_user.id === user.id && (
{current_user && user && user.login === current_user.login ? (
<div className="bgcF">
<div className="list-l-Menu">
<li className={project_type && project_type === "notice" ? "active" : ""}>
@ -229,7 +229,7 @@ class Infos extends Component {
</li>
</div>
</div>
)}
):""}
<div className="bgcF">
<ul className="list-l-Menu">
@ -289,8 +289,6 @@ class Infos extends Component {
</ul>
</div>
}
<div className="bgcF">
<div className="list-l-Menu">
<li className={project_type && project_type === "organizes" ? "active" : ""}>