change merge

This commit is contained in:
sylor_huang@126.com 2020-06-18 09:53:09 +08:00
commit ab2368dad4
16 changed files with 442 additions and 166 deletions

View File

@ -63,7 +63,7 @@ const http500 = Loadable({
loading: Loading,
})
const InfosIndex = Loadable({
loader: () => import('./forge/users/Infos'),
loader: () => import('./forge/users/Index'),
loading: Loading,
})
// 组织

View File

@ -103,6 +103,7 @@ export function initAxiosInterceptors(props) {
proxy = "https://testforgeplus.trustie.net/"
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求
// 如果需要支持重复的请求考虑config里面自定义一个allowRepeat参考来控制
const requestMap = {};
window.setfalseInRequestMap = function (keyName) {

View File

@ -0,0 +1,16 @@
import React from 'react';
import styled from 'styled-components';
const Nav = styled.div`{
background-color:#fff;
padding:20px 30px;
border-bottom:1px solid #eee;
font-size:16px;
color:#333;
}`
export default (({children})=>{
return(
<Nav>{children}</Nav>
)
})

View File

@ -15,6 +15,11 @@ export const AlignCenterBetween = styled.div`{
justify-content: space-between;
border-bottom:1px solid #eee;
}`
export const FlexAJ = styled.div`{
display:flex;
align-items: center;
justify-content: space-between;
}`
export const AlignCenter = styled.div`{
display:flex;
align-items: center;
@ -42,3 +47,33 @@ export const WhiteBack = styled.div`{
background-color:#fff;
border-radius:5px;
}`
export const Blueline = styled.a`{
height:30px;
line-height:30px;
border-radius:5px;
border:1px solid rgba(80,145,255,1);
color:rgba(80,145,255,1);
padding:0px 12px;
}`
export const NumUl = styled.ul`{
padding-left: 20px;
& > li{
list-style-type: decimal;
color:#888;
height:24px;
line-height:24px;
}
}`
export const GreenUnder = styled.a`{
color:#28BD6C!important;
position:relative;
&:after{
position:absolute;
bottom:-2px;
left:0px;
width:100%;
height:1px;
content:'';
background:#28BD6C;
}
}`

View File

@ -27,39 +27,45 @@ const ProjectDetail = Loadable({
loading: Loading,
});
const Infos = Loadable({
loader: () => import("./users/Infos"),
loading: Loading,
});
class Index extends Component {
render() {
console.log("ddd",document.cookie);
return (
<div className="newMain clearfix">
<Switch {...this.props}>
<Route
path="/projects/:projectsType/new"
render={(props) => (
<ProjectNew {...this.props} {...props} {...this.state} />
<ProjectNew {...this.props} {...props} />
)}
></Route>
<Route
path="/projects/:projectsId"
render={(props) => (
<ProjectDetail {...this.props} {...props} {...this.state} />
<ProjectDetail {...this.props} {...props} />
)}
></Route>
<Route
exact
path="/projects"
render={(props) => (
<ProjectIndex {...this.props} {...props} {...this.state} />
<ProjectIndex {...this.props} {...props} />
)}
></Route>
<Route exact path="/" render={(props) => (
<ProjectIndex
{...this.props}
{...props}
{...this.state}
></ProjectIndex>
<Route
exact
path="/"
render={(props) => (
this.props.current_user && this.props.current_user.login ?
<Infos {...this.props} {...props} />
:
<ProjectIndex {...this.props} {...props} />
)}
/>
></Route>
</Switch>
</div>
);

View File

@ -99,7 +99,7 @@
.list-l-Menu li.active::before{
position: absolute;
left: 0px;
top: 10px;
top: 15px;
width: 6px;
content: '';
height: 33px;

View File

@ -1,5 +1,13 @@
import React, { Component } from "react";
import { Input, Select, Button, Spin, Empty } from "antd";
import React, {
Component
} from "react";
import {
Input,
Select,
Button,
Spin,
Empty
} from "antd";
import axios from "axios";
import "../Order/order.css";
import "./merge.css";
@ -23,8 +31,13 @@ class UpdateMerge extends Component {
//获取新建分枝数据
getmergelist = () => {
this.setState({ isSpin: true });
const { projectsId, mergeId } = this.props.match.params;
this.setState({
isSpin: true
});
const {
projectsId,
mergeId
} = this.props.match.params;
const url = `/projects/${projectsId}/pull_requests/${mergeId}/edit.json`;
axios
.get(url)
@ -37,80 +50,126 @@ class UpdateMerge extends Component {
merge: result.data.base,
});
} else {
this.setState({ isSpin: false });
this.setState({
isSpin: false
});
}
})
.catch((error) => {
this.setState({ isSpin: false });
this.setState({
isSpin: false
});
console.log(error);
});
};
render() {
const { data, isSpin, pull, merge } = this.state;
return (
<div>
<div className="main">
<Spin spinning={isSpin}>
{data ? (
<div>
<div className="merge-header width100 inline-block">
<div className="width45 pull-left">
<div className="color-grey-3 mb10 fwb">源分支:</div>
<Input.Group compact className="display-flex">
<Button className="merge-header-button maxW50 hide-1 task-hide">
{data && data.project_author} /{" "}
{data && data.project_name}
</Button>
<Select
defaultValue={pull ? pull : "master"}
className="minW50 merge-flex1"
disabled
></Select>
</Input.Group>
</div>
<div className="width10 pull-left text-center mt25">
<i
className={"iconfont icon-youjiang color-grey-c font-32"}
></i>
</div>
<div className="width45 pull-left">
<div>
<div className="color-grey-3 mb10 fwb">目标分支:</div>
<Input.Group compact className="display-flex">
<Button className="merge-header-button maxW50 hide-1 task-hide">
{data && data.project_author} /{" "}
{data && data.project_name}
</Button>
<Select
defaultValue={merge ? merge : "master"}
className="minW50 merge-flex1"
disabled
></Select>
</Input.Group>
</div>
</div>
</div>
const {
data,
isSpin,
pull,
merge
} = this.state;
return ( <
div >
<
div className = "main" >
<
Spin spinning = {
isSpin
} > {
data ? ( <
div >
<
div className = "merge-header width100 inline-block" >
<
div className = "width45 pull-left" >
<
div className = "color-grey-3 mb10 fwb" > 源分支: < /div> <
Input.Group compact className = "display-flex" >
<
Button className = "merge-header-button maxW50 hide-1 task-hide" > {
data && data.project_author
}
/{" "} {
data && data.project_name
} <
/Button> <
Select defaultValue = {
pull ? pull : "master"
}
className = "minW50 merge-flex1"
disabled >
<
/Select> < /
Input.Group > <
/div> <
div className = "width10 pull-left text-center mt25" >
<
i className = {
"iconfont icon-youjiang color-grey-c font-32"
} >
<
/i> < /
div > <
div className = "width45 pull-left" >
<
div >
<
div className = "color-grey-3 mb10 fwb" > 目标分支 : < /div> <
Input.Group compact className = "display-flex" >
<
Button className = "merge-header-button maxW50 hide-1 task-hide" > {
data && data.project_author
}
/{" "} {
data && data.project_name
} <
/Button> <
Select defaultValue = {
merge ? merge : "master"
}
className = "minW50 merge-flex1"
disabled >
<
/Select> < /
Input.Group > <
/div> < /
div > <
/div>
<MergeForm
{...this.props}
merge_type="edit"
data={data}
merge={merge}
pull={pull}
></MergeForm>
</div>
) : (
""
)}
</Spin>
</div>
<div className=" main">
<MergeFooter footer_type="new" {...this.props}></MergeFooter>
</div>
</div>
);
}
<
MergeForm {
...this.props
}
merge_type = "edit"
data = {
data
}
merge = {
merge
}
pull = {
pull
} >
<
/MergeForm> < /
div >
): (
""
)
} <
/Spin> < /
div > <
div className = " main" >
<
MergeFooter footer_type = "new" {
...this.props
} > < /MergeFooter> < /
div > <
/div>
);
}
}
export default UpdateMerge;
export default UpdateMerge;

View File

@ -1,42 +1,51 @@
import React , { useEffect , useState } from 'react';
import { Input , Select } from 'antd';
import { getBranch } from '../GetData/getData';
import React , { useState } from 'react';
import SelectBranch from '../Branch/Select';
import Title from '../Component/Title';
import styled from 'styled-components';
import { Blueline , FlexAJ , NumUl , GreenUnder , AlignCenter , WhiteBack } from '../Component/layout';
const Div = styled.div`{
padding:20px 30px;
min-height:500px;
}`
const { Option } = Select;
export default ((props)=>{
const [ branchList , setBranchList] = useState(undefined);
const [ branch , setBranch ] = useState("master");
const { projectsId } = props.match.params;
const projectDetail = props.projectDetail;
useEffect(()=>{
getBranchs(projectsId);
},[projectsId])
function resetSetting(){
async function getBranchs(id){
let result = await getBranch(id);
setBranchList(result);
}
const branchListRender = (
branchList && branchList.map((item,key)=>{
return(
<Option value={item.name}>{item.name}</Option>
)
})
)
return(
<div className="normalBox">
<div className="normalBox-title font-16">
分支列表
</div>
<p className="pl15 pt15">请选择一个默认的分支用于合并请求和提交</p>
<div className="addPanel">
<Select className="branchSelect">
{branchListRender}
</Select>
<a className="small_submitBtn ml20" onClick={this.resetSetting}>更新仓库设置</a>
</div>
</div>
<WhiteBack>
<Title>分支设置</Title>
<Div>
<div className="pb20" style={{borderBottom:"1px solid #eee"}}>
<p className="color-grey-3 mb10">默认分支</p>
<p className="mb10">默认分支被视作为代码库中的基本分支是所有克隆代码提交合并请求的目标分支</p>
<AlignCenter>
<SelectBranch
branch={branch}
repo_id={ projectDetail && projectDetail.repo_id}
projectsId={projectsId}
changeBranch={setBranch}
/>
<a className="color-blue ml20" onClick={resetSetting()}>设为默认分支</a>
</AlignCenter>
</div>
<div>
<FlexAJ className="pt20">
<span className="color-grey-3">保护分支规则</span>
<Blueline>+&nbsp;新建规则</Blueline>
</FlexAJ>
<NumUl>
<li>限制分支的推送合并强制推送相关请去<GreenUnder>仓库设置</GreenUnder></li>
<li>一个分支同时只能有一个保护分支规则生效越早创建的规则优先级越高</li>
<li>保护分支规则只影响状态是保护分支的分支常规分支只读分支都不影响</li>
</NumUl>
</div>
</Div>
</WhiteBack>
)
})

View File

@ -15,6 +15,8 @@ import {
import NoneData from "../Nodata";
import axios from "axios";
import { getImageUrl } from "educoder";
import {WhiteBack} from '../Component/layout';
const { Search } = Input;
const { Option } = AutoComplete;
@ -430,7 +432,7 @@ class Collaborator extends Component {
);
});
return (
<div>
<WhiteBack>
<div className="flex-a-center baseForm bbr">
<span className="font-18 fwb text-black">协作者管理</span>
<div className="addPanel">
@ -496,7 +498,7 @@ class Collaborator extends Component {
) : (
""
)}
</div>
</WhiteBack>
);
}
}

View File

@ -2,10 +2,11 @@ import React, { Component } from "react";
import { Link, Route, Switch } from "react-router-dom";
import "../css/index.css";
import "./setting.css";
import "./setting.scss";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { Box , Long , Short , Gap , WhiteBack} from '../Component/layout';
const Branch = Loadable({
loader: () => import("./Branch"),
@ -30,8 +31,8 @@ class Index extends Component {
const flag = pathname === `/projects/${projectsId}/setting`;
return (
<div className="ProjectListIndex">
<div className="list-left">
<Box className="ProjectListIndex">
<Short>
<ul className="list-l-Menu">
<li className={flag ? "active" : ""}>
<p>
@ -63,7 +64,6 @@ class Index extends Component {
<i className="iconfont icon-fenzhi font-20 mr10"></i>
分支设置
</Link>
</p>
</li> */}
<li
@ -90,10 +90,10 @@ class Index extends Component {
</p>
</li> */}
</ul>
</div>
<div className="list-right">
<div>
<Switch {...this.props}>
</Short>
<Long>
<Gap>
<Switch {...this.props}>
{/* 协作者 */}
<Route
path="/projects/:projectsId/setting/collaborator"
@ -108,6 +108,12 @@ class Index extends Component {
<Tags {...this.props} {...props} {...this.state} />
)}
></Route>
<Route
path="/projects/:projectsId/setting/branch"
render={(props) => (
<Branch {...this.props} {...props} {...this.state} />
)}
></Route>
{/* 修改仓库信息 */}
<Route
path="/projects/:projectsId/setting"
@ -116,9 +122,9 @@ class Index extends Component {
)}
></Route>
</Switch>
</div>
</div>
</div>
</Gap>
</Long>
</Box>
);
}
}

View File

@ -1,8 +1,11 @@
import React, { Component } from "react";
import { Form, Input, Checkbox, Select } from "antd";
import Title from '../Component/Title';
import Mirror from './SettingMirror';
import {WhiteBack} from '../Component/layout';
import axios from "axios";
import "./setting.css";
import "./setting.scss";
const { TextArea } = Input;
const { Option } = Select;
class Setting extends Component {
@ -146,10 +149,8 @@ class Setting extends Component {
const { CategoryList, LanguageList, private_check } = this.state;
return (
<div>
<div className="">
<div className="flex-a-center baseForm bbr">
<span className="font-18 fwb text-black">基本设置</span>
</div>
<WhiteBack>
<Title>基本设置</Title>
<Form className="baseForm">
<Form.Item label="项目名称">
{getFieldDecorator("project_name", {
@ -212,22 +213,26 @@ class Setting extends Component {
</a>
</p>
</Form>
</div>
<div className="dangerousBox mb20">
<div className="dangerousTitle">危险操作区</div>
<div className="flex-a-center padding15-10">
<div>
<p className="font-bd font-16">删除本仓库</p>
<p className="mt10">
删除仓库是永久性的,
无法撤消且删除后与仓库关联的项目/任务/合并请求/版本发布等均会被删除
</p>
{/* 镜像设置部分,暂无接口,先不显示 */}
{/* <Mirror /> */}
</WhiteBack>
<WhiteBack className="dangerousBox mb20">
<div>
<div className="dangerousTitle">危险操作区</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>
<a onClick={this.deleteProject} className="red_deleteBtn">
删除本仓库
</a>
</div>
</div>
</WhiteBack>
</div>
);
}

View File

@ -0,0 +1,94 @@
import React , { forwardRef , useCallback , useState } from 'react';
import { Form , Checkbox , Input , Button } from 'antd';
import styled from 'styled-components';
import './setting.scss';
const Div = styled.div`{
margin:0px 30px;
background:#FAFAFA;
padding:0px 20px 10px 20px;
.ant-form.ant-form-horizontal{
padding:15px 0px;
}
}`
const P = styled.p`{
padding:15px 0px;
font-size:16px;
color:#333;
border-bottom:1px solid #DDDDDD;
}`
const Item = styled.div`{
padding-bottom:10px;
&>span{
color:#333;
}
.ant-checkbox-wrapper{
height:20px;
line-height:20px;
}
.ant-row.ant-form-item{
margin-bottom:0px;
}
}`
export default Form.create()(
forwardRef(({ form })=>{
const { getFieldDecorator, validateFields, setFieldsValue } = form;
const [ mirrorCheck , setMirrorCheck ] = useState(false)
const helper = useCallback(
(label, name, rules, widget, classname , isRequired = true ) => (
<Item className={classname}>
<span required={isRequired}>{label}</span>
<Form.Item>
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
</Form.Item>
</Item>
),
[]
);
return(
<Div>
<P>镜像设置</P>
<Form>
{helper(
"修剪",
"cut",
[],
<Checkbox>删除过时的远程跟踪引用</Checkbox>,'iteminline setHeight'
)}
{/* {helper(
"镜像间隔有效时间单位为“h”“m”“s”0将禁用自动同步。",
"time",
[],
<Input />,'iteminline'
)} */}
{helper(
"从URL克隆",
"clone",
[],
<Input />
)}
<p className="color-grey-8">在Clone认证部分里输入必要的信息</p>
<p className="mt10 mb10 color-grey-3 pointer" onClick={()=>setMirrorCheck(!mirrorCheck)}>需要授权验证<i className={mirrorCheck?"iconfont icon-xiajiantou font-13 ml10 color-grey-8":"iconfont icon-youjiantou font-13 ml10 color-grey-8"}></i></p>
{ mirrorCheck ?
<div className="df" style={{alignItems:'center'}}>
{helper(
"用户名",
"name",
[],
<Input />,'iteminline'
)}
{helper(
"密码",
"password",
[],
<Input type={'password'}/>,'iteminline ml30'
)}
</div>
:""}
<p className="mb15">上次同步 2020-06-16 1740</p>
<Button type={"primary"}>同步</Button>
</Form>
</Div>
)
})
)

View File

@ -12,13 +12,14 @@ import {
Button,
Table,
} from "antd";
import { Link } from "react-router-dom";
import "../Order/order.css";
import "./setting.css";
import "./setting.scss";
import NoneData from "../Nodata";
import { SketchPicker } from "react-color";
import reactCSS from "reactcss";
import axios from "axios";
import {WhiteBack} from '../Component/layout';
class NewTags extends Component {
constructor(props) {
super(props);
@ -433,7 +434,7 @@ class NewTags extends Component {
};
return (
<div className="">
<WhiteBack>
<div
className="flex-a-center baseForm bbr"
style={{ "justify-content": "space-between" }}
@ -556,7 +557,7 @@ class NewTags extends Component {
</div>
</div>
</Modal>
</div>
</WhiteBack>
);
}
}

View File

@ -23,7 +23,20 @@
content: '';
}
.baseForm{
padding:15px 20px!important;
padding:15px 30px!important;
}
.iteminline{
display: flex;
align-items: center;
.ant-row.ant-form-item{
margin-left: 15px;
}
}
.setHeight{
.ant-form-item-control{
height: 20px;
line-height: 20px;
}
}
.baseForm .ant-row.ant-form-item{
margin-bottom: 15px;
@ -49,7 +62,6 @@
}
.addPanel{
display: flex;
/* padding:15px; */
}
.red_btn{
display: block;
@ -75,10 +87,14 @@
}
.dangerousBox{
border:1px solid #efc16b;
border-radius: 4px;
margin-top: 20px;
padding:20px;
&>div{
border:1px solid #efc16b;
border-radius: 4px;
}
}
.dangerousTitle{
padding:10px;
background: #f9edbe;

26
src/forge/users/Index.jsx Normal file
View File

@ -0,0 +1,26 @@
import React from 'react';
import { Route, Switch } from "react-router-dom";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { withRouter } from "react-router";
import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
const Infos = Loadable({
loader: () => import("./Infos"),
loading: Loading,
});
export default withRouter(
(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC((props)=>{
return(
<Switch {...props}>
<Route
path="/users/:username"
render={(props) => {
return <Infos {...props} />;
}}
></Route>
</Switch>
)
}))))
)

View File

@ -8,9 +8,6 @@ import { getImageUrl } from "educoder";
import { Route, Switch } from "react-router-dom";
import { withRouter } from "react-router";
import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import "./new_user.css";
import "../css/index.css";
import './Index.scss';
@ -60,7 +57,10 @@ class Infos extends Component {
this.setState({
isSpin: true,
});
let url = `/users/${this.props.match.params.username}.json`;
const { current_user } = this.props;
const { username } = this.props.match.params;
let url = `/users/${username || (current_user && current_user.login)}.json`;
axios
.get(url)
.then((result) => {
@ -281,7 +281,12 @@ class Infos extends Component {
return <InfosUser {...this.props} {...this.state} />;
}}
></Route>
<Route
path="/"
render={(props) => {
return <InfosUser {...this.props} {...this.state} />;
}}
></Route>
</Switch>
</div>
)}
@ -292,9 +297,4 @@ class Infos extends Component {
);
}
}
export default withRouter(
ImageLayerOfCommentHOC({
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
parentSelector: ".newMain",
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Infos))))
);
export default Infos;