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

549 lines
16 KiB
JavaScript
Raw Normal View History

2020-06-04 18:28:26 +08:00
import React, { Component } from "react";
import { Menu, Spin } from "antd";
2020-06-04 18:28:26 +08:00
import { getImageUrl } from "educoder";
import { Link } from "react-router-dom";
2020-03-16 14:12:11 +08:00
import './list.css';
2020-06-04 18:27:19 +08:00
import SelectBranch from '../Branch/Select';
2020-03-16 14:12:11 +08:00
import CloneAddress from '../Branch/CloneAddress';
import RootTable from './RootTable';
import CoderRootFileDetail from './CoderRootFileDetail';
2020-03-30 10:21:22 +08:00
import { truncateCommitId } from '../common/util';
2020-04-29 10:42:53 +08:00
import RenderHtml from '../../components/render-html';
import Nodata from '../Nodata';
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
import axios from "axios";
2020-03-16 14:12:11 +08:00
/**
* address:http和SSHhttp_url(对应git地址)
* branch:当前分支
* filePath:点击目录时当前目录的路径
* subfileType:保存当前点击目录的文件类型显示目录列表时才显示新建文件如果点击的是文件就不显示新建文件按钮
* readMeContent:根目录下面的readme文件内容
*/
2020-08-27 10:27:31 +08:00
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);
}
}
2020-06-04 18:28:26 +08:00
class CoderRootDirectory extends Component {
constructor(props) {
2020-03-16 14:12:11 +08:00
super(props);
2020-06-04 18:28:26 +08:00
this.state = {
address: "http",
branch: "master",
filePath: undefined,
subFileType: undefined,
readMeContent: undefined,
2020-04-13 17:45:36 +08:00
readMeFile: undefined,
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
isSpin: true,
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
branchList: undefined,
fileDetail: undefined,
branchLastCommit: undefined,
lastCommitAuthor: undefined,
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
rootList: undefined,
2020-06-03 14:42:13 +08:00
readOnly: true,
zip_url:undefined,
2020-06-04 18:27:19 +08:00
tar_url:undefined,
chooseType:undefined,
2020-07-02 16:41:06 +08:00
md:false
2020-03-16 14:12:11 +08:00
}
}
2020-06-04 18:28:26 +08:00
changeAddress = (address) => {
2020-03-16 14:12:11 +08:00
this.setState({
2020-06-04 18:28:26 +08:00
address,
});
};
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
componentDidMount = () => {
this.Init();
2020-06-04 18:28:26 +08:00
};
2020-06-04 18:28:26 +08:00
componentDidUpdate = (prevState) => {
const { location } = this.props;
const prevlocation = prevState && prevState.location;
2020-06-04 18:28:26 +08:00
if (location !== prevlocation) {
this.setState({
2020-06-04 18:28:26 +08:00
isSpin: true,
});
this.Init();
}
2020-06-04 18:28:26 +08:00
};
2020-03-30 18:51:30 +08:00
2020-06-04 18:28:26 +08:00
Init = () => {
2020-03-16 14:12:11 +08:00
let { search } = this.props.history.location;
let branchName = undefined;
2020-06-04 18:28:26 +08:00
if (search && search.indexOf("?branch=") > -1) {
2020-04-24 09:15:52 +08:00
branchName = search.split("?branch=")[1];
2020-03-16 14:12:11 +08:00
this.setState({
2020-06-04 18:28:26 +08:00
branch: branchName,
});
2020-03-16 14:12:11 +08:00
}
2020-06-04 18:28:26 +08:00
if (search && search.indexOf("?url=") > -1) {
let url = search.split("?url=")[1];
this.setState({
2020-06-04 18:28:26 +08:00
filePath: url,
});
this.getFileDetail(url);
2020-06-04 18:28:26 +08:00
} else {
const { branch } = this.state;
2020-06-04 18:28:26 +08:00
this.getProjectRoot(branchName || branch);
}
2020-06-04 18:28:26 +08:00
};
// 页面地址返回到主目录
2020-06-04 18:28:26 +08:00
returnMain = (branch) => {
2020-08-13 11:42:44 +08:00
const { projectsId , owner } = this.props.match.params;
2020-06-11 18:00:32 +08:00
this.setState({
readOnly:true
})
2020-08-19 18:34:52 +08:00
this.props.history.push(`/projects/${owner}/${projectsId}`);
this.getProjectRoot(branch);
2020-06-04 18:28:26 +08:00
};
2020-03-16 14:12:11 +08:00
// 获取根目录
2020-06-04 18:28:26 +08:00
getProjectRoot = (branch) => {
2020-08-12 18:13:18 +08:00
const { projectsId , owner } = this.props.match.params;
const url = `/${owner}/${projectsId}/entries.json`;
axios.get(url, { params: { ref: branch } })
.then((result) => {
if (result) {
let last_commit = result.data && result.data.last_commit;
let entries = result.data && result.data.entries;
this.setState({
filePath: undefined,
fileDetail: undefined,
isSpin: false,
branchLastCommit: last_commit && last_commit.commit,
lastCommitAuthor:
last_commit && (last_commit.author || (last_commit.commit && last_commit.commit.author)),
zip_url: result.data.zip_url,
tar_url: result.data.tar_url
});
if (entries && entries.length > 0) {
this.renderData(entries);
2020-03-16 14:12:11 +08:00
}
2020-08-12 18:13:18 +08:00
this.setState({
rootList: entries,
subFileType: true,
});
}
}).catch((error) => {});
2020-06-04 18:28:26 +08:00
};
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
ChangeFile = (arr, readOnly) => {
2020-08-13 11:42:44 +08:00
const { projectsId , owner } = this.props.match.params;
2020-03-30 18:51:30 +08:00
//点击直接跳转页面 加载一次路由
2020-08-19 18:34:52 +08:00
this.props.history.push(`/projects/${owner}/${projectsId}?url=${arr.path}`);
2020-03-16 14:12:11 +08:00
this.setState({
2020-06-04 18:28:26 +08:00
readOnly: readOnly,
2020-06-11 18:00:32 +08:00
chooseType:"file"
2020-06-04 18:28:26 +08:00
});
};
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
renderUrl = (name, path, type) => {
let list = [];
2020-03-16 14:12:11 +08:00
const { filePath } = this.state;
2020-06-04 18:28:26 +08:00
if (path.indexOf("/")) {
2020-03-16 14:12:11 +08:00
const array = path.split("/");
let str = "";
2020-06-04 18:28:26 +08:00
array.map((i, k) => {
str += "/" + i;
2020-03-16 14:12:11 +08:00
return list.push({
2020-06-04 18:28:26 +08:00
key: k,
index: k,
name: i,
path: str.substr(1),
type:
filePath && filePath.length > 0
? filePath[k]
? filePath[k].type
: type
: type,
});
});
2020-08-13 11:42:44 +08:00
const { projectsId , owner } = this.props.match.params;
//点击直接跳转页面 加载一次路由
2020-06-04 18:28:26 +08:00
this.props.history.push(
2020-08-19 18:34:52 +08:00
`/projects/${owner}/${projectsId}?url=${str.substr(1)}`
2020-06-04 18:28:26 +08:00
);
} else {
2020-03-16 14:12:11 +08:00
list.push({
2020-06-04 18:28:26 +08:00
index: 0,
name,
path,
type,
});
2020-03-16 14:12:11 +08:00
}
this.setState({
2020-06-04 18:28:26 +08:00
filePath: list,
});
};
2020-03-16 14:12:11 +08:00
// 获取子目录
2020-06-04 18:28:26 +08:00
getFileDetail = (path, ref) => {
2020-08-12 18:13:18 +08:00
const { projectsId ,owner } = this.props.match.params;
2020-03-16 14:12:11 +08:00
const { branch } = this.state;
2020-08-12 18:13:18 +08:00
const url = `/${owner}/${projectsId}/sub_entries.json`;
2020-03-16 14:12:11 +08:00
axios.get(url,{
params:{
filepath:path,
2020-04-23 14:11:43 +08:00
ref:ref || branch
2020-03-16 14:12:11 +08:00
}
}).then((result)=>{
let entries = result.data && result.data.entries;
2020-06-04 18:27:19 +08:00
if( entries && entries.length > 0){
let { chooseType } = this.state;
// 当前返回的子目录只有一条数据,且这条数据返回的是文件类型
2020-06-04 18:27:19 +08:00
if(entries.length === 1 && entries[0].type === "file" && chooseType ==="file"){
2020-03-16 14:12:11 +08:00
this.setState({
2020-06-03 14:42:13 +08:00
fileDetail:entries,
rootList:undefined,
2020-04-24 09:15:52 +08:00
isSpin:false,
subFileType:false
2020-03-16 14:12:11 +08:00
})
}else{
this.setState({
fileDetail:undefined,
2020-06-03 14:42:13 +08:00
rootList:entries,
isSpin:false,
branchLastCommit:result.data.last_commit && result.data.last_commit.commit,
lastCommitAuthor:result.data.last_commit && (result.data.last_commit.author || (result.data.last_commit.commit && result.data.last_commit.commit.author))
2020-03-16 14:12:11 +08:00
})
2020-06-03 14:42:13 +08:00
this.renderData(entries);
2020-03-16 14:12:11 +08:00
}
}else{
console.log("均为undefined");
this.setState({
fileDetail:undefined,
rootList:undefined,
isSpin:false,
subFileType:false
})
2020-03-16 14:12:11 +08:00
}
})
.catch((error) => {
console.log(error);
});
2020-06-04 18:28:26 +08:00
};
2020-03-16 14:12:11 +08:00
2020-06-04 18:28:26 +08:00
renderData = (data) => {
2020-03-16 14:12:11 +08:00
const rootList = [];
const readMeContent = [];
2020-04-13 17:45:36 +08:00
const readMeFile = [];
2020-06-04 18:28:26 +08:00
data &&
data.map((item, key) => {
rootList.push({
key,
message: item.commit && item.commit.message,
...item,
});
2020-07-02 10:14:00 +08:00
if (item.is_readme_file) {
2020-06-04 18:28:26 +08:00
readMeContent.push({ ...item });
readMeFile.push({ ...item });
}
});
2020-03-16 14:12:11 +08:00
this.setState({
2020-06-04 18:28:26 +08:00
rootList: rootList,
2020-04-13 17:45:36 +08:00
readMeContent,
2020-06-04 18:28:26 +08:00
readMeFile,
});
};
2020-03-16 14:12:11 +08:00
// 点击跳转到子目录
2020-07-02 16:41:06 +08:00
goToSubRoot=(path,type,filename)=>{
2020-06-04 18:27:19 +08:00
this.setState({
chooseType:type
})
2020-08-13 11:42:44 +08:00
const { projectsId, owner } = this.props.match.params;
2020-08-19 18:34:52 +08:00
this.props.history.push(`/projects/${owner}/${projectsId}?url=${path}`);
2020-07-02 16:41:06 +08:00
if(filename.substring(filename.length - 3) === ".md"){
this.setState({
md:true
})
}else{
this.setState({
md:false
})
}
2020-06-04 18:28:26 +08:00
};
2020-03-16 14:12:11 +08:00
// readme文件内容
2020-06-04 18:28:26 +08:00
renderReadMeContent = (readMeContent, permission) => {
const { fileDetail, readMeFile } = this.state;
if (fileDetail) {
return;
}
if (readMeContent && readMeContent.length > 0) {
return (
2020-03-16 14:12:11 +08:00
<div className="commonBox">
2020-04-13 17:45:36 +08:00
<div className="commonBox-title">
2020-06-04 18:28:26 +08:00
<span className="mr10">
2020-07-02 14:21:22 +08:00
<i className="iconfont icon-wenjian1 font-16 color-grey-9 fl mt3"></i>
2020-06-04 18:28:26 +08:00
</span>
<span className="commonBox-title-read">
{readMeContent[0].name}
</span>
{permission ? (
<a
onClick={() => this.ChangeFile(readMeFile[0], false)}
className="ml20 pull-right"
>
2020-07-02 14:21:22 +08:00
<i className="iconfont icon-bianji6 font-16 color-blue"></i>
2020-06-04 18:28:26 +08:00
</a>
) : (
""
)}
2020-04-13 17:45:36 +08:00
</div>
2020-03-16 14:12:11 +08:00
<div className="commonBox-info">
2020-06-04 18:28:26 +08:00
{readMeContent[0].content ? (
<RenderHtml
2020-08-18 09:55:20 +08:00
className="break_word_comments imageLayerParent"
2020-06-04 18:28:26 +08:00
value={readMeContent[0].content}
/>
) : (
2020-03-16 14:12:11 +08:00
<span>暂无~</span>
2020-06-04 18:28:26 +08:00
)}
2020-03-16 14:12:11 +08:00
</div>
</div>
2020-06-04 18:28:26 +08:00
);
2020-03-16 14:12:11 +08:00
}
2020-06-04 18:28:26 +08:00
};
2020-03-16 14:12:11 +08:00
// 选择分支
2020-06-04 18:28:26 +08:00
changeBranch = (value) => {
2020-06-03 14:42:13 +08:00
this.setState({
2020-06-04 18:28:26 +08:00
branch: value,
isSpin: true,
2020-06-11 18:00:32 +08:00
readOnly:true
2020-06-04 18:28:26 +08:00
});
2020-07-03 16:32:47 +08:00
const { getTopCount } = this.props;
getTopCount && getTopCount(value);
2020-06-03 14:42:13 +08:00
let { search } = this.props.history.location;
2020-06-04 18:28:26 +08:00
if (search && search.indexOf("?url=") > -1) {
let url = search.split("?url=")[1];
2020-04-24 10:38:19 +08:00
this.setState({
2020-06-04 18:28:26 +08:00
filePath: url,
});
2020-06-03 14:42:13 +08:00
this.getFileDetail(url, value);
2020-06-04 18:28:26 +08:00
} else {
this.getProjectRoot(value);
2020-06-03 14:42:13 +08:00
}
2020-03-16 14:12:11 +08:00
}
2020-06-04 18:27:19 +08:00
2020-06-05 09:35:16 +08:00
// 子目录路径返回链接
2020-06-04 18:27:19 +08:00
returnUlr=(url)=>{
this.setState({
2020-06-11 18:00:32 +08:00
chooseType:"dir",
readOnly:true
2020-06-04 18:27:19 +08:00
})
2020-08-13 11:42:44 +08:00
const { projectsId , owner } = this.props.match.params;
2020-08-19 18:34:52 +08:00
this.props.history.push(`/projects/${owner}/${projectsId}?url=${url}`);
2020-06-04 18:27:19 +08:00
}
2020-06-11 18:00:32 +08:00
onEdit=(readOnly)=>{
this.setState({
readOnly
})
}
2020-07-10 15:42:57 +08:00
downloadUrl = (zip_url,tar_url) => {
return(
<Menu>
{zip_url && (
<Menu.Item>
<a href={zip_url}>ZIP</a>
</Menu.Item>
)}
{tar_url && (
<Menu.Item>
<a href={tar_url}>TAR.GZ</a>
</Menu.Item>
)}
</Menu>
)
}
title = (branchLastCommit,lastCommitAuthor) => {
2020-07-16 09:40:39 +08:00
console.log(branchLastCommit)
2020-07-10 15:42:57 +08:00
if (branchLastCommit) {
return (
<div className="f-wrap-alignCenter">
{lastCommitAuthor ? (
<React.Fragment>
{lastCommitAuthor.login ? (
<Link
to={`/users/${lastCommitAuthor.login}/projects`}
className="show-user-link"
>
<img
src={getImageUrl(`images/${lastCommitAuthor.image_url}`)}
className="radius mr10"
width="32"
height="32"
alt=""
/>
<span className="mr15">{lastCommitAuthor.name}</span>
</Link>
) : (
<span className="mr15">{lastCommitAuthor.name}</span>
)}
</React.Fragment>
) : (
""
)}
<span className="color-blue flex-1 hide-1">
{branchLastCommit.message}
</span>
<span>{branchLastCommit.time_from_now}</span>
<span className="commitKey">
{truncateCommitId(branchLastCommit.sha)}
</span>
</div>
);
2020-07-16 09:40:39 +08:00
}else{
return false;
2020-07-10 15:42:57 +08:00
}
}
2020-03-16 14:12:11 +08:00
render(){
2020-06-03 14:42:13 +08:00
const { branchLastCommit , lastCommitAuthor , rootList , branch ,filePath , fileDetail , subFileType , readMeContent, isSpin , zip_url , tar_url} = this.state;
const { isManager , isDeveloper , projectDetail } = this.props;
2020-08-12 18:13:18 +08:00
const { projectsId , owner } = this.props.match.params;
2020-03-16 14:12:11 +08:00
const columns = [
{
dataIndex: 'name',
2020-05-22 15:20:36 +08:00
width:"30%",
2020-03-16 14:12:11 +08:00
render: (text,item) => (
2020-07-02 16:41:06 +08:00
<a onClick={()=>this.goToSubRoot(item.path,item.type,text)} className="ml12 task-hide" style={{ display: "block", maxWidth: "345px" }}>
2020-05-22 17:09:11 +08:00
<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}
2020-03-16 14:12:11 +08:00
</a>
),
2020-06-04 18:28:26 +08:00
},
{
dataIndex: "commit",
width: "60%",
render: (text, item) =>
2020-07-10 15:42:57 +08:00
item.commit && item.commit.message ?
<span className="task-hide" style={{ display: "block", maxWidth: "670px" }} >
2020-06-04 18:28:26 +08:00
{item.commit.message}
</span>
2020-07-10 15:42:57 +08:00
: ""
2020-06-04 18:28:26 +08:00
},
{
dataIndex: "commit",
width: "10%",
className: "edu-txt-right",
render: (text, item) =>
2020-07-10 15:42:57 +08:00
item.commit && item.commit.time_from_now ?
<a title={item.commit.created_at} className="mr12" style={{ cursor: "default", color: "#888" }} >
2020-06-04 18:28:26 +08:00
{item.commit.time_from_now}
</a>
2020-07-10 15:42:57 +08:00
:""
2020-06-04 18:28:26 +08:00
},
2020-03-16 14:12:11 +08:00
];
2020-06-04 18:28:26 +08:00
const urlRoot = filePath === undefined ? "" : `/${filePath}`;
let array = filePath && filePath.split("/");
2020-06-04 18:28:26 +08:00
return (
<Spin spinning={isSpin}>
2020-05-20 18:11:32 +08:00
<div className="main">
<div className="f-wrap-between mb20">
2020-04-21 16:30:51 +08:00
<div className="f-wrap-alignCenter">
<SelectBranch
repo_id={projectDetail && projectDetail.repo_id}
projectsId={projectsId}
2020-06-04 18:27:19 +08:00
branch={branch}
changeBranch={this.changeBranch}
2020-08-12 18:13:18 +08:00
owner={owner}
2020-06-04 18:27:19 +08:00
></SelectBranch>
2020-04-21 16:30:51 +08:00
2020-06-04 18:28:26 +08:00
{filePath && (
2020-04-21 16:30:51 +08:00
<span className="ml20 font-16">
2020-06-04 18:28:26 +08:00
<a
onClick={() => this.returnMain(branch)}
className="color-blue"
>
{projectDetail && projectDetail.identifier}
</a>
{array &&
array.map((item, key) => {
return (
2020-04-21 16:30:51 +08:00
<React.Fragment>
{
key === array.length-1 ?
<span className="color-grey-6 subFileName" key={key}>{item}</span>
:
2020-08-27 10:27:31 +08:00
<a onClick={()=>this.returnUlr(`${getPathUrl(array,key+1)}`)} className="color-blue subFileName">{item}</a>
2020-04-21 16:30:51 +08:00
}
</React.Fragment>
2020-06-04 18:28:26 +08:00
);
})}
</span>
)}
2020-03-16 14:12:11 +08:00
</div>
2020-04-21 16:30:51 +08:00
<div className="f-wrap-alignCenter">
2020-07-10 15:42:57 +08:00
{subFileType && (projectDetail && parseInt(projectDetail.type)) !== 2 && (isManager || isDeveloper) && (
2020-06-04 18:28:26 +08:00
<div>
<span>
2020-08-19 18:34:52 +08:00
<Link to={`/projects/${owner}/${projectsId}/${branch}/uploadfile${urlRoot}`} >
2020-06-05 11:46:56 +08:00
<span className="color-green mr30">上传文件</span>
</Link>
2020-06-04 18:28:26 +08:00
</span>
<span className="mr30">
2020-06-05 11:46:56 +08:00
<Link
2020-08-19 18:34:52 +08:00
to={`/projects/${owner}/${projectsId}/${branch}/newfile${urlRoot}`}
2020-06-04 18:28:26 +08:00
>
<span className="color-blue">新建文件</span>
2020-06-05 11:46:56 +08:00
</Link>
2020-06-04 18:28:26 +08:00
</span>
</div>
)}
{projectDetail && projectDetail.clone_url && (
<CloneAddress
http_url={projectDetail.clone_url}
2020-07-10 15:42:57 +08:00
downloadUrl={this.downloadUrl(zip_url,tar_url)}
2020-06-04 18:28:26 +08:00
showNotification={this.props.showNotification}
></CloneAddress>
)}
2020-04-21 16:30:51 +08:00
</div>
</div>
2020-04-21 16:30:51 +08:00
{/* 主目录列表 */}
2020-06-04 18:28:26 +08:00
{rootList && (
<RootTable
columns={columns}
data={rootList}
2020-07-10 15:42:57 +08:00
title={() => this.title(branchLastCommit,lastCommitAuthor)}
2020-06-04 18:28:26 +08:00
></RootTable>
)}
2020-04-21 16:30:51 +08:00
{/* 子目录列表、文件 */}
2020-06-04 18:28:26 +08:00
{fileDetail && fileDetail.length > 0 && (
<CoderRootFileDetail
detail={fileDetail[0]}
{...this.props}
{...this.state}
readOnly={this.state.readOnly}
2020-06-11 18:00:32 +08:00
onEdit={this.onEdit}
2020-06-04 18:28:26 +08:00
></CoderRootFileDetail>
)}
{
!rootList && !fileDetail && <Nodata _html="暂未发现当前文件!"/>
}
2020-04-21 16:30:51 +08:00
{/* readme.txt (isManager || isDeveloper)*/}
{ rootList && this.renderReadMeContent(readMeContent, isManager || isDeveloper)}
2020-04-21 16:30:51 +08:00
</div>
</Spin>
2020-06-04 18:28:26 +08:00
);
2020-03-16 14:12:11 +08:00
}
}
export default CoderRootDirectory;