diff --git a/src/Loading.js b/src/Loading.js index 8175b7df8..c8e9c25df 100644 --- a/src/Loading.js +++ b/src/Loading.js @@ -4,7 +4,7 @@ import { Spin } from 'antd'; class Loading extends Component { componentDidUpdate(prevProps, prevState) { if (!prevProps.error && this.props.error) { - console.log(this.props.error) + // console.log(this.props.error) } } diff --git a/src/components/render-html.jsx b/src/components/render-html.jsx index e85dd061a..84a270549 100644 --- a/src/components/render-html.jsx +++ b/src/components/render-html.jsx @@ -1,15 +1,16 @@ -import React, { useEffect, useRef, useMemo } from 'react' -import 'katex/dist/katex.min.css' +import React, { useEffect, useRef, useMemo , useState } from 'react' +import 'katex/dist/katex.min.css'; import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked'; import 'code-prettify'; import dompurify from 'dompurify'; import { getEmoji } from '../forge/Main/emoji'; +import axios from 'axios'; import { renderToString } from 'katex' const preRegex = /]*>/g; const strRegexSub = /:([a-zA-Z_]+):/g; -// const quoteRegex = /[#]()/g; +const quoteRegex = /\[[#][0-9]{0,}\]\(\/\w{0,}\/\w{0,}\/issues\/[0-9]{0,}\)/g; function _unescape(str) { let div = document.createElement('div') div.innerHTML = str @@ -22,8 +23,29 @@ export default ({ value = '', className, style = {}, - url + url, + owner=undefined, + projectsId=undefined }) => { + const [ issues , setIssues ] = useState([]); + + useEffect(()=>{ + if(owner&&projectsId){ + getIssueList(); + } + },[owner,projectsId]) + + function getIssueList(){ + axios.get(`/v1/${owner}/${projectsId}/issues`,{params:{ + only_name:true,sort_direction:"desc",sort_by:"issues.created_on" + }}).then(result=>{ + if(result){ + let data = result.data.issues; + setIssues(data); + } + }) + } + let str = String(value); const html = useMemo(() => { let rs = marked(str); @@ -39,6 +61,26 @@ export default ({ rs = rs.replace(matchStr[i],getEmoji(matchStr[i])); } } + if(owner && projectsId && issues && issues.length>0){ + let matchQuote = str.match(quoteRegex); + if(matchQuote && matchQuote.length>0){ + let getIndexReg = /(?<=#)(.+?)(?=\])/g; + for(var x=0;x0 && getIndex[0]){ + let index = getIndex[0]; + let filter = issues.filter(f=>f.project_issues_index.toString() === index); + if(filter && filter.length === 1){ + let content = `#${index}:${filter[0].subject}`; + rs = rs.replace(`#${index}`,content); + }else{ + let content = `#${index}(已删除)`; + rs = rs.replace(`#${index}`,content); + } + } + } + } + } rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => { const { type, expression } = math_expressions[capture]; @@ -47,7 +89,7 @@ export default ({ rs = rs.replace(/▁/g, "▁▁▁") resetMathExpressions() return dompurify.sanitize(rs) - }, [str]); + }, [str,issues]); // 锚点跳转,链接地址里含#对应的id useEffect(()=>{ diff --git a/src/forge/Issues/Component/newPanel.jsx b/src/forge/Issues/Component/newPanel.jsx index 643ef2348..67a02943f 100644 --- a/src/forge/Issues/Component/newPanel.jsx +++ b/src/forge/Issues/Component/newPanel.jsx @@ -6,7 +6,7 @@ import Attachments from "../../Upload/attachment"; import UploadImg from '../Img/UploadImg.png'; function NewPanel(props,ref){ - const [ description , setDescription ] = useState(""); + const [ description , setDescription ] = useState(undefined); const [ fileList , setFileList] = useState(undefined); const [ attachments , setAttachments ] = useState([]); const [ save , setSave ] = useState([]); @@ -15,12 +15,11 @@ function NewPanel(props,ref){ const { createFunc , title , desc , files , onCancel , owner , projectsId } = props; const { form: { getFieldDecorator, validateFields , setFieldsValue } } = props; - useState(()=>{ title && setTimeout(()=>{ setFieldsValue({subject:title}); + desc && onContentChange(desc); },100) - desc && setDescription(desc); files && setAttachments(files); files && setSave(files); },[title , desc , files]) @@ -84,7 +83,7 @@ function NewPanel(props,ref){ {}) }else{ @@ -318,6 +321,7 @@ function Details(props){ props.history.push(`/${owner}/${projectsId}/issues/${index}`); }else{ setEdit(false); + window.scrollTo(0,0); } } @@ -367,7 +371,7 @@ function Details(props){ {...props} onCancel={onCancel} title={details.subject} - desc={details.description} + desc={edit ? desc : undefined} files={copy ? undefined : details.attachments} createFunc={createFunc} owner = {owner} projectsId = {projectsId} @@ -405,8 +409,8 @@ function Details(props){ }
- {details.description ? - + {desc ? + : 暂无描述 } diff --git a/src/modules/tpm/challengesnew/tpm-md-editor.js b/src/modules/tpm/challengesnew/tpm-md-editor.js index c5d3b56b3..f2901a757 100644 --- a/src/modules/tpm/challengesnew/tpm-md-editor.js +++ b/src/modules/tpm/challengesnew/tpm-md-editor.js @@ -74,7 +74,7 @@ function md_elocalStorage(editor, mdu, id) { return tid } -export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch, showNullButton = false, showResizeBar = false, startInit = true , forMember = true , isCanAtme = false , isQuoteIssue = false , changeAtWhoLoginList, owner, projectsId , isFocus = true}) => { +export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, className = '', noStorage = false, imageExpand = true, placeholder = '', width = '100%', height = 400, initValue = '', emoji, watch=true, showNullButton = false, showResizeBar = false, startInit = true , forMember = true , isCanAtme = false , isQuoteIssue = false , changeAtWhoLoginList, owner, projectsId , isFocus = true}) => { const editorEl = useRef(); const resizeBarEl = useRef(); @@ -130,11 +130,6 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla }) } - useEffect(()=>{ - if(initValue){ - console.log(initValue); - } - },[initValue]) // # 引用的弹框div const QuoteDiv = ( @@ -176,42 +171,44 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla } useEffect(()=>{ - if(quoteVisibleRef.current){ - const atWhoListDiv = document.getElementById("quoteDiv"); - const atWhoDivs = document.getElementsByClassName("quote"); - cmEl.addKeyMap({ - 'Up':()=>{ - let index; - for(let i = 0; i{ + let index; + for(let i = 0; i0){ + index <=atWhoDivs.length-4 && (atWhoListDiv.scrollTop -=40) + atWhoDivs[index].className = "quote"; + atWhoDivs[index-1].className = "quote active"; + } + }, + 'Down':()=>{ + let index; + for(let i = 0; i=3 && (atWhoListDiv.scrollTop +=40) + atWhoDivs[index].className = "quote"; + atWhoDivs[index+1].className = "quote active"; + } + }, + 'Enter':()=>{ + //找到classname为quote active的div,执行click事件 + if(document.getElementsByClassName("quote active")[0]){ + document.getElementsByClassName("quote active")[0].click(); + } } - if(index>0){ - index <=atWhoDivs.length-4 && (atWhoListDiv.scrollTop -=40) - atWhoDivs[index].className = "quote"; - atWhoDivs[index-1].className = "quote active"; - } - }, - 'Down':()=>{ - let index; - for(let i = 0; i=3 && (atWhoListDiv.scrollTop +=40) - atWhoDivs[index].className = "quote"; - atWhoDivs[index+1].className = "quote active"; - } - }, - 'Enter':()=>{ - //找到classname为quote active的div,执行click事件 - if(document.getElementsByClassName("quote active")[0]){ - document.getElementsByClassName("quote active")[0].click(); - } - } - }) - } else { - //移除上下、enter键监听 - cmEl && cmEl.removeKeyMap(); + }) + } else { + //移除上下、enter键监听 + cmEl.removeKeyMap(); + } } },[quoteVisible]) @@ -302,7 +299,7 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla } }) } - if(e.shiftKey && e.code === "Digit3"){ + if(e.shiftKey && e.code === "Digit3" && isQuoteIssue){ // 输入#键后在对应的位置显示可选的项目issue quoteVisibleRef.current = true; setQuoteVisible(true); @@ -348,8 +345,7 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla htmlDecode: "style,script,iframe", sequenceDiagram: true, autoFocus: false, - watch: watch === undefined ? true : watch, - + watch: watch, saveHTMLToTextarea: true, dialogMaskOpacity: 0.6, placeholder: placeholder, @@ -471,10 +467,11 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla } },[users]) + useEffect(() => { if (cmEl) { let tid = null - let ro + let ro; if (onCMBlur) { editorInstance.cm.on('blur', () => { onCMBlur(editorInstance.getValue()) }) } @@ -750,15 +747,13 @@ export default ({ mdID, onChange, onCMBeforeChange, onCMBlur, error = false, cla document.removeEventListener('mouseup', onMouseUp) } } - }, [ - editorInstance, resizeBarEl - ]) + }, [ editorInstance, resizeBarEl ]) return ( {atWhoVisible && atWhoList} - {quoteVisible && QuoteDiv }
+ {quoteVisible && QuoteDiv }