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

# Conflicts:
#	src/AppConfig.js
#	src/forge/Main/Detail.js
This commit is contained in:
caishi 2020-07-02 16:07:35 +08:00
commit be354adac4
22 changed files with 635 additions and 429 deletions

View File

@ -5,6 +5,7 @@
"dependencies": { "dependencies": {
"@monaco-editor/react": "^2.3.0", "@monaco-editor/react": "^2.3.0",
"@novnc/novnc": "^1.1.0", "@novnc/novnc": "^1.1.0",
"actioncable": "^5.2.4-3",
"antd": "^3.26.15", "antd": "^3.26.15",
"array-flatten": "^2.1.2", "array-flatten": "^2.1.2",
"autoprefixer": "7.1.6", "autoprefixer": "7.1.6",

View File

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

View File

@ -29,4 +29,12 @@
color:#fff !important; color:#fff !important;
} }
.display-flex{display: flex !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

@ -59,52 +59,14 @@ function setpostcookie() {
} }
setpostcookie(); setpostcookie();
function railsgettimes(proxy) {
clearAllCookie()
if (timestamp && checkSubmitFlg === false) {
$.ajax({
url: proxy, async: true, success: function (data) {
if (data.status === 0) {
timestamp = data.message;
setpostcookie();
}
}
})
checkSubmitFlg = true
window.setTimeout(() => {
checkSubmitFlg = false;
}, 2000);
} else if (checkSubmitFlg === false) {
$.ajax({
url: proxy, async: true, success: function (data) {
if (data.status === 0) {
timestamp = data.message;
setpostcookie();
}
}
})
checkSubmitFlg = true
window.setTimeout(() => {
checkSubmitFlg = false;
}, 2000);
}
}
window._debugType = debugType; window._debugType = debugType;
export function initAxiosInterceptors(props) { export function initAxiosInterceptors(props) {
initOnlineOfflineListener() initOnlineOfflineListener()
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation // TODO 避免重复的请求 https://github.com/axios/axios#cancellation
// TODO 读取到package.json中的配置 var
var proxy = "http://localhost:3000" proxy = "http://localhost:3000"
// proxy = "https://pre-newweb.educoder.net" proxy = "https://testforgeplus.trustie.net"
proxy = "http://192.168.2.59:3000"
// 在这里使用requestMap控制避免用户通过双击等操作发出重复的请求
// 如果需要支持重复的请求考虑config里面自定义一个allowRepeat参考来控制
const requestMap = {}; const requestMap = {};
window.setfalseInRequestMap = function (keyName) { window.setfalseInRequestMap = function (keyName) {
requestMap[keyName] = false; requestMap[keyName] = false;
@ -115,19 +77,13 @@ export function initAxiosInterceptors(props) {
setpostcookie() setpostcookie()
clearAllCookie() clearAllCookie()
if (config.url.indexOf(proxy) != -1 || config.url.indexOf(':') != -1) { if (config.url.indexOf(proxy) !== -1 || config.url.indexOf(':') !== -1) {
return config return config
} }
requestProxy(config) requestProxy(config)
let url = `/api${config.url}`; let url = `/api${config.url}`;
//qq登录去掉api
if (config.params && config.params.redirect_uri !== undefined) {
if (config.params.redirect_uri.indexOf('otherloginqq') !== -1) {
url = `${config.url}`;
}
}
if (`${config[0]}` !== `true`) { if (`${config[0]}` !== `true`) {
if (window.location.port === "3007") { if (window.location.port === "3007") {
config.url = `${proxy}${url}`; config.url = `${proxy}${url}`;

View File

@ -241,7 +241,7 @@ class CoderRootDirectory extends Component {
message: item.commit && item.commit.message, message: item.commit && item.commit.message,
...item, ...item,
}); });
if (item.name === "README.md") { if (item.is_readme_file) {
readMeContent.push({ ...item }); readMeContent.push({ ...item });
readMeFile.push({ ...item }); readMeFile.push({ ...item });
} }
@ -348,7 +348,7 @@ class CoderRootDirectory extends Component {
dataIndex: 'name', dataIndex: 'name',
width:"30%", width:"30%",
render: (text,item) => ( 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} <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> </a>
), ),
@ -482,7 +482,7 @@ class CoderRootDirectory extends Component {
)} )}
</div> </div>
<div className="f-wrap-alignCenter"> <div className="f-wrap-alignCenter">
{subFileType && (isManager || isDeveloper) && ( {subFileType && parseInt(projectDetail.type) !== 2 && (isManager || isDeveloper) && (
<div> <div>
<span> <span>
<Link <Link

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react'; import React, { Component, Fragment } from 'react';
import { Spin, Tooltip } from 'antd'; import { Spin, Tooltip } from 'antd';
import { Link, Route, Switch } from 'react-router-dom'; import { Link, Route, Switch } from 'react-router-dom';
import { Content } from '../Component/layout'; import { Content } from '../Component/layout';
@ -57,39 +57,48 @@ const OrderMilepost = Loadable({
loader: () => import('../Order/Milepost'), loader: () => import('../Order/Milepost'),
loading: Loading, loading: Loading,
}) })
const OrdernewMilepost = Loadable({ const OrdernewMilepost = Loadable({
loader: () => import('../Order/newMilepost'), loader: () => import('../Order/newMilepost'),
loading: Loading, loading: Loading,
}) })
const OrderupdateMilepost = Loadable({ const OrderupdateMilepost = Loadable({
loader: () => import('../Order/UpdateMilepost'), loader: () => import('../Order/UpdateMilepost'),
loading: Loading, loading: Loading,
}) })
const OrderupdateDetail = Loadable({ const OrderupdateDetail = Loadable({
loader: () => import('../Order/UpdateDetail'), loader: () => import('../Order/UpdateDetail'),
loading: Loading, loading: Loading,
}) })
const OrdercopyDetail = Loadable({ const OrdercopyDetail = Loadable({
loader: () => import('../Order/CopyDetail'), loader: () => import('../Order/CopyDetail'),
loading: Loading, loading: Loading,
}) })
//合并请求 //合并请求
const MergeIndexDetail = Loadable({ const MergeIndexDetail = Loadable({
loader: () => import('../Merge/merge'), loader: () => import('../Merge/merge'),
loading: Loading, loading: Loading,
}) })
const CreateMerge = Loadable({ const CreateMerge = Loadable({
loader: () => import('../Merge/NewMerge'), loader: () => import('../Merge/NewMerge'),
loading: Loading, loading: Loading,
}) })
const MessageCount = Loadable({ const MessageCount = Loadable({
loader: () => import('../Merge/MessageCount'), loader: () => import('../Merge/MessageCount'),
loading: Loading, loading: Loading,
}) })
const UpdateMerge = Loadable({ const UpdateMerge = Loadable({
loader: () => import('../Merge/UpdateMerge'), loader: () => import('../Merge/UpdateMerge'),
loading: Loading, loading: Loading,
}) })
const MilepostDetail = Loadable({ const MilepostDetail = Loadable({
loader: () => import('../Order/MilepostDetail'), loader: () => import('../Order/MilepostDetail'),
loading: Loading, loading: Loading,
@ -106,6 +115,8 @@ const ForkUsers = Loadable({
loader: () => import('../UsersList/fork_users'), loader: () => import('../UsersList/fork_users'),
loading: Loading, loading: Loading,
}) })
const TrendsIndex = Loadable({ const TrendsIndex = Loadable({
loader: () => import('../Activity/Activity'), loader: () => import('../Activity/Activity'),
loading: Loading, loading: Loading,
@ -114,11 +125,11 @@ const TrendsIndex = Loadable({
/** /**
* permissionManager:管理员Reporter报告人员(只有读取权限)Developer开发人员除不能设置仓库信息外 * permissionManager:管理员Reporter报告人员(只有读取权限)Developer开发人员除不能设置仓库信息外
*/ */
class Detail extends Component { class Detail extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
isMirror: true,
projectDetail: undefined, projectDetail: undefined,
isManager: false, isManager: false,
isReporter: false, isReporter: false,
@ -133,7 +144,9 @@ class Detail extends Component {
author: undefined, author: undefined,
branchs: undefined, branchs: undefined,
branchList: undefined, branchList: undefined,
project: null project: null,
firstSync:false,
secondSync:false
} }
} }
@ -147,54 +160,64 @@ class Detail extends Component {
} }
} }
getProject = () => { getProject = (num) => {
const name = window.location.hostname === "localhost" ? "testforgeplus.trustie.net":window.location.hostname;
console.log(`ws:${name}/cable`);
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const url = `ws://192.168.2.59:3000/cable`; const url = `/projects/${projectsId}/simple.json`;
const scoket = new WebSocket(url); axios.get(url).then((result) => {
scoket.onopen=()=>{ if (result && result.data) {
scoket.send(JSON.stringify({ "id": `${projectsId}`}));
console.log(1);
}
scoket.onmessage=(result)=>{
console.log(2," ",result);
if(result){
this.setState({ this.setState({
project: result.data project: result.data
}) })
let mirror_status = result.data.mirror_status; if (result.data.type !== 0 && result.data.mirror_status === 1) {
// this.checkMirror(mirror_status); console.log("--------start channel --------");
scoket.close(); // 是镜像项目,且未完成迁移
this.canvasChannel();
if(num){
this.setState({
secondSync:true,
firsrtSync:false
})
}else{
this.setState({
firstSync:true,
secondSync:false
})
}
}else{
this.getDetail();
this.setState({
firsrtSync:false,
secondSync:false
})
}
} }
} })
scoket.onclose=(event)=>{
console.log(3," ",event);
}
// const url = `/projects/${projectsId}/simple.json`;
// axios.get(url).then((result) => {
// if (result) {
// this.setState({
// project: result.data
// })
// let mirror_status = result.data.mirror_status;
// this.checkMirror(mirror_status);
// }
// })
} }
checkMirror=(mirror_status)=>{ canvasChannel = () => {
if (!mirror_status || (mirror_status && mirror_status === 0)) { const name = window.location.hostname === "localhost" ? "http://testforgeplus.trustie.net":window.location.hostname;
this.setState({ console.log(`ws:${name}/cable`);
isMirror:false const actioncable = require("actioncable")
}) var project = this.state.project
this.getDetail(); var cable = actioncable.createConsumer(`ws:${name}/cable`);
} else { this.canvasChannel1 = cable.subscriptions.create({
this.setState({ channel: `MirrorProjectChannel`,
isMirror: true id: project && project.identifier
}) }, {
setTimeout(() => { connected: () => {
this.getProject(); console.log("###### channel connected! ######");
}, 600000); },
} disconnected: () => { },
received: data => {
console.log(`###### ---received data--- ######`);
console.log(data);
if (data) {
this.getDetail();
cable.subscriptions.consumer.disconnect();
}
}
})
} }
getDetail = () => { getDetail = () => {
@ -294,9 +317,8 @@ class Detail extends Component {
const url = `/repositories/${repo_id}/sync_mirror.json`; const url = `/repositories/${repo_id}/sync_mirror.json`;
axios.post(url).then(result => { axios.post(url).then(result => {
if (result && result.data && result.data.status === 0) { if (result && result.data && result.data.status === 0) {
this.props.showNotification("镜像同步成功!"); // this.props.showNotification("镜像同步成功!");
this.getProject(); this.getProject(2);
// this.getDetail();
} else { } else {
this.props.showNotification("镜像同步失败!"); this.props.showNotification("镜像同步失败!");
} }
@ -306,9 +328,9 @@ class Detail extends Component {
} }
render() { render() {
const { projectDetail, watchers_count, praises_count, forked_count, isManager, watched, praised, project, isMirror } = this.state; const { projectDetail, watchers_count, praises_count, forked_count, firstSync , secondSync , isManager, watched, praised, project } = this.state;
const url = this.props.history.location.pathname; const url = this.props.history.location.pathname;
const urlArr = url.split("/"); const urlArr = url.split("/");
const urlFlag = (urlArr.length === 3); const urlFlag = (urlArr.length === 3);
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
@ -340,7 +362,7 @@ class Detail extends Component {
<div className="detailHeader-wrapper"> <div className="detailHeader-wrapper">
<div className="normal"> <div className="normal">
<div className="f-wrap-between pb15" style={{ position: "relative" }}> <div className="f-wrap-between pb15" 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 && {project && project.author &&
<Link to={`/users/${project.author.login}`} className="show-user-link color-white"> <Link to={`/users/${project.author.login}`} className="show-user-link color-white">
{project.author.name} {project.author.name}
@ -361,95 +383,98 @@ class Detail extends Component {
{ {
projectDetail && checkLogin && projectDetail.type && projectDetail.type === 2 ? projectDetail && checkLogin && projectDetail.type && projectDetail.type === 2 ?
<Tooltip placement={'right'} title={mirror}> <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> : "" </Tooltip> : ""
} }
</span> </span>
</p> </p>
{ {
isMirror ? "" : firstSync ? "":
<span className="df mt25"> <span className="df mt25">
{ {
projectDetail && projectDetail.type && projectDetail.type === 2 ? projectDetail && projectDetail.type && projectDetail.type === 2 ?
<a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : "" <a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
} }
<span className="detail_tag_btn"> <span className="detail_tag_btn">
<a className="detail_tag_btn_name" onClick={() => this.focusFunc(watched)}> <a className="detail_tag_btn_name" onClick={() => this.focusFunc(watched)}>
<img src={watched ? img_focused : img_focus} alt="" width="14px" /> <img src={watched ? img_focused : img_focus} alt="" width="14px" />
{watched ? '取消关注' : '关注'} {watched ? '取消关注' : '关注'}
</a> </a>
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/watch_users`, state }}> <Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/watch_users`, state }}>
{watchers_count} {watchers_count}
</Link> </Link>
</span>
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" onClick={() => this.pariseFunc(praised)}>
<img src={praised ? img_parised : img_parise} width="13px" alt="" />
{praised ? '取消点赞' : '点赞'}
</a>
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/praise_users`, state }}>
{praises_count}
</Link>
</span>
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
<img src={img_fork} alt="" width="10px" />Fork</a>
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/fork_users`, state }}>
{forked_count}
</Link>
</span>
</span> </span>
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" onClick={() => this.pariseFunc(praised)}>
<img src={praised ? img_parised : img_parise} width="13px" alt="" />
{praised ? '取消点赞' : '点赞'}
</a>
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/praise_users`, state }}>
{praises_count}
</Link>
</span>
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
<img src={img_fork} alt="" width="10px" />Fork</a>
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${projectsId}/fork_users`, state }}>
{forked_count}
</Link>
</span>
</span>
} }
</div> </div>
{ {
isMirror ? "" : firstSync ? "" :
<div className="f-wrap-between pb20"> <div className="f-wrap-between pb20">
<ul className="headerMenu-wrapper"> <ul className="headerMenu-wrapper">
<li className={(url.indexOf("coders") > -1 || urlFlag) ? "active" : ""}> <li className={(url.indexOf("coders") > -1 || urlFlag) ? "active" : ""}>
<Link to={{ pathname: `/projects/${projectsId}/coders`, state }}> <Link to={{ pathname: `/projects/${projectsId}/coders`, state }}>
<img alt="" src={img_1} width="18" />代码库 <img alt="" src={img_1} width="18" />代码库
</Link> </Link>
</li> </li>
<li className={(url.indexOf("orders") > -1 && !(url.indexOf("Milepost") > 0 || url.indexOf("meilpost") > 0 || url.indexOf("tags") > 0)) ? "active" : ""}> <li className={(url.indexOf("orders") > -1 && !(url.indexOf("Milepost") > 0 || url.indexOf("meilpost") > 0 || url.indexOf("tags") > 0)) ? "active" : ""}>
<Link to={{ pathname: `/projects/${projectsId}/orders`, state }}> <Link to={{ pathname: `/projects/${projectsId}/orders`, state }}>
<img alt="" src={img_2} width="12" />任务 <img alt="" src={img_2} width="12" />任务
{projectDetail && projectDetail.issues_count ? <span>{projectDetail.issues_count}</span> : ""} {projectDetail && projectDetail.issues_count ? <span>{projectDetail.issues_count}</span> : ""}
</Link> </Link>
</li> </li>
{
projectDetail && parseInt(projectDetail.type) !== 2 &&
<li className={url.indexOf("merge") > -1 ? "active" : ""}> <li className={url.indexOf("merge") > -1 ? "active" : ""}>
<Link to={{ pathname: `/projects/${projectsId}/merge`, state }}> <Link to={{ pathname: `/projects/${projectsId}/merge`, state }}>
<img alt="" src={img_3} width="13" />合并请求 <img alt="" src={img_3} width="13" />合并请求
{projectDetail && projectDetail.pull_requests_count ? <span>{projectDetail.pull_requests_count}</span> : ""} {projectDetail && projectDetail.pull_requests_count ? <span>{projectDetail.pull_requests_count}</span> : ""}
</Link> </Link>
</li> </li>
<li className={(url.indexOf("Milepost") > -1 || url.indexOf("meilpost") > -1) ? "active" : ""}> }
<Link to={{ pathname: `/projects/${projectsId}/orders/Milepost`, state }}> <li className={(url.indexOf("Milepost") > -1 || url.indexOf("meilpost") > -1) ? "active" : ""}>
<img alt="" src={img_milepost} width="16" />里程碑 <Link to={{ pathname: `/projects/${projectsId}/orders/Milepost`, state }}>
<img alt="" src={img_milepost} width="16" />里程碑
{projectDetail && projectDetail.version_count && <span>{projectDetail.version_count}</span>} {projectDetail && projectDetail.version_count && <span>{projectDetail.version_count}</span>}
</Link>
</li>
<li className={url.indexOf("trends") > -1 ? "active" : ""}>
<Link to={{ pathname: `/projects/${projectsId}/trends`, state }}>
<img alt="" src={img_6} width="16" />动态
</Link> </Link>
</li> </li>
<li className={url.indexOf("trends") > -1 ? "active" : ""}> {
<Link to={{ pathname: `/projects/${projectsId}/trends`, state }}> isManager &&
<img alt="" src={img_6} width="16" />动态 <li className={url.indexOf("setting") > 0 ? "active" : ""}><Link to={`/projects/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
</Link> }
</li> </ul>
{ </div>
isManager &&
<li className={url.indexOf("setting") > 0 ? "active" : ""}><Link to={`/projects/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
}
</ul>
</div>
} }
</div> </div>
</div> </div>
{ {
isMirror ? firstSync ?
<Content className="spincontent"> <Content className="spincontent">
<Spin tip={project && `正在从 ${project.mirror_url} 迁移`} size="large"> <Spin className="spinstyle" tip={project && `正在从 ${project.mirror_url} 迁移`} size="large">
</Spin> </Spin>
</Content> </Content>
: :
<Spin spinning={false}> <Spin spinning={secondSync} className="spinstyle" tip="正在同步镜像" size="large">
<Switch {...this.props}> <Switch {...this.props}>
{/* 新建文件 */} {/* 新建文件 */}
<Route path="/projects/:projectsId/coders/:branch/newfile/:path" <Route path="/projects/:projectsId/coders/:branch/newfile/:path"
@ -510,8 +535,6 @@ class Detail extends Component {
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} {...common} />) (props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
{/* 里程碑页面新建任务 */} {/* 里程碑页面新建任务 */}
<Route path="/projects/:projectsId/orders/:milepostId/new" <Route path="/projects/:projectsId/orders/:milepostId/new"
render={ render={
@ -524,54 +547,45 @@ class Detail extends Component {
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />) (props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
{/* 修改详情 */} {/* 修改详情 */}
<Route path="/projects/:projectsId/orders/:orderId/updatedetail" <Route path="/projects/:projectsId/orders/:orderId/updatedetail"
render={ render={
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />) (props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
{/* 复制详情 */} {/* 复制详情 */}
<Route path="/projects/:projectsId/orders/:orderId/copyetail" <Route path="/projects/:projectsId/orders/:orderId/copyetail"
render={ render={
(props) => (<OrdercopyDetail {...this.props} {...props} {...this.state} {...common} />) (props) => (<OrdercopyDetail {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
{/* 动态 */} {/* 动态 */}
<Route path="/projects/:projectsId/trends" <Route path="/projects/:projectsId/trends"
render={ render={
(props) => (<TrendsIndex {...this.props} {...props} {...this.state} {...common} />) (props) => (<TrendsIndex {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
{/* 代码Index */} {/* 代码Index */}
<Route path="/projects/:projectsId/orders" <Route path="/projects/:projectsId/orders"
render={ render={
(props) => (<OrderIndex {...this.props} {...props} {...this.state} {...common} />) (props) => (<OrderIndex {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
<Route path="/projects/:projectsId/merge/new" <Route path="/projects/:projectsId/merge/new"
render={ render={
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />) (props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)
} }
></Route> ></Route>
<Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge" <Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge"
render={ render={
(props) => (<UpdateMerge {...this.props} {...props} {...this.state} {...common} />) (props) => (<UpdateMerge {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
<Route path="/projects/:projectsId/merge/:mergeId/Messagecount" <Route path="/projects/:projectsId/merge/:mergeId/Messagecount"
render={ render={
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />) (props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
} }
></Route> ></Route>
<Route path="/projects/:projectsId/merge/:mergeId/MergeSubmit" <Route path="/projects/:projectsId/merge/:mergeId/MergeSubmit"
render={ render={
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />) (props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)

View File

@ -195,7 +195,7 @@
.spincontent{ .spincontent{
height:400px; height:400px;
} }
.spincontent .ant-spin-text{ .spinstyle .ant-spin-text{
margin-top:30px; margin-top:30px;
color: #888; color: #888;
} }

View File

@ -2,7 +2,7 @@ import React, { Component } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { Popconfirm, Tag } from "antd"; import { Popconfirm, Tag } from "antd";
import { getImageUrl } from "educoder"; import { getImageUrl } from "educoder";
import "./merge.css" import "./merge.css";
class MergeItem extends Component { class MergeItem extends Component {
constructor(props) { constructor(props) {
@ -42,7 +42,7 @@ class MergeItem extends Component {
}; };
render() { render() {
const { issues, project_name } = this.props; const { issues, project_name, project_author_name } = this.props;
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;
const { current_user } = this.props; const { current_user } = this.props;
const renderList = () => { const renderList = () => {
@ -60,7 +60,11 @@ class MergeItem extends Component {
{item.name} {item.name}
</Link> </Link>
<Tag className={`pr_tags_${item.pull_request_staus}`}> <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> </Tag>
</p> </p>
<p className="grid-item font-13"> <p className="grid-item font-13">
@ -92,21 +96,33 @@ class MergeItem extends Component {
</span> </span>
<span className="color-grey-8">{item.pr_time}</span> <span className="color-grey-8">{item.pr_time}</span>
<span className="ml15"> <span className="ml15">
<Tag> <Tag className="pr-branch-tag">
<Link <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> </Link>
</Tag> </Tag>
<span className="mr8 ver-middle"> <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> </span>
<Tag> <Tag className="pr-branch-tag">
<Link <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> </Link>
</Tag> </Tag>
</span> </span>
@ -133,7 +149,7 @@ class MergeItem extends Component {
)} )}
</li> </li>
<li>{item.version || "--"}</li> <li>{item.version || "--"}</li>
<li> <li>
<div <div
className="flex1 df" className="flex1 df"

View File

@ -256,12 +256,12 @@ class MessageCount extends Component {
</div> </div>
{ {
<div className="mt15"> <div className="mt15">
<Tag> <Tag className="pr-branch-tag">
<Link <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" 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> </Link>
</Tag> </Tag>
<span className="mr8 ver-middle"> <span className="mr8 ver-middle">
@ -271,12 +271,13 @@ class MessageCount extends Component {
} }
></i> ></i>
</span> </span>
<Tag> <Tag className="pr-branch-tag">
<Link <Link
to={`projects/${projectsId}/coders?branch=${data.pull_request.base}`} to={`/projects/${projectsId}/coders?branch=${data.pull_request.base}`}
className="ver-middle" 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> </Link>
</Tag> </Tag>
</div> </div>

View File

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

View File

@ -57,13 +57,13 @@ class UpdateMerge extends Component {
<div className="merge-header width100 inline-block"> <div className="merge-header width100 inline-block">
<div className="width45 pull-left"> <div className="width45 pull-left">
<div className="color-grey-3 mb10 fwb">源分支:</div> <div className="color-grey-3 mb10 fwb">源分支:</div>
<Input.Group compact className="display-flex"> <Input.Group compact className="display-flex">
<Button className="merge-header-button maxW50 hide-1 task-hide"> <Button className="merge-header-button maxW50 hide-1 task-hide">
{data && data.project_author} /{" "} {data.is_original ? `${data.fork_project_user_name}/${data.fork_project_identifier}` : `${data.project_author}/${data.project_name}`}
{data && data.project_name}
</Button> </Button>
<Select <Select
defaultValue={pull ? pull : "master"} defaultValue={data.is_original ? `${data.fork_project_user}:${pull}` : `${pull}`}
className="minW50 merge-flex1" className="minW50 merge-flex1"
disabled disabled
></Select> ></Select>
@ -79,11 +79,10 @@ class UpdateMerge extends Component {
<div className="color-grey-3 mb10 fwb">目标分支:</div> <div className="color-grey-3 mb10 fwb">目标分支:</div>
<Input.Group compact className="display-flex"> <Input.Group compact className="display-flex">
<Button className="merge-header-button maxW50 hide-1 task-hide"> <Button className="merge-header-button maxW50 hide-1 task-hide">
{data && data.project_author} /{" "} {`${data.project_author}/${data.project_name}`}
{data && data.project_name}
</Button> </Button>
<Select <Select
defaultValue={merge ? merge : "master"} defaultValue={data.is_original ? `${data.project_login}:${merge}` : `${merge}`}
className="minW50 merge-flex1" className="minW50 merge-flex1"
disabled disabled
></Select> ></Select>
@ -105,9 +104,9 @@ class UpdateMerge extends Component {
)} )}
</Spin> </Spin>
</div> </div>
<div className=" main"> {/* <div className=" main">
<MergeFooter footer_type="new" {...this.props}></MergeFooter> <MergeFooter footer_type="new" {...this.props}></MergeFooter>
</div> </div> */}
</div> </div>
); );
} }

View File

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

View File

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

View File

@ -1,5 +1,5 @@
import React, { Component } from "react"; 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 axios from "axios";
import "../Order/order.css"; import "../Order/order.css";
@ -21,21 +21,55 @@ class MergeForm extends Component {
mergedata: undefined, mergedata: undefined,
priority_id: undefined, priority_id: undefined,
title: undefined, title: undefined,
members: undefined,
issue_tags: undefined,
issue_versions: undefined,
issue_priories: undefined,
}; };
} }
componentDidMount = () => { componentDidMount = () => {
this.check_is_login();
this.get_default_selects();
this.set_defatul(); 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 = () => { set_defatul = () => {
const { data, merge_type } = this.props; const { data, merge_type } = this.props;
if (data && merge_type === "edit") { if (data && merge_type === "edit") {
this.setState({ this.setState({
desc: data.body, desc: data.body,
issue_tag_ids: data.issue_tag_ids[0], issue_tag_ids: data.issue_tag_ids ? data.issue_tag_ids[0] : undefined,
fixed_version_id: String(data.fixed_version_id), fixed_version_id: data.fixed_version_id ? String(data.fixed_version_id) : undefined,
assigned_to_id: String(data.assigned_to_id), assigned_to_id: data.assigned_to_id ? String(data.assigned_to_id) : undefined,
priority_id: String(data.priority_id), priority_id: data.priority_id ? String(data.priority_id) :undefined,
title: data.title, title: data.title,
}); });
} }
@ -99,13 +133,13 @@ class MergeForm extends Component {
this.props.form.validateFieldsAndScroll((err, values) => { this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
const { projectsId, mergeId } = this.props.match.params; 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) { if (values.issue_tag_ids && values.issue_tag_ids.length > 0) {
values.issue_tag_ids = [parseInt(values.issue_tag_ids)]; values.issue_tag_ids = [parseInt(values.issue_tag_ids)];
} else { } else {
values.issue_tag_ids = []; values.issue_tag_ids = [];
} }
const { desc } = this.state; const { desc } = this.state;
if (merge_type === "new") { if (merge_type === "new") {
let url = `/projects/${projectsId}/pull_requests.json`; let url = `/projects/${projectsId}/pull_requests.json`;
axios axios
@ -114,6 +148,9 @@ class MergeForm extends Component {
body: desc, body: desc,
head: pull, head: pull,
base: merge, 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) => { .then((result) => {
if (result) { if (result) {
@ -121,6 +158,8 @@ class MergeForm extends Component {
isSpin: false, isSpin: false,
}); });
this.props.history.push(`/projects/${projectsId}/merge`); this.props.history.push(`/projects/${projectsId}/merge`);
const { getDetail } = this.props;
getDetail && getDetail();
} else { } else {
this.setState({ this.setState({
isSpin: false, isSpin: false,
@ -136,30 +175,32 @@ class MergeForm extends Component {
} else { } else {
let url = `/projects/${projectsId}/pull_requests/${mergeId}.json`; let url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
axios axios
.put(url, { .put(url, {
...values, ...values,
body: desc, body: desc,
head: pull, head: pull,
base: merge, base: merge,
}) })
.then((result) => { .then((result) => {
if (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({ this.setState({
isSpin: false, isSpin: false,
}); });
this.props.history.push(`/projects/${projectsId}/merge/${mergeId}/Messagecount`); console.log(error);
} else {
this.setState({
isSpin: false,
});
}
})
.catch((error) => {
this.setState({
isSpin: false,
}); });
console.log(error);
});
} }
} else { } else {
this.setState({ this.setState({
@ -187,130 +228,136 @@ class MergeForm extends Component {
desc, desc,
isSpin, isSpin,
title, title,
members,
issue_tags,
issue_versions,
issue_priories,
} = this.state; } = this.state;
return ( return (
<div> <div>
<div className="mt20 mb20"> <Spin spinning={isSpin}>
<span className="font-16 fwb mr10 ver-middle"> <div className="mt20 mb20">
{merge_type === "new" ? "新建" : "编辑"}合并请求: <span className="font-16 fwb mr10 ver-middle">
</span> {merge_type === "new" ? "新建" : "编辑"}合并请求:
<Tag color="#28BD6C" className="ver-middle"> </span>
可合并的 <Tag color="#28BD6C" className="ver-middle">
</Tag> 可合并的
</div> </Tag>
<Form> </div>
<div className="width100 inline-block"> <Form>
<div className="width70 pull-left"> <div className="width100 inline-block">
<Form.Item> <div className="width70 pull-left">
{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> <Form.Item>
{getFieldDecorator("assigned_to_id", { {getFieldDecorator("title", {
initialValue: assigned_to_id, rules: [
})( {
<Select placeholder="审查人员" showSearch> required: true,
{this.renderSelect(data && data.members)} message: "请填写请求标题",
</Select> },
)} ],
</Form.Item> initialValue: title,
<Form.Item> })(<Input placeholder="标题" />)}
{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>
</Form.Item> </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> </div>
</div> </Form>
</Form> </Spin>
</div> </div>
); );
} }

View File

@ -7,7 +7,7 @@ class Nodata extends Component{
<div className="none_panels"> <div className="none_panels">
<div> <div>
<div className="mb15"> <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> </div>
<h3>欢迎使用合并请求</h3> <h3>欢迎使用合并请求</h3>

View File

@ -41,21 +41,22 @@ class Index extends Component {
ignore_name: undefined ignore_name: undefined
} }
} }
getUserInfo = () => { // getUserInfo = () => {
const url = `/users/me.json`; // const url = `/users/me.json`;
axios.get(url).then(result => { // axios.get(url).then(result => {
if (result && result.data.login) { // if (result && result.data.login) {
this.setState({ // this.setState({
current_user: result.data // current_user: result.data
}) // })
this.getDetail(); // this.getDetail();
} // }
}).catch(error => { // }).catch(error => {
console.log(error) // console.log(error)
}) // })
} // }
componentDidMount = () => { componentDidMount = () => {
// this.getUserInfo(); // this.getUserInfo();
this.check_is_login()
// 获取项目类别 // 获取项目类别
this.getCategory(); this.getCategory();
// 获取项目语言 // 获取项目语言
@ -64,6 +65,14 @@ class Index extends Component {
this.getGitignore(); this.getGitignore();
// 获取开源许可证 // 获取开源许可证
this.getLicenses(); this.getLicenses();
}
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
} }
getCategory = () => { getCategory = () => {
const url = `/project_categories.json` const url = `/project_categories.json`

View File

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

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) => { onPanelChange = (time, mode) => {
this.setState({ this.setState({
value: time value: time

View File

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

View File

@ -56,11 +56,20 @@ class Collaborator extends Component {
} }
componentDidMount = () => { componentDidMount = () => {
this.check_is_login()
if (this.props.project_id) { if (this.props.project_id) {
this.getMember(); this.getMember();
} }
}; };
check_is_login =() =>{
const { current_user } = this.props;
if(!current_user){
this.props.history.push("/403")
return
}
};
componentDidUpdate = (prevState) => { componentDidUpdate = (prevState) => {
if ( if (
this.props.project_id && this.props.project_id &&

View File

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

View File

@ -51,8 +51,16 @@ class NewTags extends Component {
} }
componentDidMount = () => { componentDidMount = () => {
this.check_is_login();
this.getList(); 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) => { getList = (page, order_name, order_type) => {
const { projectsId } = this.props.match.params; const { projectsId } = this.props.match.params;