forked from Gitlink/forgeplus-react
606 lines
25 KiB
JavaScript
606 lines
25 KiB
JavaScript
import React , { useEffect , useState } from 'react';
|
||
import { WhiteBack , Box , LongWidth , ShortWidth , Gap , AlignCenter , FlexAJ } from '../Component/layout';
|
||
import { Dropdown , Menu , Divider , Spin, Button , Typography } from 'antd';
|
||
import { getImageUrl , turnbar , returnbar } from "educoder";
|
||
import { Link } from 'react-router-dom';
|
||
import { truncateCommitId } from "../common/util";
|
||
import CloneAddress from '../Branch/CloneAddress';
|
||
|
||
import SelectBranch from '../Branch/Select';
|
||
import User from '../Component/User';
|
||
import axios from 'axios';
|
||
import Path from './CoderDepotPath';
|
||
import Catalogue from './CoderDepotCatalogue';
|
||
import ReadMe from './CoderDepotReadme';
|
||
import CoderRootFileDetail from './CoderRootFileDetail';
|
||
import './Index.scss';
|
||
import Releases from '../Component/Releases';
|
||
import Contributors from '../Component/Contributors';
|
||
import LanguagePower from '../Component/LanguagePower';
|
||
import DrawerPanel from '../Component/DrawerPanel';
|
||
import UpdateDescModal from './sub/UpdateDescModal';
|
||
import Nodata from '../Nodata';
|
||
import Invite from './sub/Invite';
|
||
import CheckProfile from '../Component/ProfileModal/Profile';
|
||
import RenderHtml from '../../components/render-html';
|
||
/**
|
||
* projectDetail.type:0是托管项目,1是镜像项目,2是同步镜像项目(为2时不支持在线创建、在线上传、在线修改、在线删除、创建合并请求等功能)
|
||
*/
|
||
function CoderDepot(props){
|
||
const [ projectDetail , setProjectDetail ]= useState(undefined);
|
||
const [ inviteCode , setInviteCode ] = useState(undefined);
|
||
const [ treeValue , setTreeValue ] = useState(undefined);
|
||
const [ treeValuePath , setTreeValuePath ] = useState(undefined);
|
||
const [ lastCommit,setLastCommit ] = useState(undefined);
|
||
const [ lastCommitAuthor,setLastCommitAuthor ] = useState(undefined);
|
||
const [ type ,setType ] = useState('dir');
|
||
const [ hide , setHide ] = useState(true);
|
||
const [ hideBtn , setHideBtn ] = useState(false);
|
||
const [ commitCount ,setCommitCount ] = useState(0);
|
||
const [ dirInfo ,setDirInfo ] = useState(undefined);//文件夹目录列表
|
||
const [ fileInfo ,setFileInfo ] = useState(undefined);//文件内容信息
|
||
const [ zip_url , setZip_url ] = useState(undefined);
|
||
const [ tar_url , setTar_url ] = useState(undefined);
|
||
const [ readOnly , setReadOnly] = useState(true);
|
||
const [ isSpin , setIsSpin] = useState(true);
|
||
const [ visible ,setVisible ] = useState(false);
|
||
const [ mainFlag ,setMainFlag ] = useState(false);
|
||
const [ openModal , setOpenModal ] = useState(false);
|
||
const [ desc , setDesc ] = useState(undefined);
|
||
const [ website , setWebsite ] = useState(undefined);
|
||
const [ lesson_url , setLessonUrl ] = useState(undefined);
|
||
const [ readme , setReadme ] = useState(undefined);
|
||
const [ defaultBranch , setDefaultBranch ] = useState(undefined);
|
||
const [ editReadme , setEditReadme ] = useState(false);
|
||
const [ pullsFlag , setPullsFlag ] = useState(true);
|
||
const [ issuesFlag , setIssuesFlag ] = useState(true);
|
||
const [ releaseVersions , setReleaseVersions] = useState(undefined);
|
||
|
||
const owner = props.match.params.owner;
|
||
const projectsId = props.match.params.projectsId;
|
||
let branchName = props.match.params.branchName;
|
||
branchName = returnbar(branchName);
|
||
const details = props.projectDetail;
|
||
let pathname = props.history.location.pathname;
|
||
//distribution:判断此用户是否可以创建发行版
|
||
const distribution = details && details.type != 2 && (details.permission === "Admin" || details.permission === "Owner" || details.permission === "Manager");
|
||
const { bannerList } = props;
|
||
|
||
useEffect(()=>{
|
||
if(bannerList && bannerList.length>0){
|
||
let a = bannerList.filter(i=>i.menu_name === "pulls");
|
||
let i = bannerList.filter(i=>i.menu_name === "issues");
|
||
if(a && a.length === 0){
|
||
setPullsFlag(false);
|
||
}
|
||
if(i && i.length === 0){
|
||
setIssuesFlag(false);
|
||
console.log(bannerList);
|
||
|
||
}
|
||
}
|
||
},[bannerList])
|
||
|
||
|
||
useEffect(()=>{
|
||
if(details){
|
||
setProjectDetail(details);
|
||
setDesc(details.description);
|
||
setWebsite(details.website);
|
||
setLessonUrl(details.lesson_url);
|
||
setDefaultBranch(details.default_branch);
|
||
setInviteCode(details.invite_code);
|
||
}
|
||
},[details])
|
||
|
||
useEffect(()=>{
|
||
if(treeValue){
|
||
setTreeValuePath(treeValue.split('/'));
|
||
}else{
|
||
setTreeValuePath(undefined);
|
||
}
|
||
},[treeValue])
|
||
|
||
|
||
useEffect(()=>{
|
||
if (projectsId && owner && defaultBranch){
|
||
let b = turnbar(branchName) ;
|
||
if(pathname.indexOf(`/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${b}/`) > -1) {
|
||
let url = pathname.split(`/tree/${b}/`)[1];
|
||
setTreeValue(url);
|
||
getFileInfo(url,branchName);
|
||
setType("file");
|
||
}else{
|
||
setTreeValue(undefined);
|
||
getDirInfo(branchName || defaultBranch);
|
||
setType("dir");
|
||
}
|
||
}
|
||
},[projectsId,owner,pathname,defaultBranch])
|
||
|
||
useEffect(()=>{
|
||
axios.get(`/${owner}/${projectsId}/releases.json`).then((result)=>{
|
||
if(result && result.data){
|
||
const release = {
|
||
"list":result.data.releases,
|
||
"total_count":result.data.releases && result.data.releases.length
|
||
}
|
||
setReleaseVersions(release);
|
||
}
|
||
})
|
||
},[])
|
||
|
||
// 获取readme信息
|
||
function getReadmeInfo(path, ref) {
|
||
axios.get(`/${owner}/${projectsId}/readme.json`, {
|
||
params:{
|
||
owner: owner,
|
||
repo: projectsId,
|
||
filepath:path,
|
||
ref:ref || branchName
|
||
}
|
||
}).then((result) => {
|
||
if (result) {
|
||
setReadme(result.data);
|
||
} else {
|
||
setReadme(undefined);
|
||
}
|
||
})
|
||
}
|
||
|
||
// 获取主目录列表
|
||
function getDirInfo(branch){
|
||
setIsSpin(true);
|
||
const url = `/${owner}/${projectsId}/entries.json`;
|
||
|
||
axios.get(url, {
|
||
params: { ref:branch}
|
||
}).then((result) => {
|
||
if (result) {
|
||
setCommitCount(result.data.commits_count);
|
||
setDirInfo(result.data.entries);
|
||
setFileInfo(undefined);
|
||
setTar_url(result.data.tar_url);
|
||
setZip_url(result.data.zip_url);
|
||
let c = result.data.last_commit
|
||
setLastCommit(c && c.commit);
|
||
setLastCommitAuthor(c && c.committer);
|
||
setMainFlag(true);
|
||
setReadOnly(true);
|
||
// setReadme(result.data.readme);
|
||
setEditReadme(false);
|
||
setHide(true);
|
||
getReadmeInfo('', branchName || defaultBranch);
|
||
}
|
||
setTimeout(function(){setIsSpin(false);},500);
|
||
}).catch(error=>{setIsSpin(false);})
|
||
}
|
||
|
||
useEffect(()=>{
|
||
if(projectDetail && lastCommit)
|
||
{
|
||
let ele = document.getElementById("ptxt");
|
||
if(ele){
|
||
let h = ele.offsetHeight;
|
||
if( h > 36 ) setHideBtn(true);
|
||
}
|
||
}
|
||
},[projectDetail,lastCommit])
|
||
// 获取子目录列表
|
||
function getFileInfo(path, ref){
|
||
setIsSpin(true);
|
||
const url = `/${owner}/${projectsId}/sub_entries.json`;
|
||
axios.get(url, {
|
||
params:{
|
||
filepath:returnbar(path),
|
||
ref:ref || branchName,
|
||
type
|
||
}
|
||
}).then((result) => {
|
||
if (result) {
|
||
let en = result.data.entries;
|
||
if(en.type){
|
||
setDirInfo(undefined);
|
||
setFileInfo(en);
|
||
setType(en.type);
|
||
setReadme(undefined);
|
||
}else{
|
||
setFileInfo(undefined);
|
||
setDirInfo(en);
|
||
setType("dir");
|
||
getReadmeInfo(path, branchName || defaultBranch);
|
||
}
|
||
let c = result.data.last_commit
|
||
setLastCommit(c && c.commit);
|
||
setLastCommitAuthor(c && c.committer);
|
||
setMainFlag(false);
|
||
setReadOnly(true);
|
||
setReadOnly(!editReadme);
|
||
setHide(true);
|
||
}
|
||
setTimeout(function(){setIsSpin(false);},500)
|
||
}).catch(error=>{setIsSpin(false);})
|
||
}
|
||
|
||
// 切换分支或者标签
|
||
function changeBranch(value){
|
||
let checkvalue = value;
|
||
let u = `/${owner}/${projectsId}${checkvalue && `/tree/${checkvalue}`}${treeValue ? `/${treeValue}`:""}`;
|
||
props.history.push(u);
|
||
}
|
||
|
||
// 文件相关的下拉项
|
||
function fileMenu(){
|
||
let b = branchName || defaultBranch;
|
||
let checkvalue = turnbar(b);
|
||
return (
|
||
<Menu className="fileMenu">
|
||
<Menu.Item>
|
||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/${checkvalue}/uploadfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>上传文件</CheckProfile>
|
||
</Menu.Item>
|
||
<Menu.Item>
|
||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/${checkvalue}/newfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>新建文件</CheckProfile>
|
||
</Menu.Item>
|
||
</Menu>
|
||
)
|
||
}
|
||
|
||
function getPathUrl(array,index){
|
||
if(array && array.length>0 && index){
|
||
let str = "";
|
||
for(let i=0;i<index;i++){
|
||
str += `/${array[i]}`;
|
||
}
|
||
return str.substr(1);
|
||
}
|
||
}
|
||
// 页面地址返回到主目录
|
||
function returnMain(){
|
||
setTreeValue(undefined);
|
||
let branch = branchName || defaultBranch;
|
||
let checkvalue = turnbar(branch);
|
||
props.history.push(`/${owner}/${projectsId}/tree/${checkvalue}`);
|
||
};
|
||
// 子目录路径返回链接
|
||
function returnUlr(url){
|
||
let enBranch = turnbar(branchName);
|
||
setType('dir');
|
||
props.history.push(`/${owner}/${projectsId}/tree${enBranch?`/${enBranch}`:""}/${url}`);
|
||
}
|
||
// 点击跳转到子目录
|
||
function goToSubRoot(path,type,filename){
|
||
if(type!=="submodule"){
|
||
let enBranch = branchName || defaultBranch;
|
||
let checkvalue = turnbar(enBranch);
|
||
let enPath = turnbar(path);
|
||
setType(type);
|
||
props.history.push(`/${owner}/${projectsId}${`/tree/${checkvalue}`}${enPath?`/${enPath}`:""}`);
|
||
}
|
||
}
|
||
|
||
function onEdit(readOnly){
|
||
setReadOnly(readOnly);
|
||
setEditReadme(false);
|
||
}
|
||
function ChangeFile(path, readOnly){
|
||
//点击直接跳转页面 加载一次路由
|
||
let enBranch = branchName || defaultBranch;
|
||
let checkvalue = turnbar(enBranch);
|
||
props.history.push(`/${owner}/${projectsId}/tree/${checkvalue}/${path}`);
|
||
setType("file");
|
||
setEditReadme(true);
|
||
};
|
||
|
||
function changeHide(hide){
|
||
setHide(!hide);
|
||
}
|
||
|
||
function urlLink(link){
|
||
if(props.checkIfLogin()===false){
|
||
props.showLoginDialog()
|
||
return false;
|
||
}
|
||
props.history.push(link);
|
||
}
|
||
|
||
const downloadMenu = (
|
||
<CloneAddress
|
||
http_url={projectDetail && projectDetail.clone_url}
|
||
ssh_url = {(projectDetail && props && props.platform) && projectDetail.ssh_url}
|
||
zip_url={(props && props.platform) && zip_url}
|
||
tar_url={(props && props.platform) && tar_url}
|
||
showNotification={props.showNotification}/>
|
||
)
|
||
// 确认修改简介、website、实践课程链接
|
||
function okUpdate(d,w,l){
|
||
const url = `/${owner}/${projectsId}.json`;
|
||
axios.put(url,{
|
||
description:d,website:w || "",lesson_url:l||""
|
||
}).then(result=>{
|
||
if(result && result.data && result.data.id){
|
||
setDesc(result.data.description);
|
||
setWebsite(result.data.website);
|
||
setLessonUrl(result.data.lesson_url);
|
||
}
|
||
})
|
||
}
|
||
|
||
function createIssue(){
|
||
if(baseOper){
|
||
props.history.push(`/${owner}/${projectsId}/issues/new`);
|
||
}else{
|
||
props.showLoginDialog(`/${owner}/${projectsId}/issues/new`);
|
||
}
|
||
}
|
||
|
||
let n = fileInfo && fileInfo.name;
|
||
const mdFlag = n && n.substring(n.length-3,n.length) === ".md";
|
||
|
||
const { current_user } = props;
|
||
const baseOper = current_user && current_user.login && issuesFlag;
|
||
const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter" && projectDetail.type !== 2 && pullsFlag && props.platform;
|
||
const fileOperate = type === "dir" && projectDetail && projectDetail.type !== 2 && ((projectDetail.permission && projectDetail.permission !=="Reporter") || (current_user && current_user.admin));
|
||
|
||
return(
|
||
<WhiteBack>
|
||
<UpdateDescModal desc={desc} website={website} lesson_url={lesson_url} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
|
||
<Spin spinning={isSpin}>
|
||
{
|
||
(dirInfo || fileInfo) &&
|
||
<React.Fragment>
|
||
<DrawerPanel
|
||
history={props.history}
|
||
owner={owner}
|
||
projectsId={projectsId}
|
||
name={projectDetail && projectDetail.name}
|
||
branch={branchName || defaultBranch}
|
||
visible={visible}
|
||
onClose={()=>setVisible(false)}
|
||
list = {mainFlag ? dirInfo : undefined}
|
||
/>
|
||
<div className="drawerBtn" onClick={()=>setVisible(true)}>
|
||
<i className="iconfont icon-zuohuaicon font-14"></i>
|
||
<span>目录</span>
|
||
</div>
|
||
</React.Fragment>
|
||
}
|
||
<div style={{minHeight:"500px"}}>
|
||
{
|
||
projectDetail &&
|
||
<Box className="Panels">
|
||
<LongWidth>
|
||
<div className="panelmenu">
|
||
<FlexAJ>
|
||
<AlignCenter>
|
||
<div className="mr30">
|
||
{
|
||
props && props.platform ?
|
||
<SelectBranch
|
||
repo_id={projectDetail && projectDetail.repo_id}
|
||
projectsId={projectsId}
|
||
branch={branchName || defaultBranch}
|
||
changeBranch={changeBranch}
|
||
owner={owner}
|
||
history={props.history}
|
||
branchList={projectDetail && projectDetail.branches && projectDetail.branches.list}
|
||
></SelectBranch>
|
||
:
|
||
<span>分支:<span className="color-grey-6">{branchName || defaultBranch}</span></span>
|
||
}
|
||
</div>
|
||
{
|
||
treeValuePath && treeValuePath.length > 0 ?
|
||
<Path
|
||
identifier={projectDetail && projectDetail.identifier}
|
||
treeValuePath={treeValuePath}
|
||
returnUlr={returnUlr}
|
||
returnMain={returnMain}
|
||
getPathUrl={getPathUrl}
|
||
/>
|
||
:
|
||
<React.Fragment>
|
||
<AlignCenter className="mr20">
|
||
{
|
||
props.platform ?
|
||
<Link to={`/${owner}/${projectsId}/branches`} className="iconBtn">
|
||
<i className="iconfont icon-master_icon font-16"></i>
|
||
<span>分支</span>
|
||
<span>{projectDetail && projectDetail.branches_count}</span>
|
||
</Link>
|
||
:
|
||
<span>
|
||
<i className="iconfont icon-master_icon font-16 color-grey-6"></i>
|
||
<span className="ml3 color-grey-6">分支</span>
|
||
<span className="ml3">{projectDetail && projectDetail.branches_count}</span>
|
||
</span>
|
||
}
|
||
</AlignCenter>
|
||
<AlignCenter className="mr20">
|
||
{
|
||
props.platform ?
|
||
<Link to={`/${owner}/${projectsId}/tags`} className="iconBtn">
|
||
<i className="iconfont icon-biaoqianicon font-16"></i>
|
||
<span>标签</span>
|
||
<span>{projectDetail && projectDetail.tags_count}</span>
|
||
</Link>:
|
||
<span>
|
||
<i className="iconfont icon-biaoqianicon font-16 color-grey-6"></i>
|
||
<span className="ml3 color-grey-6">标签</span>
|
||
<span className="ml3">{projectDetail && projectDetail.tags_count}</span>
|
||
</span>
|
||
}
|
||
</AlignCenter>
|
||
</React.Fragment>
|
||
}
|
||
</AlignCenter>
|
||
<AlignCenter className="depotBtn">
|
||
<div className="addOptionBtn">
|
||
{
|
||
baseOperate &&
|
||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/compare/${turnbar(branchName || defaultBranch)}...${turnbar(branchName || defaultBranch)}`)} >+ 合并请求</CheckProfile>
|
||
}
|
||
{
|
||
issuesFlag &&
|
||
<a onClick={createIssue}>+ 疑修</a>
|
||
}
|
||
</div>
|
||
{ fileOperate &&
|
||
<Dropdown
|
||
overlay={fileMenu()}
|
||
className="mr10"
|
||
trigger={['click']}
|
||
getPopupContainer={document.parentNode}
|
||
>
|
||
<a>文件 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-grey-6 mr-5"></i></a>
|
||
</Dropdown>
|
||
}
|
||
|
||
<Dropdown overlay={downloadMenu} placement="bottomRight" trigger={['click']}>
|
||
<Button type={'primary'}>下载 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-white mr-3"></i></Button>
|
||
</Dropdown>
|
||
</AlignCenter>
|
||
</FlexAJ>
|
||
{
|
||
(dirInfo && dirInfo.length>0) || fileInfo ?
|
||
<div className="listtable">
|
||
{
|
||
((lastCommit && lastCommit.message) || lastCommitAuthor) &&
|
||
<div className="listtablehead">
|
||
{
|
||
lastCommitAuthor &&
|
||
<User url={getImageUrl(`/${lastCommitAuthor.image_url}`)} name={lastCommitAuthor.name} id={lastCommitAuthor.id} login={lastCommitAuthor.login}/>
|
||
}
|
||
{
|
||
lastCommit.message &&
|
||
<div className={hideBtn && hide ? "ellipsistxt hidetxt" :"ellipsistxt"}>
|
||
<pre id="ptxt"><Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(lastCommit.sha)}`}><RenderHtml value={lastCommit.message}/></Link></pre>
|
||
</div>
|
||
}
|
||
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
|
||
|
||
<span className="ml20 color-grey-6 font-12 mt3">{lastCommit.time_from_now}</span>
|
||
{
|
||
commitCount ?
|
||
<Link to={`/${owner}/${projectsId}/commits/branch/${turnbar(branchName || defaultBranch)}`} className="ml20 color-grey-3"style={{height:"28px",lineHeight:"28px"}}>
|
||
<i className="iconfont icon-tijiaoicon mr3 font-16"></i><span style={{fontWeight:"500"}}>{commitCount}次提交</span>
|
||
</Link>:""
|
||
}
|
||
</div>
|
||
}
|
||
<ul className="listtablebody">
|
||
{
|
||
dirInfo && dirInfo.length > 0 &&
|
||
dirInfo.map((item,key)=>{
|
||
return(
|
||
<Catalogue
|
||
owner={owner}
|
||
item={item}
|
||
projectsId={projectsId}
|
||
goToSubRoot={goToSubRoot}
|
||
platform={props.platform}
|
||
/>
|
||
)
|
||
})
|
||
}
|
||
{
|
||
fileInfo &&
|
||
<CoderRootFileDetail
|
||
{...props}
|
||
detail={fileInfo}
|
||
readOnly={readOnly}
|
||
md={mdFlag}
|
||
onEdit={onEdit}
|
||
currentBranch={branchName || defaultBranch}
|
||
type={projectDetail.type}
|
||
></CoderRootFileDetail>
|
||
}
|
||
</ul>
|
||
</div>
|
||
: ""
|
||
}
|
||
{
|
||
(dirInfo && dirInfo.length === 0) && !fileInfo ? <Nodata _html="暂未发现文件"/> :""
|
||
}
|
||
{/* readme文件显示(显示文件详情时不显示readme文件) */}
|
||
{ (readme && readme.replace_content) ? <ReadMe ChangeFile={ChangeFile} readme={readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
|
||
</div>
|
||
</LongWidth>
|
||
{
|
||
(!(treeValuePath && treeValuePath.length > 0) && !fileInfo) &&
|
||
<ShortWidth>
|
||
<Gap style={{paddingLeft:"30px"}}>
|
||
<div className="panelmenu">
|
||
<FlexAJ className="font-18 color-ooo mb20" style={{lineHeight:"28px"}}>关于
|
||
{
|
||
projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner" || projectDetail.permission==="Manager") &&
|
||
<i onClick={()=>setOpenModal(true)} className="iconfont icon-a-shezhi color-grey-9 font-15 pointer"></i>
|
||
}
|
||
</FlexAJ>
|
||
{desc && <p className="font-14 color-grey-3 mb15 task-hide-2" style={{lineHeight:"24px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}} title={desc}>{desc}</p>}
|
||
{
|
||
website &&
|
||
<div className="color-grey-6 df pinfos mb5">
|
||
<i className="iconfont icon-lianjie2 font-15 mr10"></i>
|
||
<a href={website} target="_blank" style={{wordBreak:"break-all",lineHeight:"20px",marginTop:"5px",textDecoration:"underline"}}>{website}</a>
|
||
</div>
|
||
}
|
||
<div className="pinfos mb5">
|
||
<i className="iconfont icon-zishuwenjian_icon font-15 mr10"></i>
|
||
<a href="#readme">README.md</a>
|
||
</div>
|
||
<div className="color-grey-6 mb5">
|
||
<i className="iconfont icon-neicunicon font-15 mr10"></i>
|
||
<span>{projectDetail && projectDetail.size}</span>
|
||
</div>
|
||
{
|
||
projectDetail && projectDetail.license_name &&
|
||
<div className="pinfos">
|
||
<i className="iconfont icon-xieyiicon font-16 mr10"></i>
|
||
<Link to={`/${owner}/${projectsId}/tree/${turnbar(branchName || defaultBranch)}/LICENSE`} className="color-grey-6">{projectDetail.license_name}</Link>
|
||
</div>
|
||
}
|
||
</div>
|
||
{
|
||
inviteCode &&
|
||
<div>
|
||
<Divider />
|
||
<Invite code={inviteCode}/>
|
||
</div>
|
||
}
|
||
{
|
||
lesson_url &&
|
||
<div>
|
||
<Divider />
|
||
<p className="font-16 color-ooo">实践课程</p>
|
||
<a href={lesson_url} target="_blank" className="color-grey-6" style={{textDecoration:"underline",wordBreak:"break-all"}}>{lesson_url}</a>
|
||
</div>
|
||
}
|
||
{/* 发布 */}
|
||
{
|
||
releaseVersions && props.platform &&
|
||
<React.Fragment>
|
||
<Divider />
|
||
<Releases
|
||
owner={owner}
|
||
projectsId={projectsId}
|
||
releaseVersions={releaseVersions}
|
||
history={props.history}
|
||
distribution={distribution}
|
||
/>
|
||
</React.Fragment>
|
||
}
|
||
{/* 贡献者 */}
|
||
<Contributors owner={owner} projectsId={projectsId} />
|
||
{/* 语言 */}
|
||
<LanguagePower owner={owner} projectsId={projectsId}/>
|
||
</Gap>
|
||
</ShortWidth>
|
||
}
|
||
</Box>
|
||
}
|
||
</div>
|
||
</Spin>
|
||
</WhiteBack>
|
||
)
|
||
}
|
||
export default CoderDepot; |