forked from Gitlink/forgeplus-react
Merge pull request 'wiki集成锚点和独立路由功能' (#524) from durian/forgeplus-react:dev_military_osredm into dev_military_osredm
This commit is contained in:
commit
6387d2c775
|
@ -222,7 +222,7 @@
|
||||||
"webpack": "^4.42.1",
|
"webpack": "^4.42.1",
|
||||||
"webpack-bundle-analyzer": "^3.7.0"
|
"webpack-bundle-analyzer": "^3.7.0"
|
||||||
},
|
},
|
||||||
"volta":{
|
"volta": {
|
||||||
"node":"8.12.0"
|
"node": "8.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,16 @@
|
||||||
$('#ie_info').css({display:'block'});
|
$('#ie_info').css({display:'block'});
|
||||||
$('#root').css({display:'none'});
|
$('#root').css({display:'none'});
|
||||||
}
|
}
|
||||||
</script>
|
window.onload=function(){
|
||||||
|
$(".newContainer").delegate("a.anchors","click",function(){
|
||||||
|
let h = $(this).offset().top - 180;
|
||||||
|
$("html,body").animate({scrollTop:h},10);
|
||||||
|
window.location.hash = $(this).attr("name");
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<script src="%PUBLIC_URL%js/js_min_all.js"></script>
|
<script src="%PUBLIC_URL%js/js_min_all.js"></script>
|
||||||
<script src="%PUBLIC_URL%js/codemirror/codemirror.js"></script>
|
<script src="%PUBLIC_URL%js/codemirror/codemirror.js"></script>
|
||||||
<script src="%PUBLIC_URL%js/editormd/editormd.min.js"></script>
|
<script src="%PUBLIC_URL%js/editormd/editormd.min.js"></script>
|
||||||
|
|
|
@ -33,7 +33,8 @@ export function initAxiosInterceptors(props) {
|
||||||
initOnlineOfflineListener();
|
initOnlineOfflineListener();
|
||||||
|
|
||||||
// var proxy = "http://192.168.1.40:3000";
|
// var proxy = "http://192.168.1.40:3000";
|
||||||
var proxy = "http://111.8.36.180:8000";
|
// var proxy = "http://111.8.36.180:8000";
|
||||||
|
var proxy = "http://117.50.100.12:49999"
|
||||||
// var proxy = "https://www.osredm.com";
|
// var proxy = "https://www.osredm.com";
|
||||||
|
|
||||||
//响应前的设置
|
//响应前的设置
|
||||||
|
|
|
@ -155,7 +155,8 @@ renderer.heading = function (text, level, raw) {
|
||||||
level: level,
|
level: level,
|
||||||
text: text
|
text: text
|
||||||
})
|
})
|
||||||
return '<h' + level + ' id="' + anchor + '">' + text + '</h' + level + '>'
|
let id = anchor.replace(/[.,/#!$%^&*;:{}=\-_`~():,。¥;「」|?》《~·【】‘、!]/g,"");
|
||||||
|
return '<h' + level + ' id="' + id + '" class="markdown_anchors"><a name="#'+id+'" class="anchors"><i class="iconfont icon-lianjieicon font-14"></i></a>' + text + '</h' + level + '>'
|
||||||
}
|
}
|
||||||
marked.setOptions({
|
marked.setOptions({
|
||||||
silent: true,
|
silent: true,
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import React, { useEffect, useRef, useMemo } from 'react'
|
import React, { useEffect, useRef, useMemo } from 'react'
|
||||||
import 'katex/dist/katex.min.css'
|
import 'katex/dist/katex.min.css'
|
||||||
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked';
|
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked';
|
||||||
import 'code-prettify'
|
import 'code-prettify';
|
||||||
import dompurify from 'dompurify';
|
import dompurify from 'dompurify';
|
||||||
|
|
||||||
import { renderToString } from 'katex'
|
import { renderToString } from 'katex'
|
||||||
|
|
||||||
const preRegex = /<pre[^>]*>/g
|
const preRegex = /<pre[^>]*>/g;
|
||||||
function _unescape(str) {
|
function _unescape(str) {
|
||||||
let div = document.createElement('div')
|
let div = document.createElement('div')
|
||||||
div.innerHTML = str
|
div.innerHTML = str
|
||||||
|
@ -46,7 +46,7 @@ export default ({
|
||||||
let id = decodeURIComponent(u.split("#")[1]);
|
let id = decodeURIComponent(u.split("#")[1]);
|
||||||
let ele = document.getElementById(id);
|
let ele = document.getElementById(id);
|
||||||
if(ele){
|
if(ele){
|
||||||
window.scrollTo(0, ele.offsetTop + 120);
|
window.scrollTo(0, ele.offsetTop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,8 @@ export default Form.create()(({ form, history, showNotification, projectDetail,
|
||||||
}
|
}
|
||||||
|
|
||||||
function goBack() {
|
function goBack() {
|
||||||
history.push(`/${owner}/${projectsId}/wiki`);
|
// history.push(`/${owner}/${projectsId}/wiki`);
|
||||||
|
window.location.href = `/${owner}/${projectsId}/wiki`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeModal(e) {
|
function changeModal(e) {
|
||||||
|
|
|
@ -9,17 +9,18 @@ import { wikiPages, getWiki, deleteWiki } from './api';
|
||||||
import { httpUrl, TokenKey } from './fetch';
|
import { httpUrl, TokenKey } from './fetch';
|
||||||
import './Index.scss';
|
import './Index.scss';
|
||||||
import { isArray } from 'lodash';
|
import { isArray } from 'lodash';
|
||||||
|
import RenderHtml from '../../components/render-html';
|
||||||
const Search = Input.Search;
|
const Search = Input.Search;
|
||||||
const InputGroup = Input.Group;
|
const InputGroup = Input.Group;
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
const { match, history, showNotification, project, projectDetail } = props;
|
const { match, history, showNotification, project, projectDetail, history:{location:{pathname}} } = props;
|
||||||
const permission = projectDetail && projectDetail.permission && projectDetail.permission !== "Reporter";
|
const permission = projectDetail && projectDetail.permission && projectDetail.permission !== "Reporter";
|
||||||
|
|
||||||
let projectsId = match.params.projectsId;
|
let projectsId = match.params.projectsId;
|
||||||
let owner = match.params.owner;
|
let owner = match.params.owner;
|
||||||
|
let wikiName = pathname && pathname.split('/').pop();
|
||||||
const [fileArrInit, setFileArrInit] = useState(null);
|
const [fileArrInit, setFileArrInit] = useState(null);
|
||||||
const [checkItem, setCheckItem] = useState({});
|
const [checkItem, setCheckItem] = useState({});
|
||||||
const [itemDetail, setItemDetail] = useState({});
|
const [itemDetail, setItemDetail] = useState({});
|
||||||
|
@ -40,7 +41,12 @@ export default (props) => {
|
||||||
setFileArr(res.data);
|
setFileArr(res.data);
|
||||||
setFileArrInit(res.data);
|
setFileArrInit(res.data);
|
||||||
if (res.data.length) {
|
if (res.data.length) {
|
||||||
setCheckItem(res.data[0]);
|
if (wikiName) {
|
||||||
|
let activeItem = res.data.filter(item => { return item.name == wikiName })[0] || res.data[0];
|
||||||
|
setCheckItem(activeItem)
|
||||||
|
} else {
|
||||||
|
setCheckItem(res.data[0]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
setFileArr([]);
|
setFileArr([]);
|
||||||
|
@ -69,7 +75,7 @@ export default (props) => {
|
||||||
let value = e.target.value;
|
let value = e.target.value;
|
||||||
let newFileArr = [];
|
let newFileArr = [];
|
||||||
for (const item of fileArrInit) {
|
for (const item of fileArrInit) {
|
||||||
if (item.name.indexOf(value) > -1) {
|
if (item.name.match(new RegExp(value, 'i'))) {
|
||||||
newFileArr.push(item);
|
newFileArr.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,10 +171,10 @@ export default (props) => {
|
||||||
const uploadProps = {
|
const uploadProps = {
|
||||||
name: 'multipartFile',
|
name: 'multipartFile',
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
action: `${httpUrl}/api/wikiExport/uploadWiki/${owner}/${projectsId}/${project && project.id}`, //?token=${sessionStorage.taskToken}
|
action: `${httpUrl}/api/wikiExport/uploadWiki/${owner}/${projectsId}/${project && project.id}`,
|
||||||
showUploadList: false,
|
showUploadList: false,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: cookie.load(TokenKey) || sessionStorage.taskToken,
|
Authorization: cookie.load(TokenKey),
|
||||||
},
|
},
|
||||||
beforeUpload: beforeUpload,
|
beforeUpload: beforeUpload,
|
||||||
onChange(info) {
|
onChange(info) {
|
||||||
|
@ -191,6 +197,11 @@ export default (props) => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function changeItem(item){
|
||||||
|
history.push(`/${owner}/${projectsId}/wiki/${item.name}`)
|
||||||
|
setCheckItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
< Spin spinning={!fileArrInit} className="opacitySpin">
|
< Spin spinning={!fileArrInit} className="opacitySpin">
|
||||||
{fileArrInit && fileArrInit.length ?
|
{fileArrInit && fileArrInit.length ?
|
||||||
|
@ -234,10 +245,10 @@ export default (props) => {
|
||||||
{
|
{
|
||||||
fileArr.map(item => {
|
fileArr.map(item => {
|
||||||
return <div className="wiki-nav-title-parent" key={item.name}>
|
return <div className="wiki-nav-title-parent" key={item.name}>
|
||||||
<div className={`wiki-nav-title ${item.name === checkItem.name ? 'active' : ''}`} onClick={() => { setCheckItem(item) }}>
|
<div className={`wiki-nav-title ${item.name === checkItem.name ? 'active' : ''}`} onClick={() => { changeItem(item) }}>
|
||||||
<div className="nav-title-left">
|
<div className="nav-title-left">
|
||||||
<i className="iconfont icon-wenjianjia2 mr3"></i>
|
<i className="iconfont icon-wenjianjia2 mr3"></i>
|
||||||
<span className="nav-title-left-text">{item.name}</span>
|
<span className="nav-title-left-text">{item.name.substring(0, item.name.indexOf('.') !== -1 ? item.name.lastIndexOf('.') : item.name.length-1)}</span>
|
||||||
</div>
|
</div>
|
||||||
{permission && <i className="iconfont icon-shanchuicon1 delete-title-icon color-grey-6" onClick={(e) => { deleteFileModal(e, item) }}></i>}
|
{permission && <i className="iconfont icon-shanchuicon1 delete-title-icon color-grey-6" onClick={(e) => { deleteFileModal(e, item) }}></i>}
|
||||||
</div>
|
</div>
|
||||||
|
@ -271,7 +282,7 @@ export default (props) => {
|
||||||
{permission && <Button type="primary" onClick={goEdit}>编辑</Button>}
|
{permission && <Button type="primary" onClick={goEdit}>编辑</Button>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="wiki-content-detail editor-content-panel markdown-body" dangerouslySetInnerHTML={{ __html: itemDetail && itemDetail.simple_content }} ></div>
|
{itemDetail && itemDetail.md_content && <RenderHtml className="wiki-content-detail editor-content-panel" value={ itemDetail.md_content } url={history.location}/>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div >
|
</div >
|
||||||
|
|
|
@ -8,6 +8,6 @@ let actionUrl = settings && settings.common.wiki;
|
||||||
const service = javaFetch(actionUrl);
|
const service = javaFetch(actionUrl);
|
||||||
export const httpUrl = actionUrl;
|
export const httpUrl = actionUrl;
|
||||||
export default service;
|
export default service;
|
||||||
|
export const TokenKey = 'autologin_trustie';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -394,4 +394,22 @@ button.btngrey{
|
||||||
border-color:rgba(153, 153, 153, 0.5);
|
border-color:rgba(153, 153, 153, 0.5);
|
||||||
color: #666666;
|
color: #666666;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.markdown_anchors{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.markdown_anchors:hover {
|
||||||
|
.anchors{
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.markdown_anchors {
|
||||||
|
.anchors:hover{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.markdown_anchors .anchors {
|
||||||
|
color: inherit;
|
||||||
|
margin-left: -14px;
|
||||||
|
display: none;
|
||||||
}
|
}
|
Loading…
Reference in New Issue