Merge branch 'newVersion_forge' of http://gitea.trustie.net/jasder/forgeplus-react into newVersion_forge

This commit is contained in:
Jasder 2020-07-02 14:18:21 +08:00
commit 1d54c1a8f7
29 changed files with 702 additions and 307 deletions

View File

@ -1569,6 +1569,7 @@ a.edu-txt-w80,
.font-80 {
font-size: 80px !important;
}
.color-grey-b{color: #bbb !important}
/*a标签的下划线*/
a.decoration {

View File

@ -29,4 +29,12 @@
color:#fff !important;
}
.display-flex{display: flex !important;}
.merge-flex1{flex:1}
.merge-flex1{flex:1}
.ant-tag.pr-branch-tag{
border-radius: 12px;
height: 24px;
background: rgba(241,248,255,1);
border: none;
font-size: 13px;
padding: 0 10px;
}

View File

@ -98,9 +98,10 @@ export function initAxiosInterceptors(props) {
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
// TODO 读取到package.json中的配置
var proxy = "http://localhost:3000"
var
proxy = "http://localhost:3000"
// proxy = "https://pre-newweb.educoder.net"
proxy = "https://testforgeplus.trustie.net"
// proxy = "https://testforgeplus.trustie.net"
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求

View File

@ -14,7 +14,7 @@ li.ant-menu-item{
align-items: center;
padding:20px 34px;
background-color: #fff;
margin:18px 0px;
margin-bottom:18px;
.img{
margin-right: 20px;
width: 190px;

View File

@ -48,8 +48,8 @@ export const WhiteBack = styled.div`{
border-radius:5px;
}`
export const Blueline = styled.a`{
height:32px;
line-height:30px;
height:30px;
line-height:28px;
border-radius:2px;
border:1px solid rgba(80,145,255,1);
color:rgba(80,145,255,1);
@ -57,8 +57,8 @@ export const Blueline = styled.a`{
display:inline-block;
}`
export const Redline = styled.a`{
height:32px;
line-height:32px;
height:30px;
line-height:28px;
border-radius:2px;
border:1px solid #F73030;
color:#F73030;
@ -68,8 +68,8 @@ export const Redline = styled.a`{
text-align:center;
}`
export const Greenline = styled.a`{
height:32px;
line-height:32px;
height:30px;
line-height:28px;
border-radius:2px;
border:1px solid #28BD6C;
color:#28BD6C;
@ -78,6 +78,28 @@ export const Greenline = styled.a`{
min-width:80px;
text-align:center;
}`
export const Greenback = styled.a`{
height:30px;
line-height:30px;
border-radius:2px;
background-color:#28BD6C;
color:#fff;
padding:0px 12px;
display:inline-block;
min-width:80px;
text-align:center;
}`
export const Redback = styled.a`{
height:30px;
line-height:30px;
border-radius:2px;
background-color:#F73030;
color:#fff;
padding:0px 12px;
display:inline-block;
min-width:80px;
text-align:center;
}`
export const NumUl = styled.ul`{
padding-left: 20px;
& > li{

View File

@ -243,7 +243,7 @@ class CoderRootDirectory extends Component {
message: item.commit && item.commit.message,
...item,
});
if (item.name === "README.md") {
if (item.is_readme_file) {
readMeContent.push({ ...item });
readMeFile.push({ ...item });
}
@ -350,7 +350,7 @@ class CoderRootDirectory extends Component {
dataIndex: 'name',
width:"30%",
render: (text,item) => (
<a onClick={()=>this.goToSubRoot(item.path,item.type)} className="ml12">
<a onClick={()=>this.goToSubRoot(item.path,item.type)} className="ml12 task-hide" style={{ display: "block", maxWidth: "345px" }}>
<i className={ item.type === "file" ? "iconfont icon-wenjia font-15 color-green-file mr5":"iconfont icon-wenjianjia1 color-green-file font-15 mr5"}></i>{text}
</a>
),
@ -484,7 +484,7 @@ class CoderRootDirectory extends Component {
)}
</div>
<div className="f-wrap-alignCenter">
{subFileType && (isManager || isDeveloper) && (
{subFileType && parseInt(projectDetail.type) !== 2 && (isManager || isDeveloper) && (
<div>
<span>
<Link

View File

@ -367,7 +367,7 @@ class Detail extends Component {
<div className="detailHeader-wrapper">
<div className="normal">
<div className="f-wrap-between mb15" style={{ position: "relative" }}>
<p className="font-18 color-white df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
<p className="font-22 color-white df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
{project && project.author &&
<Link to={`/users/${project.author.login}`} className="show-user-link color-white">
{project.author.name}
@ -388,7 +388,7 @@ class Detail extends Component {
{
projectDetail && checkLogin && projectDetail.type && projectDetail.type === 2 ?
<Tooltip placement={'right'} title={mirror}>
<i className="iconfont icon-jingxiang font-18 fl mt6 ml10" style={{ color: "#8D90E3" }}></i>
<i className="iconfont icon-banbenku font-18 fl mt6 ml10" style={{ color: "#8D90E3" }}></i>
</Tooltip>:""
}
</span>
@ -438,12 +438,16 @@ class Detail extends Component {
{ projectDetail && projectDetail.issues_count ? <span>{projectDetail.issues_count}</span> :""}
</Link>
</li>
<li className={url.indexOf("merge") > -1 ? "active" : ""}>
{
projectDetail && parseInt(projectDetail.type) !== 2 &&
<li className={url.indexOf("merge") > -1 ? "active" : ""}>
<Link to={{ pathname: `/projects/${projectsId}/merge`, state }}>
<img alt="" src={img_3} width="13" />合并请求
{ projectDetail && projectDetail.pull_requests_count ? <span>{projectDetail.pull_requests_count}</span> : "" }
</Link>
</li>
}
<li className={(url.indexOf("Milepost") > -1 || url.indexOf("meilpost") > -1) ? "active" : ""}>
<Link to={{ pathname: `/projects/${projectsId}/orders/Milepost`, state }}>
<img alt="" src={img_milepost} width="16" />里程碑

View File

@ -2,7 +2,7 @@ import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Popconfirm, Tag } from "antd";
import { getImageUrl } from "educoder";
import "./merge.css"
import "./merge.css";
class MergeItem extends Component {
constructor(props) {
@ -42,7 +42,7 @@ class MergeItem extends Component {
};
render() {
const { issues, project_name } = this.props;
const { issues, project_name, project_author_name } = this.props;
const { projectsId } = this.props.match.params;
const { current_user } = this.props;
const renderList = () => {
@ -60,7 +60,11 @@ class MergeItem extends Component {
{item.name}
</Link>
<Tag className={`pr_tags_${item.pull_request_staus}`}>
{item.pull_request_staus==="merged" ? "已合并" : (item.pull_request_staus === "closed"?"已拒绝" : "开启的") }
{item.pull_request_staus === "merged"
? "已合并"
: item.pull_request_staus === "closed"
? "已拒绝"
: "开启的"}
</Tag>
</p>
<p className="grid-item font-13">
@ -92,21 +96,33 @@ class MergeItem extends Component {
</span>
<span className="color-grey-8">{item.pr_time}</span>
<span className="ml15">
<Tag>
<Tag className="pr-branch-tag">
<Link
to={`projects/${projectsId}/coders?branch=${item.pull_request_head}`} className="maxW200px hide-1 ver-middle"
to={`/projects/${
item.is_original ? item.fork_project_id : projectsId
}/coders?branch=${item.pull_request_head}`}
className="maxW200px hide-1 ver-middle"
>
{project_name}:{item.pull_request_head}
{item.is_original
? item.fork_project_user
: project_author_name}
:{item.pull_request_head}
</Link>
</Tag>
<span className="mr8 ver-middle">
<i className={"iconfont icon-youjiang color-grey-c font-16"}></i>
<i
className={
"iconfont icon-youjiang color-grey-c font-16"
}
></i>
</span>
<Tag>
<Tag className="pr-branch-tag">
<Link
to={`projects/${projectsId}/coders?branch=${item.pull_request_base}`} className="maxW200px hide-1 ver-middle"
to={`/projects/${projectsId}/coders?branch=${item.pull_request_base}`}
className="maxW200px hide-1 ver-middle"
>
{project_name}:{item.pull_request_base}
{/* {item.is_fork ? item.pull_request_base : `${item.author_name}:${item.pull_request_base}`} */}
{project_author_name}:{item.pull_request_base}
</Link>
</Tag>
</span>
@ -133,7 +149,7 @@ class MergeItem extends Component {
)}
</li>
<li>{item.version || "--"}</li>
<li>
<div
className="flex1 df"

View File

@ -256,12 +256,12 @@ class MessageCount extends Component {
</div>
{
<div className="mt15">
<Tag>
<Tag className="pr-branch-tag">
<Link
to={`projects/${projectsId}/coders?branch=${data.pull_request.head}`}
to={`/projects/${data.pull_request.is_original?data.pull_request.fork_project_id:projectsId}/coders?branch=${data.pull_request.head}`}
className="ver-middle"
>
{data.project_name}{data.pull_request.head}
{data.pull_request.is_original ? data.pull_request.fork_project_user : data.issue.project_author_name}:{data.pull_request.head}
</Link>
</Tag>
<span className="mr8 ver-middle">
@ -271,12 +271,13 @@ class MessageCount extends Component {
}
></i>
</span>
<Tag>
<Tag className="pr-branch-tag">
<Link
to={`projects/${projectsId}/coders?branch=${data.pull_request.base}`}
to={`/projects/${projectsId}/coders?branch=${data.pull_request.base}`}
className="ver-middle"
>
{data.project_name}{data.pull_request.base}
{/* {data.pull_request.is_fork ? data.pull_request.base : `${data.pull_request.pull_request_user}:${data.pull_request.base}`} */}
{data.issue.project_author_name}:{data.pull_request.base}
</Link>
</Tag>
</div>

View File

@ -3,8 +3,8 @@ import { Input, Select, Button, Spin, Alert } from "antd";
import axios from "axios";
import "../Order/order.css";
import "./merge.css";
import MergeForm from "./merge_form"
import MergeFooter from "./merge_footer"
import MergeForm from "./merge_form";
import MergeFooter from "./merge_footer";
const Option = Select.Option;
class NewMerge extends Component {
constructor(props) {
@ -12,35 +12,91 @@ class NewMerge extends Component {
this.state = {
data: undefined,
branches: undefined,
origin_branches: undefined,
merge: undefined,
pull: undefined,
merge_branches: undefined,
merge_projects: undefined,
merge: "master",
pull: "master",
is_fork: false,
projects_names: undefined,
isSpin: false,
show_message: true,
merge_head: false, // 是否向fork后的源项目发起合并请求
default_message: "必须选择不同的分支",
project_id: undefined, // 当前项目的id也即开始发送合并请求的源项目id
merge_project_user: undefined
};
}
componentDidMount = () => {
this.getmergelist();
const { projectsId } = this.props.match.params;
this.getmergelist(projectsId);
};
//获取新建分枝数据
getmergelist = () => {
const { projectsId } = this.props.match.params;
getmergelist = (projectsId) => {
this.setState({isSpin: true})
const url = `/projects/${projectsId}/pull_requests/new.json`;
axios
.get(url)
.then((result) => {
if (result) {
this.setState({
data: result.data,
is_fork: result.data.is_fork,
projects_names: result.data.projects_names,
merge_projects: result.data.merge_projects,
branches: result.data.branches,
origin_branches: result.data.branches,
merge_branches: result.data.branches,
project_id: result.data.project_id,
});
this.set_default_pull()
this.set_default_merge()
}
this.setState({isSpin: false})
})
.catch((error) => {
this.setState({isSpin: false})
console.log(error);
});
};
set_default_pull = () => {
const {branches} = this.state;
let default_pull = branches.filter((e) => e.name === "master")
if (default_pull.length > 0){
this.state.pull = default_pull[0].name
}else{
this.state.pull = "master"
}
}
set_default_merge = () => {
const {merge_branches} = this.state;
let default_merge = merge_branches.filter((e) => e.name === "master")
if (default_merge.length > 0){
this.state.merge = default_merge[0].name
}else{
this.state.merge = "master"
}
this.ischeckmerge();
}
newMergelist = (projectsId) => {
this.setState({isSpin: true})
const url = `/projects/${projectsId}/pull_requests/get_branches.json`;
axios
.get(url)
.then((result) => {
if (result) {
this.setState({
merge_branches: result.data
})
this.set_default_merge()
}
this.setState({isSpin: false})
})
.catch((error) => {
this.setState({isSpin: false})
console.log(error);
});
};
@ -50,18 +106,37 @@ class NewMerge extends Component {
this.ischeckmerge();
};
selectProjectName = (value) => {
const { project_id, projects_names } = this.state;
let is_fork_id = parseInt(value) !== parseInt(project_id)
this.setState({
isSpin: true,
merge_head: is_fork_id,
data: {
is_original: is_fork_id,
fork_project_id: is_fork_id ? project_id : "",
merge_user_login: is_fork_id ? projects_names[0].project_user_login : undefined
}
})
this.props.history.push(`/projects/${value}/merge/new`);
this.newMergelist(value);
};
//判断2分支是否可以合并
ischeckmerge = () => {
this.setState({ isSpin: true });
const { projectsId } = this.props.match.params;
const { pull, merge } = this.state;
const { pull, merge, project_id, merge_head } = this.state;
const url = `/projects/${projectsId}/pull_requests/check_can_merge.json`;
axios
.post(url, {
project_id: projectsId,
head: merge ? merge : "master",
base: pull ? pull : "master",
head: pull,
base: merge,
is_original: merge_head,
fork_project_id: merge_head ? project_id : undefined
})
.then((result) => {
if (result) {
@ -95,20 +170,38 @@ class NewMerge extends Component {
const {
data,
branches,
origin_branches,
merge_branches,
merge_projects,
pull,
merge,
isSpin,
show_message,
default_message,
merge_head,
projects_names,
} = this.state;
const renderBrances = (list) => {
const { projectsId } = this.props.match.params;
const renderBrances = (list, type) => {
if (list && list.length > 0) {
return list.map((item, key) => {
return (
<Option key={key + 1} value={item}>
{item}
<Option
key={key + 1}
value={item.name}
>
{item.name}
</Option>
);
});
}
};
const renderProjectNames = (list) => {
if (list && list.length > 0) {
return list.map((item, key) => {
return (
<Option key={key + 1} value={item.project_id}>
{item.project_name}
</Option>
);
});
@ -120,65 +213,77 @@ class NewMerge extends Component {
};
return (
<div >
<div>
<div className="main">
<Spin spinning={isSpin}>
<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"}
onSelect={(e) => this.selectBrach("pull", e)}
showSearch
className="minW50 merge-flex1"
>
{renderBrances(branches)}
</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>
<Spin spinning={isSpin}>
<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={merge ? merge : "master"}
onSelect={(e) => this.selectBrach("merge", e)}
defaultValue={parseInt(projectsId)}
class=" maxW50 hide-1 task-hide"
disabled
>
{renderProjectNames(projects_names)}
</Select>
<Select
defaultValue={pull}
onSelect={(e) => this.selectBrach("pull", e)}
showSearch
className="minW50 merge-flex1"
>
{renderBrances(branches)}
{renderBrances(branches, false)}
</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">
<Select
defaultValue={parseInt(projectsId)}
class=" maxW50 hide-1 task-hide"
onSelect={(e) => this.selectProjectName(e)}
>
{renderProjectNames(merge_projects)}
</Select>
<Select
defaultValue={merge}
value={merge}
onSelect={(e) => this.selectBrach("merge", e)}
showSearch
className="minW50 merge-flex1"
>
{renderBrances(merge_branches, merge_head)}
</Select>
</Input.Group>
</div>
</div>
</div>
</div>
{show_message ? (
<div className="mb50 mt50">
<Alert
description={withHtml(default_message)}
type="error"
/>
</div>
)
:
<MergeForm {...this.props} merge_type="new" data={data} merge={merge?merge:"master"} pull={pull?pull:"master"}></MergeForm>
}
</Spin>
{show_message ? (
<div className="mb50 mt50">
<Alert description={withHtml(default_message)} type="error" />
</div>
) : (
<MergeForm
{...this.props}
merge_type="new"
data={data}
merge={merge}
pull={pull}
></MergeForm>
)}
</Spin>
</div>
<div className=" main">
{/* <div className=" main">
<MergeFooter footer_type="new" {...this.props}></MergeFooter>
</div>
</div> */}
</div>
);
}

View File

@ -57,13 +57,13 @@ class UpdateMerge extends Component {
<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}
{data.is_original ? `${data.fork_project_user_name}/${data.fork_project_identifier}` : `${data.project_author}/${data.project_name}`}
</Button>
<Select
defaultValue={pull ? pull : "master"}
defaultValue={data.is_original ? `${data.fork_project_user}:${pull}` : `${pull}`}
className="minW50 merge-flex1"
disabled
></Select>
@ -79,11 +79,10 @@ class UpdateMerge extends Component {
<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}
{`${data.project_author}/${data.project_name}`}
</Button>
<Select
defaultValue={merge ? merge : "master"}
defaultValue={data.is_original ? `${data.project_login}:${merge}` : `${merge}`}
className="minW50 merge-flex1"
disabled
></Select>
@ -105,9 +104,9 @@ class UpdateMerge extends Component {
)}
</Spin>
</div>
<div className=" main">
{/* <div className=" main">
<MergeFooter footer_type="new" {...this.props}></MergeFooter>
</div>
</div> */}
</div>
);
}

View File

@ -417,6 +417,7 @@ class merge extends Component {
page={select_params.page}
limit={select_params.limit}
project_name={data.project_name}
project_author_name={data.project_author_name}
{...this.props}
{...this.state}
></OrderItem>

View File

@ -33,12 +33,12 @@ class MergeFooter extends Component {
</TabPane>
}
<TabPane tab={<span className="ml-3 font-16">提交</span>} key="2">
{/* <TabPane tab={<span className="ml-3 font-16"></span>} key="2">
<CodesCommit {...this.props} main_class="pd10"></CodesCommit>
</TabPane>
<TabPane tab={<span className="ml-3 font-16">文件</span>} key="3">
</TabPane> */}
{/* <TabPane tab={<span className="ml-3 font-16"></span>} key="3">
<Empty />
</TabPane>
</TabPane> */}
</Tabs>
</div>
);

View File

@ -1,5 +1,5 @@
import React, { Component } from "react";
import { Button, Form, Menu, Input, Select, Tag, Checkbox } from "antd";
import { Button, Form, Menu, Input, Select, Tag, Checkbox, Spin } from "antd";
import axios from "axios";
import "../Order/order.css";
@ -21,21 +21,55 @@ class MergeForm extends Component {
mergedata: undefined,
priority_id: undefined,
title: undefined,
members: undefined,
issue_tags: undefined,
issue_versions: undefined,
issue_priories: undefined,
};
}
componentDidMount = () => {
this.check_is_login();
this.get_default_selects();
this.set_defatul();
};
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
};
get_default_selects = () => {
const { projectsId } = this.props.match.params;
this.setState({ isSpin: true });
axios
.get(`/projects/${projectsId}/pull_requests/create_merge_infos.json`)
.then((result) => {
if (result) {
this.setState({
members: result.data.members,
issue_tags: result.data.issue_tags,
issue_versions: result.data.issue_versions,
issue_priories: result.data.issue_priories,
});
}
this.setState({ isSpin: false });
})
.catch((error) => {
this.setState({ isSpin: false });
console.log(error);
});
};
set_defatul = () => {
const { data, merge_type } = this.props;
if (data && merge_type === "edit") {
this.setState({
desc: data.body,
issue_tag_ids: data.issue_tag_ids[0],
fixed_version_id: String(data.fixed_version_id),
assigned_to_id: String(data.assigned_to_id),
priority_id: String(data.priority_id),
issue_tag_ids: data.issue_tag_ids ? data.issue_tag_ids[0] : undefined,
fixed_version_id: data.fixed_version_id ? String(data.fixed_version_id) : undefined,
assigned_to_id: data.assigned_to_id ? String(data.assigned_to_id) : undefined,
priority_id: data.priority_id ? String(data.priority_id) :undefined,
title: data.title,
});
}
@ -99,13 +133,13 @@ class MergeForm extends Component {
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
const { projectsId, mergeId } = this.props.match.params;
const { merge, pull, merge_type } = this.props;
const { merge, pull, merge_type, data } = this.props;
if (values.issue_tag_ids && values.issue_tag_ids.length > 0) {
values.issue_tag_ids = [parseInt(values.issue_tag_ids)];
} else {
values.issue_tag_ids = [];
}
const { desc } = this.state;
const { desc } = this.state;
if (merge_type === "new") {
let url = `/projects/${projectsId}/pull_requests.json`;
axios
@ -114,6 +148,9 @@ class MergeForm extends Component {
body: desc,
head: pull,
base: merge,
is_original: data && data.is_original,
fork_project_id: data && data.fork_project_id,
merge_user_login: data && data.merge_user_login
})
.then((result) => {
if (result) {
@ -121,6 +158,8 @@ class MergeForm extends Component {
isSpin: false,
});
this.props.history.push(`/projects/${projectsId}/merge`);
const { getDetail } = this.props;
getDetail && getDetail();
} else {
this.setState({
isSpin: false,
@ -136,30 +175,32 @@ class MergeForm extends Component {
} else {
let url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
axios
.put(url, {
...values,
body: desc,
head: pull,
base: merge,
})
.then((result) => {
if (result) {
.put(url, {
...values,
body: desc,
head: pull,
base: merge,
})
.then((result) => {
if (result) {
this.setState({
isSpin: false,
});
this.props.history.push(
`/projects/${projectsId}/merge/${mergeId}/Messagecount`
);
} else {
this.setState({
isSpin: false,
});
}
})
.catch((error) => {
this.setState({
isSpin: false,
});
this.props.history.push(`/projects/${projectsId}/merge/${mergeId}/Messagecount`);
} else {
this.setState({
isSpin: false,
});
}
})
.catch((error) => {
this.setState({
isSpin: false,
console.log(error);
});
console.log(error);
});
}
} else {
this.setState({
@ -187,130 +228,136 @@ class MergeForm extends Component {
desc,
isSpin,
title,
members,
issue_tags,
issue_versions,
issue_priories,
} = this.state;
return (
<div>
<div className="mt20 mb20">
<span className="font-16 fwb mr10 ver-middle">
{merge_type === "new" ? "新建" : "编辑"}合并请求:
</span>
<Tag color="#28BD6C" className="ver-middle">
可合并的
</Tag>
</div>
<Form>
<div className="width100 inline-block">
<div className="width70 pull-left">
<Form.Item>
{getFieldDecorator("title", {
rules: [
{
required: true,
message: "请填写请求标题",
},
],
initialValue: title,
})(<Input placeholder="标题" />)}
</Form.Item>
<MDEditor
placeholder={"请输入合并请求的描述..."}
height={350}
mdID={"merge-new-description"}
initValue={desc}
onChange={this.onContentChange}
></MDEditor>
<p className="clearfix mt20">
<Button
type="primary"
loading={isSpin}
onClick={this.handleSubmit}
>
<span className="plr10">
{merge_type === "new" ? "创建" : "提交"}
</span>
</Button>
<Button
type="default"
className="ml30"
href={
merge_type === "new"
? `/projects/${projectsId}/merge`
: `/projects/${projectsId}/merge/${mergeId}/detail`
}
>
<span className="plr10">取消</span>
</Button>
</p>
</div>
<div className="width30 pull-left">
<div className="pl30">
<Spin spinning={isSpin}>
<div className="mt20 mb20">
<span className="font-16 fwb mr10 ver-middle">
{merge_type === "new" ? "新建" : "编辑"}合并请求:
</span>
<Tag color="#28BD6C" className="ver-middle">
可合并的
</Tag>
</div>
<Form>
<div className="width100 inline-block">
<div className="width70 pull-left">
<Form.Item>
{getFieldDecorator("assigned_to_id", {
initialValue: assigned_to_id,
})(
<Select placeholder="审查人员" showSearch>
{this.renderSelect(data && data.members)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("fixed_version_id", {
initialValue: fixed_version_id,
})(
<Select
placeholder={
data && data.issue_versions.length > 0
? "未选择里程碑"
: "请添加里程碑"
}
showSearch
>
{this.renderSelect(data && data.issue_versions)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("issue_tag_ids", {
initialValue: issue_tag_ids,
})(
<Select
placeholder={
data && data.issue_tags.length > 0
? "未选择标签"
: "请在仓库设置里添加标签"
}
showSearch
>
{this.renderSelect(data && data.issue_tags)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("priority_id", {
initialValue: priority_id,
})(
<Select placeholder="优先级" showSearch>
{this.renderSelect(data && data.issue_priories)}
</Select>
)}
</Form.Item>
<Form.Item name="checkbox-group" label="其他">
<Checkbox.Group>
<div>
<Checkbox value="A">必须审查代码</Checkbox>
</div>
<div>
<Checkbox value="B">合并后删除提交分支</Checkbox>
</div>
<div>
<Checkbox value="C">合并后关闭提到的任务</Checkbox>
</div>
</Checkbox.Group>
{getFieldDecorator("title", {
rules: [
{
required: true,
message: "请填写请求标题",
},
],
initialValue: title,
})(<Input placeholder="标题" />)}
</Form.Item>
<MDEditor
placeholder={"请输入合并请求的描述..."}
height={350}
mdID={"merge-new-description"}
initValue={desc}
onChange={this.onContentChange}
></MDEditor>
<p className="clearfix mt20">
<Button
type="primary"
loading={isSpin}
onClick={this.handleSubmit}
>
<span className="plr10">
{merge_type === "new" ? "创建" : "提交"}
</span>
</Button>
<Button
type="default"
className="ml30"
href={
merge_type === "new"
? `/projects/${projectsId}/merge`
: `/projects/${projectsId}/merge/${mergeId}/detail`
}
>
<span className="plr10">取消</span>
</Button>
</p>
</div>
<div className="width30 pull-left">
<div className="pl30">
<Form.Item>
{getFieldDecorator("assigned_to_id", {
initialValue: assigned_to_id,
})(
<Select placeholder="审查人员" showSearch>
{this.renderSelect(members)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("fixed_version_id", {
initialValue: fixed_version_id,
})(
<Select
placeholder={
issue_versions && issue_versions.length > 0
? "未选择里程碑"
: "请添加里程碑"
}
showSearch
>
{this.renderSelect(issue_versions)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("issue_tag_ids", {
initialValue: issue_tag_ids,
})(
<Select
placeholder={
issue_tags && issue_tags.length > 0
? "未选择标签"
: "请在仓库设置里添加标签"
}
showSearch
>
{this.renderSelect(issue_tags)}
</Select>
)}
</Form.Item>
<Form.Item>
{getFieldDecorator("priority_id", {
initialValue: priority_id,
})(
<Select placeholder="优先级" showSearch>
{this.renderSelect(issue_priories)}
</Select>
)}
</Form.Item>
<Form.Item name="checkbox-group" label="其他">
<Checkbox.Group>
<div>
<Checkbox value="A">必须审查代码</Checkbox>
</div>
<div>
<Checkbox value="B">合并后删除提交分支</Checkbox>
</div>
<div>
<Checkbox value="C">合并后关闭提到的任务</Checkbox>
</div>
</Checkbox.Group>
</Form.Item>
</div>
</div>
</div>
</div>
</Form>
</Form>
</Spin>
</div>
);
}

View File

@ -7,7 +7,7 @@ class Nodata extends Component{
<div className="none_panels">
<div>
<div className="mb15">
<i className="iconfont icon-hebingqingqiu font-80 ver-middle color-grey-8"></i>
<i className="iconfont icon-hebingqingqiu font-80 ver-middle color-grey-b"></i>
</div>
<h3>欢迎使用合并请求</h3>

View File

@ -41,21 +41,22 @@ class Index extends Component {
ignore_name: undefined
}
}
getUserInfo = () => {
const url = `/users/me.json`;
axios.get(url).then(result => {
if (result && result.data.login) {
this.setState({
current_user: result.data
})
this.getDetail();
}
}).catch(error => {
console.log(error)
})
}
// getUserInfo = () => {
// const url = `/users/me.json`;
// axios.get(url).then(result => {
// if (result && result.data.login) {
// this.setState({
// current_user: result.data
// })
// this.getDetail();
// }
// }).catch(error => {
// console.log(error)
// })
// }
componentDidMount = () => {
// this.getUserInfo();
this.check_is_login()
// 获取项目类别
this.getCategory();
// 获取项目语言
@ -64,6 +65,14 @@ class Index extends Component {
this.getGitignore();
// 获取开源许可证
this.getLicenses();
}
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
}
getCategory = () => {
const url = `/project_categories.json`
@ -216,6 +225,21 @@ class Index extends Component {
})
}
ChangeAddr=(e)=>{
let value = e.target.value;
if(value.indexOf("/") > -1){
let arr = value.split("/");
let first = arr[arr.length-1];
if(first.indexOf(".git") > -1){
let second = first.split('.')[0];
if(!second)return;
this.props.form.setFieldsValue({
repository_name:second
})
}
}
}
render() {
const { getFieldDecorator } = this.props.form;
// 项目类型deposit-托管项目mirror-镜像项目
@ -262,7 +286,7 @@ class Index extends Component {
required: true, message: '请填写镜像版本库地址'
}],
})(
<Input placeholder="输入需要同步到本项目的镜像版本库地址" />
<Input placeholder="输入需要同步到本项目的镜像版本库地址" onChange={this.ChangeAddr} />
)}
</Form.Item>
<p className="formTip color-orange">示例https://github.com/facebook/reack.git</p>

View File

@ -55,6 +55,10 @@ class UserSubmitComponent extends Component {
: `/projects/${projectsId}/coders`;
this.props.history.push(url);
this.props.showNotification("文件新建成功!");
if(submitType === "1"){
const { getDetail } = this.props;
getDetail && getDetail();
}
}
})
.catch((error) => {

View File

@ -5,7 +5,7 @@
.setInputAddon .ant-input-group-addon{
height: 30px;
line-height: 30px;
border-left: 1px solid #d9d9d9!important;
border: 1px solid #d9d9d9!important;
border-right: none!important;
}

View File

@ -17,6 +17,17 @@ class NewMilepost extends Component {
}
}
componentDidMount = () => {
this.check_is_login();
};
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
};
onPanelChange = (time, mode) => {
this.setState({
value: time

View File

@ -55,7 +55,6 @@ class order extends Component {
allValue: [],
all: false,
select_params: {
status_type: "1", //开启中和关闭中,全部,默认为全部
assigned_to_id: undefined, // 负责人
author_id: undefined, // 发布人
issue_tag_id: undefined, // 标签
@ -77,7 +76,7 @@ class order extends Component {
componentDidMount = () => {
this.getSelectList();
this.getIssueList();
this.getIssueList('1');
};
getSelectList = () => {
@ -101,7 +100,7 @@ class order extends Component {
};
// 获取列表数据
getIssueList = (begin, end) => {
getIssueList = (status_type , begin, end) => {
this.setState({
isSpin: true
})
@ -113,7 +112,8 @@ class order extends Component {
params: {
...select_params,
start_date: begin,
due_date: end
due_date: end,
status_type
}
})
.then((result) => {
@ -165,7 +165,8 @@ class order extends Component {
this.state.select_params.order_name = key_name[0];
this.state.select_params.order_type = e.item.props.value;
this.state.select_params.page = 1;
this.getIssueList();
const { status_type } = this.state;
this.getIssueList(status_type);
};
getOption = (e, id, name,toGet) => {
@ -192,7 +193,8 @@ class order extends Component {
assigned_to_id
});
if(!toGet){
this.getIssueList();
const { status_type } = this.state;
this.getIssueList(status_type);
}
};
@ -225,8 +227,10 @@ class order extends Component {
checkedValue: [],
all: false
});
const { status_type } = this.state;
this.state.select_params.page = page;
this.getIssueList();
this.getIssueList(status_type);
};
// 搜索
@ -235,9 +239,11 @@ class order extends Component {
search: value,
isSpin: true,
});
const { status_type } = this.state;
this.state.select_params.search = value;
this.state.select_params.page = 1;
this.getIssueList();
this.getIssueList(status_type);
};
openorder = (type) => {
@ -254,12 +260,11 @@ class order extends Component {
paix: "排序",
});
this.state.select_params = {
status_type: type,
search: undefined,
page: 1,
limit: 15,
};
this.getIssueList();
this.getIssueList(type);
};
// 筛选:全部、指派给我、由我创建
@ -269,7 +274,7 @@ class order extends Component {
isSpin: true,
});
if (type) {
if (current_user === undefined) {
if (!current_user) {
this.setState({
isSpin: false,
});
@ -304,8 +309,9 @@ class order extends Component {
this.state.select_params.assigned_to_id = undefined;
this.state.select_params.author_id = undefined;
}
const { status_type } = this.state;
this.getIssueList();
this.getIssueList(status_type);
};
deletedetail = (id) => {
@ -319,7 +325,9 @@ class order extends Component {
})
.then((result) => {
if (result) {
this.getIssueList();
const { status_type } = this.state;
this.getIssueList(status_type);
}
})
.catch((error) => {
@ -339,16 +347,18 @@ class order extends Component {
// 修改开始时间
changeBeginTime = (data, value) => {
const { status_type } = this.state;
this.setState({
begin: value
})
this.getIssueList(value, this.state.end);
this.getIssueList(status_type,value, this.state.end);
}
changeEndTime = (data, value) => {
const { status_type } = this.state;
this.setState({
end: value
})
this.getIssueList(this.state.begin, value);
this.getIssueList(status_type,this.state.begin, value);
}
// 选择列表里面的checkbox
@ -395,6 +405,11 @@ class order extends Component {
updateIssues=()=>{
const {checkedValue , select_params} = this.state;
const { projectsId } = this.props.match.params;
if(!select_params.update_author_id && !select_params.update_fixed_version_id &&!select_params.update_status_id ){
this.resetSelectParams();
return;
}
this.setState({
isSpin:true
})
@ -415,6 +430,12 @@ class order extends Component {
}
successFunc=()=>{
this.resetSelectParams();
const { status_type } = this.state;
this.getIssueList(status_type);
}
resetSelectParams=()=>{
let select_params = this.state.select_params;
select_params.update_author_id = undefined;
select_params.update_fixed_version_id = undefined;
@ -427,7 +448,6 @@ class order extends Component {
update_status_ids:"修改状态",
select_params
})
this.getIssueList();
}
// 批量删除

View File

@ -38,9 +38,17 @@ class order_form extends Component {
}
componentDidMount = () => {
this.check_is_login()
this.getSelectList();
this.get_detail();
};
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
}
get_detail = () => {
const { form_type } = this.props;
if (form_type === "new") {

View File

@ -56,11 +56,20 @@ class Collaborator extends Component {
}
componentDidMount = () => {
this.check_is_login()
if (this.props.project_id) {
this.getMember();
}
};
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
};
componentDidUpdate = (prevState) => {
if (
this.props.project_id &&
@ -468,7 +477,7 @@ class Collaborator extends Component {
<Spin spinning={isSpin}>
<div className="collaboratorList baseForm">
{listData ? (
{listData && listData.length>0 ? (
<Table
pagination={false}
columns={columns}

View File

@ -19,10 +19,18 @@ class Setting extends Component {
}
componentDidMount = () => {
this.check_is_login()
this.getCategory();
this.getLanguage();
this.getInfo();
};
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
};
getLanguage = () => {
const url = `/project_languages.json`;
axios

View File

@ -51,8 +51,16 @@ class NewTags extends Component {
}
componentDidMount = () => {
this.check_is_login();
this.getList();
};
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
};
getList = (page, order_name, order_type) => {
const { projectsId } = this.props.match.params;

View File

@ -25,6 +25,9 @@
.baseForm{
padding:15px 30px!important;
}
.collaboratorList{
min-height: 400px;
}
.iteminline{
display: flex;
align-items: center;
@ -172,6 +175,10 @@
}
.ant-table-tbody > tr > td{
border-bottom: none;
padding:15px 8px 15px 0px;
}
.ant-table-tbody > tr > td:last-child{
padding-right: 0px;
}
}

View File

@ -1,32 +1,35 @@
import React , { useState } from 'react';
import { Box , Long , Short , Gap , Banner , WhiteBack } from '../../Component/layout';
import { Box , Long , Short , Gap , WhiteBack } from '../../Component/layout';
import Title from '../../Component/Title';
import Setnav from '../../Component/Setnav';
import styled from 'styled-components';
const Div = styled.div`{
padding:18px 30px;
}`
import { Route, Switch } from "react-router-dom";
import Loadable from "react-loadable";
import Loading from "../../../Loading";
const Common = Loadable({
loader: () => import("./SettingCommon"),
loading: Loading,
});
export default (props)=>{
const pathname = props.location.pathname;
const organizeId = props.match.params.organizeId;
const memberId = props.match.params.memberId;
function returnActive (pathname){
let a = 0;
if(pathname === `/organize/${organizeId}/setting/member`){
if(pathname === `/organize/${organizeId}/member/${memberId}/setting/member`){
a = 1;
}else if(pathname === `/organize/${organizeId}/setting/group`){
}else if(pathname === `/organize/${organizeId}/member/${memberId}/setting/project`){
a = 2;
}else if(pathname === `/organize/${organizeId}/setting/hooks`){
a = 3;
}
return a;
}
const active = returnActive(pathname);
const array = {list:[
{name:'基本设置',icon:"icon-base",href:`/organize/${organizeId}/setting`},
{name:'团队成员管理',icon:"icon-zuzhichengyuan",href:`/organize/${organizeId}/setting/member`},
{name:'团队项目管理',icon:"icon-zuzhixiangmu",href:`/organize/${organizeId}/setting/group`},
{name:'基本设置',icon:"icon-base",href:`/organize/${organizeId}/member/${memberId}/setting`},
{name:'团队成员管理',icon:"icon-zuzhichengyuan",href:`/organize/${organizeId}/member/${memberId}/setting/member`},
{name:'团队项目管理',icon:"icon-zuzhixiangmu",href:`/organize/${organizeId}/member/${memberId}/setting/project`},
],
active
}
@ -38,10 +41,14 @@ export default (props)=>{
<Long>
<Gap>
<WhiteBack>
<Banner>团队项目管理</Banner>
<Div>
</Div>
<Switch>
<Route
path="/organize/:organizeId/member/:memberId/setting"
render={() => (
<Common {...props} />
)}
></Route>
</Switch>
</WhiteBack>
</Gap>
</Long>

View File

@ -0,0 +1,67 @@
import React , { useState } from 'react';
import { AutoComplete , Pagination } from 'antd';
import { Banner , Blueline , FlexAJ , Greenback , Redback } from '../../Component/layout';
import styled from 'styled-components';
const Option = AutoComplete.Option;
const Div = styled.div`{
padding:18px 30px;
}`;
const LIMIT = 15;
const demoData=[{name:"Python相关",id:1},{name:"Python相关",id:2}];
export default ()=>{
const [ searchKey , setSearchKey ] = useState(undefined);
const [ page , setPage ] = useState(1);
const [ total , setTotal ] = useState(0);
function changeInputUser(){}
function selectInputUser(){}
//
function ChangePage(page){
setPage(page);
}
const source = demoData && demoData.map((item,key)=>{
return(
<Option key={key} value={`${item.id}`}>{item.name}</Option>
)
})
return(
<div>
<Banner>团队项目管理</Banner>
<Div>
<FlexAJ className="actionNav">
<div>
<AutoComplete
dataSource={source}
value={searchKey}
style={{ width: 270 }}
onChange={changeInputUser}
onSelect={selectInputUser}
placeholder="搜索项目…"
/>
<Blueline className="ml30">+&nbsp;添加项目</Blueline>
</div>
<span>
<Greenback>添加所有</Greenback>
<Redback className="ml20">移除所有</Redback>
</span>
</FlexAJ>
<div className="GSlist">
<div>
<span>
caishi/前端v0.1
</span>
<a style={{color:"#F73030"}}>移除</a>
</div>
</div>
{
total > LIMIT ?
<div className="edu-txt-center mt30 mb20">
<Pagination simple defaultCurrent={page} total={total} pageSize={LIMIT} onChange={ChangePage}></Pagination>
</div>:""
}
</Div>
</div>
)
}

View File

@ -38,6 +38,7 @@
.teamDetail{
width: 1200px;
margin:0px auto;
padding-top:18px;
}
.list{
display: flex;
@ -322,3 +323,19 @@
}
}
// 组织团队设置
.actionNav{
padding:20px 30px;
background-color: #FAFAFA;
}
.GSlist{
padding-top:15px;
min-height: 400px;
&>div{
padding:20px 0px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #eee;
}
}

View File

@ -31,19 +31,19 @@ export default ((props)=>{
<Switch {...props}>
<Route
path="/organize/:organizeId/member/:memberId/setting"
render={(props) => {
render={() => {
return <GroupSetting {...props} />
}}
></Route>
<Route
path="/organize/:organizeId/setting"
render={(props) => {
render={() => {
return <Setting {...props} />
}}
></Route>
<Route
path="/organize/:organizeId"
render={(props) => {
render={() => {
return <DetailIndex {...props} />
}}
></Route>