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

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;