Merge remote-tracking branch 'origin/master'

dev_forum
杨树明 5 years ago
commit 23224a437d

@ -39,18 +39,29 @@ class DMDEditor extends Component{
onChange = (val) => {
// this.setState({ value: val })
this.props.onChange(val)
if (this.state.showError == true) {
this.setState({showError: false})
}
}
showError = () => {
this.mdRef.current.showError()
this.setState({showError: true})
}
render(){
const { mdMode } = this.state;
const { mdMode, showError } = this.state;
const { initValue } = this.props;
let _style = {}
if (showError) {
_style.border = '1px solid red'
}
_style = Object.assign(_style, {display: mdMode == true ? 'none' : '', color: initValue? '': '#999', alignItems: 'center', wordBreak: 'break-all'})
return(
<React.Fragment>
<style>{`
`}</style>
<div id="content_editorMd_show" className="new_li content_editorMd_show"
style={{display: mdMode == true ? 'none' : '', color: initValue? '': '#999', alignItems: 'center', wordBreak: 'break-all'}}
style={_style}
dangerouslySetInnerHTML={{__html: initValue ? markdownToHTML(initValue):this.props.placeholder}}
onClick={this.toMDMode}
>

@ -238,6 +238,7 @@
width: 100%;
word-wrap: break-word;
margin-bottom: 4px;
margin-top: 4px;
}
.childComment .break_word_comments{
line-height: 22px;

@ -96,7 +96,7 @@ class CommentItemMDEditor extends Component {
}
render() {
const { match, history, item, user } = this.props
const { match, history, item, user, buttonText } = this.props
if (!item) {
return <div></div>
}
@ -111,7 +111,7 @@ class CommentItemMDEditor extends Component {
</a>
</div>
<div id={`reply_message_${item.id}`} className="reply_to_message commentItemMDEditor"
style={{ paddingTop: '0px', paddingBottom: '20px', marginTop: '36px' }}
style={{ paddingTop: '0px', paddingBottom: '0px', marginTop: '36px' }}
>
<div id={`reply_message_editorMd_${item.id}`} className="editorMD" style={{ marginBottom: '0px'}}>
<textarea style={{'display': 'none'}}>
@ -119,11 +119,14 @@ class CommentItemMDEditor extends Component {
</div>
<div className="editor__resize" href="javascript:void(0);" style={{display: ''}}>调整高度</div>
<a id={`commitBtn_${item.id}`} href="javascript:void(0)"
onClick={this.onCommit} style={{ marginRight: '44px' }}
className="commentsbtn task-btn task-btn-blue fr " style={{display: ''}}>
发送
</a>
<div class="clearfix">
<a id={`commitBtn_${item.id}`} href="javascript:void(0)"
onClick={this.onCommit} style={{ marginRight: '44px' }}
className="commentsbtn task-btn task-btn-blue fr " style={{display: ''}}>
{ buttonText || '发送'}
</a>
</div>
</div>
</div>
);

@ -408,6 +408,7 @@ class Comments extends Component {
currentReplyComment={currentReplyComment}
item={item}
user={user}
buttonText={this.props.buttonText}
>
</CommentItemMDEditor>
}

@ -416,7 +416,7 @@ class TopicDetail extends Component {
const user = this._getUser();
this.setState({
comments: addNewComment(comments, _id, content, user)
comments: addNewComment(comments, _id, content, user, this)
})
const newMemo2 = Object.assign({}, this.state.memo);
newMemo2.total_replies_count = newMemo2.total_replies_count + 1;
@ -526,8 +526,15 @@ class TopicDetail extends Component {
const courseId=this.props.match.params.coursesId;
const boardId = this.props.match.params.boardId
return (
<div className="edu-back-white edu-class-container edu-position course-message" id="forum_index_list"> {/* fl with100 */}
<div className="edu-back-white edu-class-container edu-position course-message topicDetail" id="forum_index_list"> {/* fl with100 */}
<style>{`
.topicDetail #forum_list .return_btn.no_mr {
margin-right: 1px;
}
/* 有内容时,编辑器下方的边框*/
.topicDetail .borderBottom.commentInputs {
border-bottom: 1px solid rgb(238, 238, 238);
}
.independent {
background: rgb(250, 250, 250);
padding-bottom: 20px;
@ -658,7 +665,7 @@ class TopicDetail extends Component {
</div>
<MemoDetailMDEditor ref="editor" memo={memo} usingMockInput={true} placeholder="说点什么"
height={160} showError={true} buttonText={'发表'}></MemoDetailMDEditor>
height={160} showError={true} buttonText={'发表'} className={comments && comments.length && 'borderBottom'}></MemoDetailMDEditor>
{/* onClick={ this.createNewComment }
enableReplyTo={true}

@ -64,13 +64,13 @@ export function handleContentBeforeCreateNew(argContent) {
return content
}
export function addNewComment(comments, _id, content, user, isSuperAdmin) {
export function addNewComment(comments, _id, content, user, isSuperAdmin, parentComponent) {
if (!comments) {
comments = [];
}
comments.unshift( {
"can_delete": true,
"admin": user.admin,
"admin": parentComponent ? parentComponent.props.isAdmin() : user.admin ,
isSuperAdmin: isSuperAdmin,
"content": content,

@ -175,7 +175,7 @@ class CCommentItem extends Component{
// src={getImageUrl(`images/${item.image_url}`)}
return (
<div className="comment_item_cont df clearfix" key={item.id}>
<div className="comment_item_cont appraise df clearfix" key={item.id}>
<div className="J_Comment_Face fl">
{item.is_appeal_info == true ?
<a href={`javascript:void(0)`} target="_blank">

@ -76,7 +76,7 @@ class CommonReply extends Component{
const isSuperAdmin = this.props.isSuperAdmin()
this.setState({
comments: addNewComment(this.state.comments, _id, content, user, isSuperAdmin),
comments: addNewComment(this.state.comments, _id, content, user, isSuperAdmin, this),
total_count: this.state.total_count + 1
})
this.refs.editor.showEditor();

@ -38,8 +38,10 @@
margin-top: 8px;
}
.course-message .comment_item_cont:last-child {
/* 作品评阅需要 */
border-bottom: none;
}
.course-message .appraise.comment_item_cont:last-child {
/* 作品评阅需要 */
padding-bottom: 0px;
}

@ -55,21 +55,25 @@ class SingleEditor extends Component{
// TODO check
const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1);
if(!question_title) {
this.props.showNotification('请先输入题目题干'); return;
this.refs['titleEditor'].showError()
this.props.showNotification('题目:不能为空'); return;
}
const intScore = parseFloat(question_score)
if(!question_score || intScore == NaN) {
this.props.showNotification('分值不能为空'); return;
this.props.showNotification('分值不能为空'); return;
} else {
if (intScore == 0) {
this.props.showNotification('分值必须大于0'); return;
this.props.showNotification('分值必须大于0'); return;
}
}
if(!answerArray || answerArray.length == 0) {
this.props.showNotification('请先点击本题的正确选项'); return;
this.props.showNotification('必须设置标准答案'); return;
}
if(!question_title) {
this.props.showNotification('请先输入题目题干'); return;
this.refs['titleEditor'].showError()
this.props.showNotification('题目:不能为空'); return;
}
/**
@ -185,6 +189,7 @@ class SingleEditor extends Component{
<TPMMDEditor mdID={`question_${question_id}`} placeholder="请您输入题目" height={155} watch={false}
initValue={question_title} onChange={(val) => this.setState({ question_title: val})}
ref="titleEditor"
></TPMMDEditor>
<div>

@ -45,14 +45,17 @@ class MainEditor extends Component{
// TODO check
const answerArray = standard_answers
if(!question_title) {
this.props.showNotification('请先输入题目题干'); return;
this.refs['titleEditor'].showError()
this.props.showNotification('题目:不能为空'); return;
}
const intScore = parseFloat(question_score)
if(!question_score || intScore == NaN) {
this.props.showNotification('分值不能为空'); return;
this.props.showNotification('分值不能为空'); return;
} else {
if (intScore == 0) {
this.props.showNotification('分值必须大于0'); return;
this.props.showNotification('分值必须大于0'); return;
}
}
// if(!answerArray || answerArray.length == 0 || !answerArray[0]) {
@ -151,7 +154,7 @@ class MainEditor extends Component{
<TPMMDEditor mdID={`question_${question_id}`} placeholder="请您输入题目" height={155} watch={false}
initValue={question_title} onChange={(val) => this.setState({ question_title: val})}
noStorage={true}
noStorage={true} ref="titleEditor"
></TPMMDEditor>
<div>

@ -35,6 +35,10 @@ class NullChildEditor extends Component{
// this.mdReactObject = that;
// }
showError = (itemIndex) => {
this.refs[`nullChildDMDEditor${itemIndex}`].showError()
}
render() {
let { question_title, question_score, question_type, question_choices, standard_answers } = this.state;
let { question_id, index, onAnswerChange, addChildAnswer, toMDMode, exerciseIsPublish,
@ -49,6 +53,7 @@ class NullChildEditor extends Component{
return <div className="df flex1" >
<div className="flex1" style={{ flex: '0 0 1000px'}}>
<DMDEditor
ref={`nullChildDMDEditor${itemIndex}`}
className={'nullChildEditor'}
placeholder={`请输入参考答案${itemIndex == 0 ?'':'(可选)'}`}
toMDMode={toMDMode} noStorage={true}

@ -69,14 +69,16 @@ class NullEditor extends Component{
// const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1);
let answerArray = []
if(!question_title) {
this.props.showNotification('请先输入题目题干'); return;
this.refs['titleEditor'].showError()
this.props.showNotification('题目:不能为空'); return;
}
const intScore = parseFloat(question_score)
if(!question_score || intScore == NaN) {
this.props.showNotification('分值不能为空'); return;
this.props.showNotification('分值不能为空'); return;
} else {
if (intScore == 0) {
this.props.showNotification('分值必须大于0'); return;
this.props.showNotification('分值必须大于0'); return;
}
}
let isEmpty = false;
@ -88,7 +90,9 @@ class NullEditor extends Component{
answers.forEach((item, itemIndex) => {
answerArray[index].answer_text.push(item)
if(!item) {
this.props.showNotification(`请先输入第${index+1}个填空的第${itemIndex+1}参考答案。`);
this.refs[`nullChildEditor${index}`].showError(itemIndex)
// this.props.showNotification(`请先输入第${index+1}个填空的第${itemIndex+1}参考答案。`);
this.props.showNotification(`答案:不能为空`);
isEmpty = true;
}
})
@ -97,7 +101,9 @@ class NullEditor extends Component{
return;
}
if(!question_title) {
this.props.showNotification('请先输入题目题干'); return;
this.refs['titleEditor'].showError()
this.props.showNotification('题目:不能为空'); return;
}
/**
@ -294,13 +300,16 @@ class NullEditor extends Component{
<NullMDEditor {...this.props} mdID={`question_${question_id}`} placeholder="请您输入题目" height={155} watch={false}
initValue={question_title} onChange={(val) => this.setState({ question_title: val})}
onPlaceholderChange={this.onPlaceholderChange} showNullButton={exerciseIsPublish ? false : true}
ref="titleEditor"
></NullMDEditor>
<div className="clearfix">
{
standard_answers.map((answers, index) => {
return <NullChildEditor {...this.props}
return <NullChildEditor
ref={`nullChildEditor${index}`}
{...this.props}
toMDMode={this.toMDMode}
answers={answers}
index={index}

@ -84,7 +84,9 @@ export default class NullMDEditor extends Component {
}
showError = () => {
this.refs['nullMDEditor'].showError()
}
render() {
let {
@ -94,6 +96,7 @@ export default class NullMDEditor extends Component {
return (
<TPMMDEditor {...this.props}
onCMBeforeChange={this.onCMBeforeChange}
ref='nullMDEditor'
>
</TPMMDEditor>
)

@ -98,7 +98,7 @@ class ShixunEditor extends Component{
// }
for(let _i = 0; _i < question_scores.length; _i++) {
if (!question_scores[_i] || question_scores[_i] == '0') {
this.props.showNotification(`${_i+1}题的分值必须大于0`); return;
this.props.showNotification(`${_i+1}题的分值必须大于0`); return;
}
}

@ -87,7 +87,10 @@ class SingleEditor extends Component{
// TODO check
const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1);
if(!question_title) {
this.props.showNotification('请先输入题目题干'); return;
this.refs['titleEditor'].showError()
this.props.showNotification('题目:不能为空'); return;
}
const intScore = parseFloat(question_score)
if(!question_score || intScore == NaN) {
@ -101,11 +104,15 @@ class SingleEditor extends Component{
this.props.showNotification('请先点击选择本选择题的正确选项'); return;
}
if(!question_title) {
this.props.showNotification('请先输入题目题干'); return;
this.refs['titleEditor'].showError()
this.props.showNotification('题目:不能为空'); return;
}
for(let i = 0; i < question_choices.length; i++) {
if (!question_choices[i]) {
this.refs[`optionEditor${i}`].showError()
this.props.showNotification(`请先输入 ${tagArray[i]} 选项的内容`); return;
}
}
@ -237,6 +244,8 @@ class SingleEditor extends Component{
<TPMMDEditor mdID={qNumber} placeholder="请您输入题目" height={155} watch={false} className="mb20"
initValue={question_title} onChange={(val) => this.setState({ question_title: val})}
ref="titleEditor"
></TPMMDEditor>
{question_choices.map( (item, index) => {
@ -254,6 +263,7 @@ class SingleEditor extends Component{
{/* </Tooltip> */}
<div style={{ flex: '0 0 1038px'}}>
<DMDEditor
ref={`optionEditor${index}`}
toMDMode={this.toMDMode} toShowMode={this.toShowMode}
height={166} className={'optionMdEditor'} watch={false} noStorage={true}
mdID={qNumber + index} placeholder="" onChange={(value) => this.onOptionContentChange(value, index)}

@ -73,7 +73,7 @@ class GraduationTaskssettingReply extends Component{
const user = this._getUser();
this.setState({
comments: addNewComment(this.state.comments, _id, content, user),
comments: addNewComment(this.state.comments, _id, content, user, this.props.isSuperAdmin(), this),
total_count: this.state.total_count + 1
})
this.refs.editor.showEditor();

@ -17,7 +17,7 @@ class Graduationtaskitem extends Component{
let { item }=this.props;
const _content = item.content && this.parseCommentContent(item.content)
return(
<div className="comment_item_cont df clearfix" key={item.id}>
<div className="comment_item_cont appraise df clearfix" key={item.id}>
<div className="J_Comment_Face fl">
<a href={`${_origin}/users/${item.user_login}`} target="_blank">
<img alt="用户头像" height="50" src={getImageUrl(`images/${item.image_url}`)} width="50"/>

@ -67,7 +67,7 @@ class GraduateTopicReply extends Component{
const user = this._getUser();
this.setState({
comments: addNewComment(this.state.comments, _id, content, user),
comments: addNewComment(this.state.comments, _id, content, user, this.props.isSuperAdmin(), this),
total_count: this.state.total_count + 1
})
this.refs.editor.showEditor();

@ -117,7 +117,7 @@ class MemoDetailMDEditor extends Component {
this.initMDEditor()
}
render() {
const { match, history, memo, placeholder } = this.props
const { match, history, memo, placeholder, className } = this.props
const { isInited, errorMsg } = this.state
if (!memo) {
return <div></div>
@ -154,7 +154,7 @@ class MemoDetailMDEditor extends Component {
}
`}</style>
<div style={{ display: isInited ? 'none' : '', borderBottom: `${this.props.commentsLength == 0 ? 'none' : '1px solid #EEEEEE'}`}}
className="mockInputWrapper commentInput" >
className={`mockInputWrapper commentInput ${className}`} >
<input onClick={this.onMockInputClick} placeholder={placeholder || '我要回复'}></input>
<a href="javascript:void(0)"
onClick={this.onMockInputClick} className="commentsbtn task-btn task-btn-blue">
@ -172,7 +172,7 @@ class MemoDetailMDEditor extends Component {
`
} */}
</style>
<div nhname={`new_message_${memo.id}`} className="commentInput commentInputs"
<div nhname={`new_message_${memo.id}`} className={`commentInput commentInputs ${className}`}
style={{ padding: '30px',boxSizing:"border-box", display: isInited ? '' : 'none', paddingBottom: '40px' }} >
<div id="memo_comment_editorMd" className="editorMD" style={{ marginBottom: '0px'
, border: errorMsg ? '1px solid red' : '1px solid #ddd'}}>

@ -239,7 +239,9 @@ export default class TPMMDEditor extends Component {
}
__editorName.cm.on("change", (_cm, changeObj) => {
that.contentChanged = true;
if (that.state.showError) {
that.setState({showError: false})
}
that.onEditorChange()
})
that.props.onCMBlur && __editorName.cm.on('blur', () => {
@ -256,6 +258,9 @@ export default class TPMMDEditor extends Component {
}, this);
}
showError = () => {
this.setState({showError: true})
}
onEditorChange = () => {
if (!this.answers_editormd) return;
const val = this.answers_editormd.getValue();
@ -297,14 +302,18 @@ export default class TPMMDEditor extends Component {
render() {
let {
choice_url,
showError
} = this.state;
let { mdID, className, noStorage } = this.props;
let _style = {}
if (showError) {
_style.border = '1px solid red'
}
return (
<React.Fragment>
<div className={`df ${className}`}>
<div className={`df ${className}`} >
{/* padding10-20 */}
<div className="edu-back-greyf5 radius4" id={`mdEditor_${mdID}`}>
<div className="edu-back-greyf5 radius4" id={`mdEditor_${mdID}`} style={{..._style}}>
<textarea style={{display: 'none'}} id="evaluate_script_show" name="content"></textarea>
<div className="CodeMirror cm-s-defualt">
</div>

@ -97,3 +97,51 @@ return;
// var uglified = uglify.minify(['file1.js', 'file2.js', 'file3.js']);
/**
优化
underscore被单独加载了去掉'D:\\Code\\trustieplus\\public\\react\\public\\js\\editormd\\underscore.min.js',
marked
raphaeljs sequence diagrams 1.0.4
统计 js_min_all加载的js
https://github.com/paulmillr/es6-shim
jQuery v1.8.3 jquery.com
Underscore.js 1.8.2
marked v0.3.3
Raphaël 2.1.3 - JavaScript Vector Library
flowchart, v1.3.4
editormd.js
CodeMirror
cm active-line.js
cm mode javascript
cm merge.js
CodeMirror addon hint
cm showHint
cm anyword-hint
CodeMirror python
CodeMirror c-like(java)
CodeMirror matchbrackets
>
// Copyright (C) 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
Loading…
Cancel
Save