forked from Gitlink/forgeplus-react
336 lines
9.7 KiB
JavaScript
336 lines
9.7 KiB
JavaScript
import React, { Component } from "react";
|
|
import { Popconfirm , Select , Dropdown , Spin , Anchor } from "antd";
|
|
import "./list.scss";
|
|
import axios from "axios";
|
|
import Meditor from "../Newfile/m_editor";
|
|
import RenderHtml from "../../components/render-html";
|
|
import ReadmeCatelogue from "./sub/ReadmeCatelogue";
|
|
|
|
const $ = window.$;
|
|
function bytesToSize(bytes) {
|
|
if (bytes === 0) return "0 B";
|
|
let k = 1024,
|
|
sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
|
|
i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return (bytes / Math.pow(k, i)).toFixed(2) + " " + sizes[i];
|
|
}
|
|
class CoderRootFileDetail extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
value: undefined,
|
|
language: undefined,
|
|
languages: undefined,
|
|
description: props.detail.replace_content,
|
|
menuList:undefined
|
|
};
|
|
}
|
|
|
|
componentDidMount = () => {
|
|
window.scrollTo(0, 0);
|
|
const { detail , mdFlag } = this.props;
|
|
this.setState({
|
|
value: detail.content,
|
|
});
|
|
this.languages_total();
|
|
};
|
|
|
|
componentDidUpdate=(prevProps)=>{
|
|
const { replace_content } = this.props && this.props.detail;
|
|
const prevcontent = prevProps.detail && prevProps.detail.replace_content;
|
|
if (replace_content && prevcontent) {
|
|
if (prevcontent !== replace_content){
|
|
this.setState({
|
|
description: replace_content
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
languages_total = () => {
|
|
const { detail } = this.props;
|
|
const file_name = detail.path.split("/").pop().split(".").pop();
|
|
let languages = [];
|
|
let default_language = "javascript";
|
|
let all_languages = {
|
|
apex: ["apex", "apxc"],
|
|
azcli: ["azcli"],
|
|
bat: ["bat"],
|
|
clojure: ["clj"],
|
|
coffee: ["coffee"],
|
|
cpp: ["cpp"],
|
|
csharp: ["cs"],
|
|
csp: ["csp"],
|
|
css: ["css"],
|
|
dockerfile: ["dockerfile", "docker", "yml"],
|
|
fsharp: ["fs"],
|
|
go: ["go"],
|
|
html: ["html", "htm", "erb"],
|
|
ini: ["ini"],
|
|
java: ["java", "class"],
|
|
javascript: ["js"],
|
|
json: ["json"],
|
|
less: ["less"],
|
|
lua: ["lua"],
|
|
markdown: ["markdown", "md", "rmd"],
|
|
msdax: ["dax"],
|
|
mysql: ["sql"],
|
|
objective: ["m", "mm", "o", "out"],
|
|
perl: ["perl"],
|
|
pgsql: ["sql"],
|
|
php: ["php"],
|
|
postiats: ["postiats"],
|
|
powerquery: [""],
|
|
powershell: ["ps1"],
|
|
pug: ["pug"],
|
|
python: ["py"],
|
|
r: ["r"],
|
|
razor: ["cshtml"],
|
|
redis: ["rdb"],
|
|
ruby: ["rb"],
|
|
rust: ["rs"],
|
|
sb: ["sb"],
|
|
scheme: ["scm", "ss"],
|
|
scss: ["scss"],
|
|
shell: ["sh"],
|
|
solidity: ["sol"],
|
|
sql: ["sql"],
|
|
st: ["st"],
|
|
swift: ["swift"],
|
|
typescript: ["ts"],
|
|
vb: ["vbp", "frm", "frx", "bas", "cls"],
|
|
xml: ["xml"],
|
|
yaml: ["yml"],
|
|
};
|
|
for (var item in all_languages) {
|
|
languages.push(item);
|
|
let item_values = all_languages[item];
|
|
if (item_values.indexOf(file_name) !== -1) {
|
|
default_language = item;
|
|
}
|
|
}
|
|
this.setState({
|
|
languages,
|
|
language: default_language
|
|
})
|
|
};
|
|
|
|
select_language = (e) => {
|
|
this.setState({
|
|
language: e,
|
|
});
|
|
};
|
|
EditFile = (flag) => {
|
|
const { onEdit } = this.props;
|
|
onEdit && onEdit(flag);
|
|
};
|
|
|
|
DownLoadFile = (url) => {
|
|
let download_url = "/attachments/entries/get_file?download_url=" + url
|
|
window.open(download_url)
|
|
}
|
|
|
|
// 编辑文件
|
|
|
|
changeMmirror = (e, e1, value) => {
|
|
this.setState({
|
|
value,
|
|
});
|
|
};
|
|
|
|
deleteFile = () => {
|
|
const { detail } = this.props;
|
|
const { projectsId, owner ,branchName} = this.props.match.params;
|
|
|
|
const url = `/${owner}/${projectsId}/delete_file.json`;
|
|
axios.delete(url, {
|
|
params: {
|
|
filepath: detail.path,
|
|
branch:branchName,
|
|
sha: detail.sha,
|
|
},
|
|
})
|
|
.then((result) => {
|
|
if (result) {
|
|
this.props.showNotification("删除成功!");
|
|
this.props.history.push(`/${owner}/${projectsId}`);
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
};
|
|
|
|
updateCode = (value) => {
|
|
this.setState({
|
|
value,
|
|
});
|
|
};
|
|
|
|
onContentChange = (value) => {
|
|
this.setState({
|
|
description: value,
|
|
});
|
|
};
|
|
|
|
renderMenulist=()=>{
|
|
const { description } = this.state;
|
|
if(description){
|
|
const items = $.map($("#files-md").find("h1,h2,h3,h4,h5,h6"), function (el, _) {
|
|
const anchor = el.id;
|
|
const level = el.tagName.replace("H", "");
|
|
const href = `#${anchor}`;
|
|
return { href:`${href}`,text:el.textContent , level:level }
|
|
});
|
|
return items;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
menu=()=>{
|
|
const menuList = this.renderMenulist();
|
|
if(menuList && menuList.length > 0){
|
|
return(
|
|
<ReadmeCatelogue menuList={menuList} hash={this.props.history.location.hash}/>
|
|
)
|
|
}else{
|
|
return <Spin />
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const {
|
|
readOnly,
|
|
detail,
|
|
current_user,
|
|
isManager,
|
|
isDeveloper,
|
|
currentBranch,
|
|
platform,
|
|
md,
|
|
type
|
|
} = this.props;
|
|
const { language, languages, description } = this.state;
|
|
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
|
const Option = Select.Option;
|
|
return (
|
|
<React.Fragment>
|
|
<Anchor className="griditemAnchor" offsetTop={58}>
|
|
<div className="griditemCate">
|
|
{
|
|
md && readOnly &&
|
|
<Dropdown overlay={this.menu()} trigger={['hover']} overlayClassName="menuslist">
|
|
<span className="catelogue mr20">
|
|
<i className="iconfont icon-muluicon font-12 mr5"></i>
|
|
<span>目录</span>
|
|
</span>
|
|
</Dropdown>
|
|
}
|
|
<span className="color-grey-6 font-16">
|
|
{bytesToSize(detail && detail.size)}
|
|
</span>
|
|
</div>
|
|
<p className="text-right">
|
|
{flag && platform && (
|
|
<div>
|
|
{readOnly ? (
|
|
<span>
|
|
{
|
|
!detail.direct_download?
|
|
<span>
|
|
<a onClick={() => this.DownLoadFile(detail.download_url)} className="ml20">
|
|
<i className="iconfont icon-xiazai1 font-15 color-grey-6"></i>
|
|
</a>
|
|
{
|
|
type !==2 &&
|
|
<a onClick={() => this.EditFile(false)} className="ml20">
|
|
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
|
</a>
|
|
}
|
|
</span>:""
|
|
}
|
|
</span>
|
|
) : (
|
|
<React.Fragment>
|
|
<Select
|
|
showSearch={true}
|
|
placeholder={"请选择文本语言"}
|
|
style={{ width: 200 }}
|
|
value={language}
|
|
onChange={this.select_language}
|
|
>
|
|
<Option value={undefined}>请选择文本语言</Option>
|
|
{languages &&
|
|
languages.map((item, key) => {
|
|
return (
|
|
<Option value={item} key={key}>
|
|
{item}
|
|
</Option>
|
|
);
|
|
})}
|
|
</Select>
|
|
<button
|
|
type="button"
|
|
className="ant-btn ant-btn-sm ml20"
|
|
onClick={() => this.EditFile(true)}
|
|
>
|
|
<span>取 消</span>
|
|
</button>
|
|
</React.Fragment>
|
|
)}
|
|
{
|
|
type !==2 &&
|
|
<Popconfirm
|
|
title="确认删除这个文件?"
|
|
className="ml20"
|
|
okText="确定"
|
|
cancelText="取消"
|
|
onConfirm={this.deleteFile}
|
|
>
|
|
<a>
|
|
<i className="iconfont icon-shanchu font-15 color-grey-6"></i>
|
|
</a>
|
|
</Popconfirm>
|
|
}
|
|
|
|
</div>
|
|
)}
|
|
</p>
|
|
</Anchor>
|
|
<div>
|
|
{detail.image_type ? (
|
|
<div className="edu-txt-center pt20 pb20">
|
|
<img alt="" src={detail.download_url} style={{ maxWidth: "80%" }} />
|
|
</div>
|
|
) : detail.direct_download ? (
|
|
<div className="mt20 text-center">
|
|
<a href={detail.download_url} className="color-blue font-15">
|
|
下载原始文件
|
|
</a>
|
|
</div>
|
|
) : (
|
|
md && readOnly ?
|
|
<div className="files-md" id="files-md">
|
|
<RenderHtml className="file-md imageLayerParent" value={description} url={this.props.history.location}/>
|
|
</div>
|
|
:
|
|
<Meditor
|
|
{...this.props}
|
|
{...this.state}
|
|
language={language ? language : "javascript"}
|
|
filepath={`/${detail.path}`}
|
|
content={detail.content}
|
|
readOnly={readOnly}
|
|
editorType="update"
|
|
currentBranch={currentBranch}
|
|
descName={detail && `Update ${detail.name}`}
|
|
></Meditor>
|
|
)}
|
|
</div>
|
|
</React.Fragment>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default CoderRootFileDetail;
|