forked from Gitlink/forgeplus-react
转移项目-前端页面已画完
This commit is contained in:
parent
c32e215b27
commit
09065383c1
|
@ -1,8 +1,8 @@
|
|||
.ant-modal-mask{
|
||||
z-index: 10000;
|
||||
z-index: 1001;
|
||||
}
|
||||
.ant-modal-wrap{
|
||||
z-index: 10001;
|
||||
z-index: 1002;
|
||||
.ant-form-explain{
|
||||
position: absolute;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
import React ,{ forwardRef, useEffect, useState } from 'react';
|
||||
import { Modal , Form , Input , Radio , Select } from 'antd';
|
||||
import './Index.scss';
|
||||
|
||||
const { Option } = Select;
|
||||
function DivertModal({form , visible , onSuccess , onCancel}){
|
||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||
const [ cate , setCate ] = useState(0);
|
||||
|
||||
useEffect(()=>{
|
||||
setFieldsValue({goal:cate})
|
||||
},[])
|
||||
|
||||
function onOk(){
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
onSuccess();
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
function changeType(e){
|
||||
setCate(e.target.value);
|
||||
}
|
||||
const layout = {
|
||||
labelCol: { span: 5 },
|
||||
wrapperCol: { span: 18 },
|
||||
};
|
||||
return(
|
||||
<Modal
|
||||
width="620px"
|
||||
visible={visible}
|
||||
title="转移仓库"
|
||||
onCancel={onCancel}
|
||||
onOk={onOk}
|
||||
okText="转移"
|
||||
cancelText={"取消"}
|
||||
centered
|
||||
>
|
||||
<div className="diverModal">
|
||||
{
|
||||
cate === 0 ?
|
||||
<ul className="descUl">
|
||||
<li>转移需对方确认接受,转移成功后你将被移出仓库,其他已有成员权限不变</li>
|
||||
<li>转移成功后,仓库的地址将变更至目标用户的命名空间下</li>
|
||||
<li>已有成员如需继续操作仓库,需更新本地仓库的remote,使之指向新的地址</li>
|
||||
</ul>
|
||||
:
|
||||
<ul className="descUl">
|
||||
<li>仓库仅可以转移到您已经加入的组织中,不可以转移到未加入的组织中</li>
|
||||
<li>涉及到仓库改名操作,请提前做好仓库备份并且在转移后对本地仓库的remote进行修改</li>
|
||||
<li>转移仓库到组织后,你和组织创建者/管理员同时拥有对该仓库的管理操作</li>
|
||||
</ul>
|
||||
}
|
||||
<Form {...layout} colon={false} layout={"horizontal"}>
|
||||
<Form.Item label="转移给:" style={{marginBottom:"0px"}}>
|
||||
{getFieldDecorator("goal",{
|
||||
rules:[]
|
||||
})(
|
||||
<Radio.Group onChange={changeType}>
|
||||
<Radio value={0}>个人</Radio>
|
||||
<Radio value={1}>组织</Radio>
|
||||
</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>
|
||||
<Form.Item label="仓库标识:">
|
||||
{getFieldDecorator("username",
|
||||
{rules:[{required:true,message:"请输入仓库标识"}]}
|
||||
)(
|
||||
<Input placeholder="请输入仓库标识" autoComplete={"off"}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Form.create()(forwardRef(DivertModal));
|
|
@ -0,0 +1,12 @@
|
|||
.diverModal{
|
||||
.descUl{
|
||||
background-color: #fffae6;
|
||||
border-radius: 4px;
|
||||
padding:10px 15px;
|
||||
color: #efc16b;
|
||||
border:1px solid #efc16b;
|
||||
}
|
||||
.ant-form-item-required::before{
|
||||
content: "";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Menu } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import './Index.scss';
|
||||
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../../Loading";
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
|
||||
const Notify = Loadable({
|
||||
loader: () => import("./Notify"),
|
||||
loading: Loading,
|
||||
});
|
||||
const UndoEvent = Loadable({
|
||||
loader: () => import("./UndoEvent"),
|
||||
loading: Loading,
|
||||
});
|
||||
function Index(props){
|
||||
const username = props.match.params.username;
|
||||
const pathname = props.history.location.pathname;
|
||||
const [ menu , setMenu ] = useState("notify");
|
||||
|
||||
useEffect(()=>{
|
||||
if(pathname && username){
|
||||
if(pathname === `/users/${username}/notice`){
|
||||
setMenu("notify");
|
||||
}
|
||||
if(pathname === `/users/${username}/notice/undo`){
|
||||
setMenu("undo");
|
||||
}
|
||||
}
|
||||
},[pathname])
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Menu selectedKeys={[menu]} mode={"horizontal"} className="noticeMenu">
|
||||
<Menu.Item key="notify"><Link to={`/users/${username}/notice`}>通知</Link></Menu.Item>
|
||||
<Menu.Item key="undo"><Link to={`/users/${username}/notice/undo`}>接收仓库</Link></Menu.Item>
|
||||
</Menu>
|
||||
<Switch>
|
||||
<Route
|
||||
path="/users/:username/notice/undo"
|
||||
render={(p) => {
|
||||
return <UndoEvent {...props} {...p} />;
|
||||
}}
|
||||
></Route>
|
||||
<Route
|
||||
path="/users/:username/notice"
|
||||
render={(p) => {
|
||||
return <Notify {...props} {...p} />;
|
||||
}}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,36 @@
|
|||
.noticeMenu{
|
||||
.ant-menu-item{
|
||||
font-size: 16px;
|
||||
padding:0px;
|
||||
margin:0px 20px!important;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
}
|
||||
}
|
||||
.notifyList{
|
||||
padding:0px 20px;
|
||||
min-height: 400px;
|
||||
li{
|
||||
display: flex;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding:20px 0px;
|
||||
.notifyImg{
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.notifyFlex{
|
||||
flex:1;
|
||||
p{
|
||||
margin:0px;
|
||||
}
|
||||
.notifyInfos{
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
&:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import Nodata from '../Nodata';
|
||||
import { Skeleton , Pagination } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
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 [ list , setList ] = useState(undefined);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
|
||||
useEffect(()=>{
|
||||
setList(l);
|
||||
},[])
|
||||
|
||||
return(
|
||||
<div>
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<div>
|
||||
<ul className="notifyList">
|
||||
{
|
||||
list.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
<Link to={`/users/${i.login}`}><img src={getImageUrl(i.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>
|
||||
</p>
|
||||
<p>正在将仓库转移给【某某某】</p>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
:
|
||||
<Skeleton />
|
||||
}
|
||||
{list && list.length === 0 && <Nodata _html="暂无数组" /> }
|
||||
{
|
||||
total > limit &&
|
||||
<div className="edu-txt-center pt20 pb20">
|
||||
<Pagination simple pageSize={limit} total={total} current={page} onChange={(p)=>{setPage(p)}}/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Notify;
|
|
@ -0,0 +1,81 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import Nodata from '../Nodata';
|
||||
import { FlexAJ } from '../Component/layout';
|
||||
import { Skeleton , Pagination } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
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 [ list , setList ] = useState(undefined);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
|
||||
useEffect(()=>{
|
||||
setList(l);
|
||||
},[])
|
||||
|
||||
// 接受
|
||||
function acceptDivert(){
|
||||
|
||||
}
|
||||
|
||||
// 拒绝
|
||||
function revertDivert(){
|
||||
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<div>
|
||||
<ul className="notifyList">
|
||||
{
|
||||
list.map((i,k)=>{
|
||||
return(
|
||||
<li>
|
||||
<Link to={`/users/${i.login}`}><img src={getImageUrl(i.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>
|
||||
</p>
|
||||
<FlexAJ>
|
||||
<p>请求将仓库转移给【用户名】,是否接受?</p>
|
||||
<span>
|
||||
<a className="color-grey-3" onClick={acceptDivert}>接受</a>
|
||||
<a className="color-red ml20" onClick={revertDivert}>拒绝</a>
|
||||
</span>
|
||||
</FlexAJ>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
:
|
||||
<Skeleton />
|
||||
}
|
||||
{list && list.length === 0 && <Nodata _html="暂无数组" /> }
|
||||
{
|
||||
total > limit &&
|
||||
<div className="edu-txt-center pt20 pb20">
|
||||
<Pagination simple pageSize={limit} total={total} current={page} onChange={(p)=>{setPage(p)}}/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default UndoEvent;
|
|
@ -2,6 +2,7 @@ import React, { Component } from "react";
|
|||
import { Form, Input, Checkbox, Select , Spin } from "antd";
|
||||
import Title from '../Component/Title';
|
||||
import {WhiteBack} from '../Component/layout';
|
||||
import DivertModal from '../Divert/DivertModal';
|
||||
import axios from "axios";
|
||||
import "./setting.scss";
|
||||
const { TextArea } = Input;
|
||||
|
@ -25,7 +26,8 @@ class Setting extends Component {
|
|||
LanguageList: undefined,
|
||||
private_check: undefined,
|
||||
loading:true,
|
||||
project_units:['home',"activity","code"]
|
||||
project_units:['home',"activity","code"],
|
||||
divertVisible:false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -186,12 +188,28 @@ class Setting extends Component {
|
|||
});
|
||||
};
|
||||
|
||||
// 转移仓库
|
||||
DivertProject=()=>{
|
||||
this.setState({
|
||||
divertVisible:true
|
||||
})
|
||||
}
|
||||
// 取消仓库转移
|
||||
CancelDivertProject=()=>{
|
||||
|
||||
}
|
||||
// 确定转移仓库
|
||||
onSuccess=()=>{
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const { CategoryList, LanguageList, private_check ,loading } = this.state;
|
||||
const { CategoryList, LanguageList, private_check ,loading , divertVisible } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<DivertModal visible={divertVisible} onSuccess={this.onSuccess} onCancel={()=>{this.setState({divertVisible:false})}}/>
|
||||
<Spin spinning={loading}>
|
||||
<WhiteBack>
|
||||
<Title>基本设置</Title>
|
||||
|
@ -282,6 +300,15 @@ class Setting extends Component {
|
|||
<WhiteBack className="dangerousBox mb20">
|
||||
<div>
|
||||
<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>
|
||||
<a onClick={this.DivertProject} className="red_deleteBtn">转移</a>
|
||||
</div>
|
||||
<div className="flex-a-center padding15-10">
|
||||
<div>
|
||||
<p className="font-bd font-16">删除本仓库</p>
|
||||
|
|
|
@ -41,8 +41,8 @@ const FanUser = Loadable({
|
|||
loading: Loading,
|
||||
})
|
||||
|
||||
const UndoEvents = Loadable({
|
||||
loader: () => import("./undo_events"),
|
||||
const Notice = Loadable({
|
||||
loader: () => import("../Notice/Index"),
|
||||
loading: Loading,
|
||||
})
|
||||
class Infos extends Component {
|
||||
|
@ -116,9 +116,10 @@ class Infos extends Component {
|
|||
undo_link = () => {
|
||||
const {user} = this.state
|
||||
this.setState({
|
||||
route_type: undefined
|
||||
route_type: undefined,
|
||||
project_type:"notice"
|
||||
})
|
||||
this.props.history.push(`/users/${user && user.login}/undo_events`)
|
||||
this.props.history.push(`/users/${user && user.login}/notice`)
|
||||
}
|
||||
|
||||
route_link = (type) => {
|
||||
|
@ -130,7 +131,8 @@ class Infos extends Component {
|
|||
organize_link = () => {
|
||||
const {user} = this.state
|
||||
this.setState({
|
||||
route_type: undefined
|
||||
route_type: undefined,
|
||||
project_type:"organizes"
|
||||
})
|
||||
this.props.history.push(`/users/${user && user.login}/organizes`)
|
||||
}
|
||||
|
@ -211,10 +213,11 @@ class Infos extends Component {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* {current_user && user && current_user.id === user.id && (
|
||||
{current_user && user && current_user.id === user.id && (
|
||||
<div className="bgcF">
|
||||
<div className="list-l-Menu">
|
||||
<p className="list-l-p pd20" onClick={() => this.undo_link()}>
|
||||
<li className={project_type && project_type === "notice" ? "active" : ""}>
|
||||
<p onClick={() => this.undo_link()}>
|
||||
<span className="font-16 color-grey-3">
|
||||
<i className="iconfont icon-dahuizhongzuo3x font-15 mr5"></i>
|
||||
待办事项
|
||||
|
@ -223,9 +226,10 @@ class Infos extends Component {
|
|||
{user.undo_events}
|
||||
</span>
|
||||
</p>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
)} */}
|
||||
)}
|
||||
|
||||
<div className="bgcF">
|
||||
<ul className="list-l-Menu">
|
||||
|
@ -289,7 +293,8 @@ class Infos extends Component {
|
|||
|
||||
<div className="bgcF">
|
||||
<div className="list-l-Menu">
|
||||
<p className="list-l-p pd20" onClick={() => this.organize_link()} >
|
||||
<li className={project_type && project_type === "organizes" ? "active" : ""}>
|
||||
<p onClick={() => this.organize_link()} >
|
||||
<span className="font-16 color-grey-3">
|
||||
<i className="iconfont icon-itsm-liuchengguanli font-15 mr5"></i>
|
||||
组织
|
||||
|
@ -298,6 +303,7 @@ class Infos extends Component {
|
|||
{user && user.user_org_count}
|
||||
</span>
|
||||
</p>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -312,9 +318,9 @@ class Infos extends Component {
|
|||
}}
|
||||
></Route>
|
||||
<Route
|
||||
path="/users/:username/undo_events"
|
||||
path="/users/:username/notice"
|
||||
render={() => {
|
||||
return <UndoEvents {...this.props} {...this.state} />;
|
||||
return <Notice {...this.props} {...this.state} />;
|
||||
}}
|
||||
></Route>
|
||||
<Route
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
import Nodata from "../Nodata";
|
||||
class UndoEvents extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="pd20">
|
||||
<div className="grid-item pb20 bbt">
|
||||
<h3>待办事项</h3>
|
||||
</div>
|
||||
<Nodata _html={`暂时没有数据~`} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default UndoEvents;
|
Loading…
Reference in New Issue