forgeplus-react/src/forge/Main/Detail.js

1014 lines
35 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { Component } from 'react';
import { Spin, Tooltip , Button } from 'antd';
import { Link, Route, Switch } from 'react-router-dom';
import { withRouter } from "react-router";
import { connect } from 'react-redux';
import { Content, AlignTop } from '../Component/layout';
import DetailBanner from './sub/DetailBanner';
import CoderDepot from './CoderDepot'
import cookie from 'react-cookies';
import { setSeoMeta } from 'educoder';
import { Base64 } from 'js-base64';
import { setProject, setProjectDetail, setProjectEntries, setProjectMenuList, setProjectReadMe } from '../../redux/actions/server';
import actions from '../../redux/actions';
import types from '../../redux/actions/actionTypes'
import { getProjectFunc, getProjectDetailFunc } from '../../services/project'
import '../css/index.scss'
import './list.scss';
import '../../modules/courses/css/Courses.css'
import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC";
import { unInstallMarketBot } from "../../softbot/api";
import Loadable from 'react-loadable';
import Loading from '../../Loading';
import axios from 'axios';
import { async } from 'q';
const Setting = Loadable({
loader: () => import('../Settings/Index'),
loading: Loading,
})
const OrderIndex = Loadable({
loader: () => import('../Issues/index'),
loading: Loading,
})
const CoderRootIndex = Loadable({
loader: () => import('./CoderRootIndex'),
loading: Loading,
})
const OrderMilepost = Loadable({
loader: () => import('../Order/Milepost'),
loading: Loading,
})
const OrdernewMilepost = Loadable({
loader: () => import('../Order/newMilepost'),
loading: Loading,
})
const OrderupdateMilepost = Loadable({
loader: () => import('../Order/UpdateMilepost'),
loading: Loading,
})
//合并请求
const MergeIndexDetail = Loadable({
loader: () => import('../Merge/merge'),
loading: Loading,
})
const CreateMerge = Loadable({
loader: () => import('../Merge/CreateMerge'),
loading: Loading,
})
const MessageCount = Loadable({
loader: () => import('../Merge/MessageCount'),
loading: Loading,
})
const UpdateMerge = Loadable({
loader: () => import('../Merge/UpdateMerge'),
loading: Loading,
})
const MilepostDetail = Loadable({
loader: () => import('../Order/MilepostDetail.jsx'),
loading: Loading,
})
const WatchUsers = Loadable({
loader: () => import('../UsersList/watch_users'),
loading: Loading,
})
const PraiseUsers = Loadable({
loader: () => import('../UsersList/praise_users'),
loading: Loading,
})
const ForkUsers = Loadable({
loader: () => import('../UsersList/fork_users'),
loading: Loading,
})
const Contribute = Loadable({
loader: () => import('./sub/Contribute'),
loading: Loading,
})
const CoderRootCommit = Loadable({
loader: () => import('./CoderRootCommit'),
loading: Loading,
})
// const CoderDepot = Loadable({
// loader: () => import('./CoderDepot'),
// loading: Loading,
// })
const TrendsIndex = Loadable({
loader: () => import('../Activity/Activity'),
loading: Loading,
})
const DataSetIndex = Loadable({
loader: () => import('../Dataset/Index'),
loading: Loading,
})
const DataSetUpload = Loadable({
loader: () => import('../Dataset/component/uploadModal'),
loading: Loading,
})
const DevAbout = Loadable({
loader: () => import('../About/Index'),
loading: Loading,
})
const Source = Loadable({
loader: () => import('../Source/Index'),
loading: Loading,
})
const Server = Loadable({
loader: () => import('../Server/Index'),
loading: Loading,
})
const DevIndex = Loadable({
loader: () => import('../DevOps/Index'),
loading: Loading,
});
const Wiki = Loadable({
loader: () => import('../Wiki/Index'),
loading: Loading,
});
const WikiEdit = Loadable({
loader: () => import('../Wiki/EditWiki'),
loading: Loading,
});
const Invite = Loadable({
loader: () => import('../Invite/Index'),
loading: Loading,
});
const Review = Loadable({
loader: () => import('../Newfile/codeReview'),
loading: Loading,
});
/**
* permissionManager:管理员Reporter报告人员(只有读取权限)Developer开发人员除不能设置仓库信息外
*/
function checkPathname(projectsId, owner, pathname) {
let name = "";
if (pathname && pathname !== `/${owner}/${projectsId}`) {
let url = pathname.split(`/${owner}/${projectsId}`)[1] || "";
if (url.indexOf("/about") > -1) {
name = "about"
} else if (url.indexOf("/issues") > -1 || url.indexOf("Milepost") > 0) {
name = "issues";
} else if (url.indexOf("/pulls") > -1 || url.indexOf("/compare") > -1) {
// /pulls合并请求除新建合并请求外
// /compare新建合并请求
name = "pulls"
} else if (url.indexOf("/milestones") > -1) {
name = "milestones"
} else if (url.indexOf("/activity") > -1) {
name = "activity"
} else if (url.indexOf("/settings") > -1) {
name = "settings"
} else if (url.indexOf("/dataset") > -1) {
name = "dataset"
} else if (url.indexOf(`/devops`) > -1) {
name = "devops"
} else if (url.indexOf(`/source`) > -1) {
name = "source"
} else if (url.indexOf(`/wiki`) > -1) {
name = "wiki"
} else if (url.indexOf(`/service`) > -1) {
name = "server"
}
}
return name;
}
class Detail extends Component {
constructor(props) {
super(props);
this.state = {
projectDetail: props.defaultDetail || undefined,
isManager: false,
isReporter: false,
isDeveloper: false,
project_id: undefined,
watchers_count: undefined,
praises_count: undefined,
forked_count: undefined,
watched: false,
praised: false,
http_url: undefined,
branchs: undefined,
branchList: undefined,
project: props.projectBase || undefined,
firstSync: false,
secondSync: false,
open_devops: false,
forkSpin: false,
// 默认分支
defaultBranch: undefined,
// 非本平台项目
platform: false,
mirror_status:0,
bannerList: props.projectMenu || []
}
}
componentDidMount = () => {
// this.getProject();
let history = this.props.location;
this.clearIssueCookies(history);
if (this.props.clearProject) {
const typeList = [ types.GET_PROJECT_BASE, types.GET_PROJECT_DETAIL, types.GET_PROJECT_ENTRIES, types.GET_PROJECT_MENU, types.GET_PROJECT_README ]
typeList.forEach(e => {
this.props.clearProject(e)
})
}
}
componentDidUpdate = async (prevState) => {
let prevParam = prevState.match.params;
let propsParam = this.props.match.params;
if (prevState && this.props && (prevParam.projectsId !== propsParam.projectsId || prevParam.owner !== propsParam.owner)) {
const { projectsId, owner } = this.props.match.params;
const data = await getProjectFunc(owner, projectsId);
if (data.data) {
this.getProject(data.data)
}
}
this.props.history.listen((history) => {
// 非issue链接地址清除cookie states具体保存和操作在order.js页面
this.clearIssueCookies(history);
})
}
clearIssueCookies = (history) => {
const { pathname } = history;
const { projectsId, owner } = this.props.match.params;
let currentIssue = pathname.indexOf(`/${owner}/${projectsId}/issues`) === -1;
if (currentIssue) {
cookie.save('states', undefined, { expires: 0, path: `/` });
cookie.save('issuestates', undefined, { expires: 0, path: `/` });
}
}
async componentWillMount() {
const { projectsId, owner } = this.props.match.params;
if (!this.props.projectBase) {
const data = await getProjectFunc(owner, projectsId);
if (data && data.data) {
this.getProject(data.data)
}
} else {
this.getProject(this.props.projectBase)
}
}
componentWillUnmount() {
this.timerChannel && clearTimeout(this.timerChannel);
}
getProject = async (data) => {
const { projectsId, owner } = this.props.match.params;
this.setState({
project: data,
open_devops: data.open_devops,
platform: data.platform && data.platform !== 'educoder'
})
if (data.type !== 0 && data.mirror_status === 1) {
console.log("--------start channel --------");
this.setState({
firstSync: true,
secondSync: false,
mirror_status:1
})
// 是镜像项目,且未完成迁移
this.canvasChannel();
} else {
this.setState({
firstSync: false,
secondSync: false,
mirror_status:data.mirror_status || 0
})
this.getBanner(this.props.projectMenu)
let projectdata
if (this.props.defaultDetail) {
projectdata = this.props.defaultDetail
} else {
const res = await getProjectDetailFunc(owner, projectsId, !window.location.host);
if (res && res.status === 200) {
projectdata = res.data
}
}
if (projectdata) {
this.getDetail(projectdata)
}
}
}
// 工作流激活后修改状态
changeOpenDevops = (flag) => {
this.setState({
open_devops: flag
})
}
/**
*
* @param {*} deleteFlag :同步镜像需要提示成功,且未成功的情况下不需要删除项目
*/
canvasChannel = (deleteFlag) => {
const name = window.location.hostname === "localhost" ? "testforgeplus.trustie.net" : window.location.hostname;
const actioncable = require("actioncable");
var project = this.state.project;
var cable = actioncable.createConsumer(`wss://${name}/cable`);
this.canvasChannel1 = cable.subscriptions.create({
channel: `MirrorProjectChannel`,
id: project && project.id
}, {
connected: () => {
console.log("###### channel connected! ######");
},
disconnected: () => {
console.log("###### cannot connected! ######");
},
received: async data => {
console.log(`###### ---received data--- ######`);
if (data) {
console.log("start ----",data)
if (deleteFlag) {
this.setState({
firstSync: false,
mirror_status:data.project && data.project.mirror_status,
secondSync: false
});
this.props.showNotification("镜像同步成功!");
window.location.reload();
}
// else {
if (data.status === -1) {
// this.deleteProjectBack();
// const projectdata = await getProjectDetailFunc(owner, projectsId, !window.location.host).data;
// this.getDetail(projectdata)
// this.getBanner();
this.toMirrorFunc();
}
// }
// this.reloadDetail();
cable.subscriptions.consumer.disconnect();
}
},
onerror: () => {
console.log("###### cannot connected! ######");
}
});
// 如果是火狐由于部分版本ws不能连接成功故增加刷新
// if(navigator.userAgent.indexOf("Firefox")>-1){
this.timerChannel = setTimeout(this.reloadDetail, 10000);
// }
}
reloadDetail = () => {
if (this.state.firstSync || this.state.secondSync) {
window.location.reload();
}
}
toMirrorFunc=()=>{
let hash = '/projects/mirror/new';
this.props.history.push({
pathname: hash,
mirror_status: 2
});
}
// deleteProjectBack = () => {
// const { history } = this.props;
// const { projectsId, owner } = this.props.match.params;
// axios.delete(`/${owner}/${projectsId}.json`).then(res => {
// let hash = '/projects/mirror/new';
// if (res && res.data) {
// history.push({
// pathname: hash,
// mirror_status: 2
// });
// }
// else {
// window.location.hash = hash;
// }
// });
// }
getDetail = async (data) => {
const { projectsId, owner } = this.props.match.params;
if (!data) {
const url = `/${owner}/${projectsId}/detail.json`;
const res = await axios.get(url)
if (res.data) {
data = res.data
}
}
if (data) {
if (data.status === 404) {
if (window.location.pathname.includes('/invite')) {
let inviteString = window.location.search && window.location.search.split('?invite=')[1];
let inviteData = inviteString && JSON.parse(Base64.decode(inviteString));
const { project = {}, projectDetail = {} } = this.state
this.setState({
project: Object.assign(project, { author: { name: inviteData.ownerName } }),
projectDetail: Object.assign(projectDetail, { name: inviteData.projectName })
});
} else {
this.props.history.push('/nopage');
}
} else {
this.setState({
projectDetail: data,
project_id: data.project_id,
isManager: data.permission && (data.permission === "Manager" || data.permission === "Admin" || data.permission === "Owner"),
isReporter: data.permission && data.permission === "Reporter",
isDeveloper: data.permission && data.permission === "Developer",
http_url: data.clone_url,
praised: data.praised,
watched: data.watched,
watchers_count: data.watchers_count,
praises_count: data.praises_count,
forked_count: data.forked_count,
defaultBranch: data.default_branch
});
// seo优化设置
let keyWords=`${owner},${projectsId}${ data.topics && data.topics.length > 0 && ','}${ data.topics && data.topics.length > 0 && data.topics.map(item => item.name).join(',') }`;
let title= `${owner}/${projectsId}${data.description?''+data.description:''}`;
setSeoMeta(keyWords,title,data.description || '',`/${owner}/${projectsId}`,owner,projectsId);
}
}
}
// 获取动态导航栏菜单
async getBanner(data) {
const { projectsId, owner } = this.props.match.params;
if (!data) {
const url = `/${owner}/${projectsId}/menu_list.json`;
const res = await axios.get(url)
if (res.data) {
data = res.data
}
}
if (data) {
this.setState({
bannerList: data
})
}
}
// 关注和取消关注
focusFunc = (flag) => {
const { platform } = this.state;
if (!platform) return;
const { project_id } = this.state;
axios({
method: flag ? 'delete' : 'post',
url: `/watchers/${flag ? 'unfollow' : 'follow'}.json`,
params: {
target_type: "project",
id: project_id
}
}).then(result => {
if (result && result.data.status === 0) {
this.setWatchersCount(result.data.watchers_count, result.data.watched);
}
})
.catch(error => {
console.log(error);
});
!flag && this.props.showNpsModal("indexProject", 1);
}
// 点赞和取消点赞
pariseFunc = (flag) => {
const { platform } = this.state;
if (!platform) return;
const { project_id } = this.state;
axios({
method: flag ? 'delete' : 'post',
url: `/projects/${project_id}/praise_tread/${flag ? 'unlike' : 'like'}.json`
}).then(result => {
if (result && result.data.status === 0) {
this.setPraisesCount(result.data.praises_count, result.data.praised)
}
})
.catch(error => {
console.log(error);
});
!flag && this.props.showNpsModal("indexProject", 2);
}
setWatchersCount = (count, is_watched) => {
this.setState({
watched: is_watched,
watchers_count: count
})
}
setPraisesCount = (count, is_praised) => {
this.setState({
praised: is_praised,
praises_count: count
})
}
// fork项目
forkFunc = () => {
const { platform } = this.state;
if (!platform) return;
this.setState({
forkSpin: true
})
const { current_user } = this.props
const { projectsId, owner } = this.props.match.params;
const url = `/${owner}/${projectsId}/forks.json`;
axios.post(url).then(result => {
if (result && result.data.status === 0) {
if (result.data.message === "fork失败你已拥有了这个项目") {
this.props.history.push(`/${current_user && current_user.login}/${projectsId}`);
return;
}
this.props.history.push(`/${current_user && current_user.login}/${result.data.identifier}`);
this.props.showNotification(result.data.message);
this.props.showNpsModal("indexProject", 3);
}
this.setState({
forkSpin: false
})
}).catch(error => {
this.setState({
forkSpin: false
})
})
}
// 同步镜像
synchronismMirror = () => {
const { isManager } = this.state;
const { current_user , showLoginDialog } = this.props;
if(!(current_user && current_user.login)){
showLoginDialog();
return
}
if((current_user && current_user.admin) || isManager){
const { platform } = this.state;
if (!platform) return;
const { projectsId, owner } = this.props.match.params;
const url = `/${owner}/${projectsId}/sync_mirror.json`;
axios.post(url).then(result => {
if (result && result.data && result.data.status === 0) {
this.setState({
secondSync: true
})
this.canvasChannel(true);
} else {
this.props.showNotification("镜像同步失败!");
}
}).catch(error => {
console.log(error);
})
}
}
textFunc = (forked_from_project_id, fork_info) => {
return forked_from_project_id && fork_info ?
<div className="color-grey-9 df">
<span>复刻自</span>
<Link to={`/${fork_info.fork_project_user_login}`} className="show-user-link color-grey-6 ml5">{fork_info.fork_project_user_name}</Link>
<span> / </span>
<Link to={`/${fork_info.fork_project_user_login}/${fork_info.fork_project_identifier}`} className="color-grey-6 task-hide flex1" style={{ maxWidth: "400px" }} title={fork_info.fork_form_name}>{fork_info.fork_form_name}</Link>
</div> : ""
}
// 删除仓库
deleteProject = () => {
const { projectsId , owner } = this.props.match.params;
const { projectName } = this.state;
this.props.confirm({
content: <span style={{display:"block",textAlign:"left"}}>该操作无法撤销且将会一并删除相关的疑修合并请求工作流里程碑动态等数据<br/>是否确认删除 <span style={{fontWeight:"bold"}}>{owner}/{projectName}({projectsId})</span></span>,
onOk: () => {
const url = `/${owner}/${projectsId}.json`;
axios.delete(url).then((result) => {
window.scrollTo(0,0);
this.props.showNotification("仓库删除成功!");
this.props.history.push(`/${owner}`);
})
.catch((error) => {
console.log(error);
});
},
});
};
render() {
const { projectDetail, watchers_count, praises_count,
forked_count, firstSync, secondSync, watched, praised,
project, open_devops, platform, defaultBranch, bannerList, forkSpin , mirror_status } = this.state;
const url = this.props.history.location.pathname;
const urlArr = url.split("/");
const urlFlag = (urlArr.length === 3);
const { projectsId, owner } = this.props.match.params;
const { current_user } = this.props;
let pathname = checkPathname(projectsId, owner, url);
const { state } = this.props.history.location;
const common = {
getDetail: this.getDetail,
getBanner: this.getBanner,
getProject:this.getProject,
changeOpenDevops: this.changeOpenDevops,
defaultBranch
}
return (
<div>
<div className="detailHeader-wrapper">
<div className="normal">
<div className="AlignTop" style={{ padding: "18px 0px 10px", justifyContent: "space-between" }}>
<div>
<div className="AlignTop">
<div className="projectallName">
{project && project.author &&
<Link to={`/${project.author.login}`}>{project.author.name}</Link>
}
<span className="ml5 mr5">/</span>
<Link to={`/${owner}/${projectsId}`} className="projectN mt6">{projectDetail && projectDetail.name}</Link>
</div>
{projectDetail && projectDetail.private && <span className="privateTag mt6">私有</span>}
{!platform && <span className="privateTag red mt6">只读</span>}
</div>
<div className="mt8">
{
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
this.textFunc(projectDetail.forked_from_project_id, projectDetail.fork_info)
: ""
}
</div>
</div>
<div>
{
firstSync ? "" :
<span className="df">
{
(projectDetail && projectDetail.type && projectDetail.type === 2) ?
<a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
}
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" style={{ cursor: platform ? "pointer" : "default" }} onClick={() => this.focusFunc(watched)}>
<i className={watched ? "iconfont icon-yiguanzhuicon color-orange font-16 mr3" : "iconfont icon-guanzhuicon color-grey-9 font-16 mr3"}></i>
<span>{watched ? '取消关注' : '关注'}</span>
</a>
{
watchers_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" style={{ color: `#666` }} to={platform ? { pathname: `/${owner}/${projectsId}/following`, state } : ""}>
{watchers_count}
</Link>
:
<span className="detail_tag_btn_count">{watchers_count}</span>
: ""
}
</span>
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" style={{ cursor: platform ? "pointer" : "default" }} onClick={() => this.pariseFunc(praised)}>
<i className={praised ? "iconfont icon-yidianzan_icon color-orange font-15 mr3" : "iconfont icon-xingzhuang color-grey-9 font-14 mr3"}></i>
<span>{praised ? '取消点赞' : '点赞'}</span>
</a>
{
praises_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" style={{ color: `#666` }} to={{ pathname: `/${owner}/${projectsId}/stargazers`, state }}>
{praises_count}
</Link> :
<span className="detail_tag_btn_count">{praises_count}</span>
: ""
}
</span>
<span className="detail_tag_btn" loading={forkSpin}>
<Tooltip title="复刻是fork的中文名即复制代码仓库" placement="bottom">
<a className="detail_tag_btn_name" style={{ cursor: platform ? "pointer" : "default" }} onClick={this.forkFunc}>
<i className="iconfont icon-morenfuke_icon1 color-grey-9 mr3 font-16"></i><span>(Fork)</span>
</a>
</Tooltip>
{
forked_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" to={{ pathname: `/${owner}/${projectsId}/members`, state }}>
{forked_count}
</Link>
:
<span className="detail_tag_btn_count">{forked_count}</span>
: ""
}
</span>
</span>
}
</div>
</div>
{/* <div className="mt6" style={{minHeight:"20px"}}>
{
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
this.textFunc(projectDetail.forked_from_project_id,projectDetail.fork_info)
:""
}
{
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
<span className="color-grey-9">镜像自 <a className="color-blue hoverLine" target="_blank" href={projectDetail.mirror_url}>{projectDetail.mirror_url}</a></span>
:""
}
</div> */}
{
firstSync ? "" :
<DetailBanner
history={this.props.history}
list={bannerList}
owner={owner}
projectsId={projectsId}
pathname={pathname}
state={state}
projectDetail={projectDetail}
open_devops={open_devops}
platform={platform}
urlFlag={urlFlag}
showNotification={this.props.showNotification}
current_user={current_user}
showNpsModal={this.props.showNpsModal}
/>
}
</div>
</div>
{
firstSync &&
<Content className="spincontent">
<Spin className="spinstyle" tip={project && `正在从 ${project.mirror_url} 迁移`} size="large" />
<Button className="red_deleteBtn mt30" onClick={this.deleteProject}>
删除本仓库
</Button>
</Content>
}
<Spin spinning={secondSync && !firstSync} className="spinstyle" tip="正在同步镜像" size="large">
<Switch {...this.props}>
{/* 服务 */}
<Route path="/:owner/:projectsId/service"
render={
() => (<Server {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 资源 */}
<Route path="/:owner/:projectsId/source"
render={
() => (<Source {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 主页 */}
<Route path="/:owner/:projectsId/about"
render={
() => (<DevAbout {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 数据集 */}
<Route path="/:owner/:projectsId/dataset/upload"
render={
(props) => (<DataSetUpload {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/dataset"
render={
(props) => (<DataSetIndex {...this.props} {...props} {...this.state} {...common}/>)
}
></Route>
{/* wiki新增文件 */}
<Route path="/:owner/:projectsId/wiki/add"
render={
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
}
></Route>
{/* wiki编辑文件 */}
<Route path="/:owner/:projectsId/wiki/:wikiName/:key/edit"
render={
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
}
></Route>
{/* wiki具体某一个地址 */}
<Route path="/:owner/:projectsId/wiki/:wikiName/:key"
render={
(props) => (<Wiki {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* wiki */}
<Route path="/:owner/:projectsId/wiki"
render={
() => (<Wiki {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 工作流 */}
<Route path="/:owner/:projectsId/devops"
render={
() => (<DevIndex {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 标签列表 */}
{/* <Route path="/:owner/:projectsId/issues/tags"
render={
(props) => (<TagList {...this.props} {...props} {...this.state} {...common} />)
}
></Route> */}
{/* 仓库设置 */}
<Route path="/:owner/:projectsId/settings"
render={
(props) => (<Setting {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/*修改里程碑*/}
<Route path="/:owner/:projectsId/milestones/:meilid/edit"
render={
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 新建里程碑 */}
<Route path="/:owner/:projectsId/milestones/new"
render={
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/*里程碑详情*/}
<Route path="/:owner/:projectsId/milestones/:mileId"
render={
(props) => (<MilepostDetail {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 里程碑 */}
<Route path="/:owner/:projectsId/milestones"
render={
(props) => (<OrderMilepost {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 动态 */}
<Route path="/:owner/:projectsId/activity"
render={
(props) => (<TrendsIndex {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 代码Index */}
<Route path="/:owner/:projectsId/issues"
render={
(props) => (<OrderIndex {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/compare"
render={
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)
}
></Route>
<Route path="/:owner/:projectsId/pulls/:mergeId/edit"
render={
(props) => (<UpdateMerge {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* review */}
<Route path="/:owner/:projectsId/pulls/:mergeId/review"
render={
(props) => (<Review {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/pulls/:mergeId"
render={
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/pulls/:mergeId/commits"
render={
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/pulls/:mergeId/files"
render={
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/pulls/:mergeId/MergeSubmit"
render={
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/pulls"
render={
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/following"
render={
(props) => (<WatchUsers {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/stargazers"
render={
(props) => (<PraiseUsers {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/members"
render={
(props) => (<ForkUsers {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 贡献者列表 */}
<Route path="/:owner/:projectsId/contribute"
render={
() => (<Contribute {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 代码库----详情页面 */}
<Route path="/:owner/:projectsId/commits/branch/:branchName"
render={
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/tree/:branchName"
render={
(props) => (<CoderDepot {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 邀请 */}
<Route path="/:owner/:projectsId/invite"
render={
(props) => (<Invite {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId/:subIndex"
render={
(props) => ( __CLIENT__ && <CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path="/:owner/:projectsId"
render={
(props) => <CoderDepot {...this.props} {...props} {...this.state} {...common} mirror_status={mirror_status}/>
}
></Route>
</Switch>
</Spin>
</div>
)
}
}
const mapStateToProps = (state) => {
const {
projectBase,
defaultDetail,
projectMenu,
} = state.projectReducer;
return {
projectBase,
defaultDetail,
projectMenu,
};
}
const mapDispatchToProps = (dispatch) => ({
clearProject: (type) => dispatch(actions.clearProject(type)),
});
Detail.preFetch = ({ store, match, query }) => {
return new Promise(async function(resolve, reject) {
let { dispatch } = store;
// const { owner,projectsId } = match.params
const detail = await dispatch(setProjectDetail(match.params))
const promises = [
dispatch(setProject(match.params)),
dispatch(setProjectEntries({...match.params, branch: match.params.branchName ? match.params.branchName : detail.default_branch})),
dispatch(setProjectMenuList(match.params)),
dispatch(setProjectReadMe({...match.params, branch: match.params.branchName ? match.params.branchName : detail.default_branch}))
];
const data = await Promise.all(promises);
resolve({
code: 200,
});
});
};
export default __CLIENT__ ? withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(ImageLayerOfCommentHOC({
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
parentSelector: ".newContainer",
})(Detail))) : withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(Detail));