Merge remote-tracking branch 'origin/master'

dev_forum
杨树明 6 years ago
commit 166dbb3f03

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -484,7 +484,7 @@ class Comments extends Component {
const goldRewardInputErrorObj = goldRewardInputError ? {'error': 'error'} : {} const goldRewardInputErrorObj = goldRewardInputError ? {'error': 'error'} : {}
return ( return (
<div className="fit -scroll"> <div className="fit -scroll" style={{ 'overflow-x': 'hidden'}}>
{ usingAntdModal ? <Modals { usingAntdModal ? <Modals

@ -0,0 +1,78 @@
import React,{ Component } from "react";
import {Tooltip, Modal, Input } from 'antd'
import moment from 'moment'
import { getUrl, WordsBtn } from 'educoder'
import axios from 'axios'
class AddDirModal extends Component{
constructor(props){
super(props);
this.state = {
}
}
onInput = (e) => {
this.setState({
inputValue: e.target.value
})
}
open = () => {
this.setState({ visible: true, inputValue: '' })
}
onSave = () => {
let coursesId = this.props.match.params.coursesId;
const url = `/courses/${coursesId}/boards.json`
let { inputValue } = this.state;
axios.post(url,{
name: inputValue
}).then((response)=>{
if (response.data.status == 0) {
this.onCancel()
this.props.showNotification('添加成功')
this.props.addSuccess && this.props.addSuccess()
}
}).catch((error)=>{
console.log(error)
})
}
onCancel = () => {
this.setState({ visible: false, inputValue: '' })
}
render(){
let { inputValue, visible } = this.state;
const { title } = this.props;
return(
<Modal
keyboard={false}
title={title}
visible={visible}
className={"Navmodal"}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
>
<div className="df">
<div className={"fl mt5"}>{this.props.label}</div>
<Input placeholder={this.props.inputPlaceholder || '示例讨论小组A'}
className={"input-flex-35 greyInput fl"}
maxLength="60"
value={inputValue}
onInput={this.onInput}
/>
</div>
{/* {this.state.NavmodalValuetype===true?<span className={"color-red"}>
{this.state.NavmodalValues}
</span>:""} */}
{/* this.state.NavmodalValuetype===true?"clearfix mt20 edu-txt-center": */}
<div className={"clearfix mt50 edu-txt-center"}>
<a className="task-btn mr30" onClick={this.onCancel}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.onSave}>确定</a>
</div>
</Modal>
)
}
}
export default AddDirModal;

@ -3,13 +3,13 @@ import React,{ Component } from "react";
import { import {
Form, Input, InputNumber, Switch, Radio, Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message, Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal Row, Col, Select, Modal, Divider
} from 'antd'; } from 'antd';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor'; import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios' import axios from 'axios'
import './board.css' import './board.css'
import "../common/formCommon.css" import "../common/formCommon.css"
import AddDirModal from './AddDirModal'
import { RouteHOC } from './common.js' import { RouteHOC } from './common.js'
import CBreadcrumb from '../common/CBreadcrumb' import CBreadcrumb from '../common/CBreadcrumb'
import {getUploadActionUrl, bytesToSize, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll} from 'educoder'; import {getUploadActionUrl, bytesToSize, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll} from 'educoder';
@ -29,14 +29,14 @@ class BoardsNew extends Component{
boards: [] boards: []
} }
} }
componentDidMount = () => { addSuccess = () => {
this.fetchBoards()
const topicId = this.props.match.params.topicId }
fetchBoards = () => {
const isEdit = this.isEdit
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
const boardsUrl = `/courses/board_list.json?board_id=${boardId}`
const isEdit = !!topicId
const boardsUrl = `/courses/board_list.json?board_id=${boardId}`
axios.get(boardsUrl, { }) axios.get(boardsUrl, { })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
@ -57,8 +57,17 @@ class BoardsNew extends Component{
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
}
componentDidMount = () => {
const topicId = this.props.match.params.topicId
const isEdit = !!topicId
this.isEdit = isEdit this.isEdit = isEdit
const boardId = this.props.match.params.boardId
this.fetchBoards()
if (isEdit) { if (isEdit) {
const url = `/messages/${topicId}.json` const url = `/messages/${topicId}.json`
axios.get(url, { axios.get(url, {
@ -260,6 +269,12 @@ class BoardsNew extends Component{
return( return(
<div className="newMain "> <div className="newMain ">
<AddDirModal {...this.props}
title="添加目录"
label="目录名称"
ref="addDirModal"
addSuccess={this.addSuccess}
></AddDirModal>
<style>{` <style>{`
.courseForm .ant-form { .courseForm .ant-form {
} }
@ -312,7 +327,17 @@ class BoardsNew extends Component{
{getFieldDecorator('select_board_id', { {getFieldDecorator('select_board_id', {
// initialValue: '3779', // initialValue: '3779',
})( })(
<Select style={{ width: 230 }}> <Select style={{ width: 230 }}
dropdownRender={menu => (
<div>
{menu}
<Divider style={{ margin: '4px 0' }} />
<div style={{ padding: '8px', cursor: 'pointer' }} onMouseDown={() => this.refs['addDirModal'].open()}>
<Icon type="plus" /> 添加目录
</div>
</div>
)}
>
{this.state.boards.map(item => { {this.state.boards.map(item => {
return ( return (
<Option value={item.id}>{item.name}</Option> <Option value={item.id}>{item.name}</Option>

@ -71,9 +71,10 @@ function buildColumns(that, student_works) {
width: 90, width: 90,
dataIndex: 'user_name', dataIndex: 'user_name',
key: 'user_name', key: 'user_name',
// width: '110px',
render: (text, record) => ( render: (text, record) => (
<div style={{ <div style={{
width: '110px',
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
whiteSpace: 'nowrap' whiteSpace: 'nowrap'

@ -241,16 +241,18 @@ class CommonReply extends Component{
.course-message .commentInput { .course-message .commentInput {
padding-bottom: 56px !important; padding-bottom: 56px !important;
} }
.course-message .commentInput.mockInputWrapper { .course-message .commentInput.mockInputWrapper {
padding-bottom: 30px !important; padding-bottom: 20px !important;
} }
.course-message .memoReplies { .course-message .memoReplies {
border-top: 1px solid #EDEDED; /* border-top: 1px solid #EDEDED; */
padding-bottom: 30px;
} }
`}</style> `}</style>
<MemoDetailMDEditor ref="editor" memo={memo} usingMockInput={true} placeholder="说点什么" <MemoDetailMDEditor ref="editor" memo={memo} usingMockInput={true} placeholder="说点什么"
height={160} showError={true} height={160} showError={true}
replyComment={this.replyComment} replyComment={this.replyComment}
commentsLength={comments ? comments.length : 0}
></MemoDetailMDEditor> ></MemoDetailMDEditor>
{/* bor-bottom-greyE */} {/* bor-bottom-greyE */}
<div className="padding40 memoReplies commentsDelegateParent" <div className="padding40 memoReplies commentsDelegateParent"

@ -7,6 +7,7 @@ import CoursesListType from '../coursesPublic/CoursesListType';
import Addcourses from '../coursesPublic/Addcourses'; import Addcourses from '../coursesPublic/Addcourses';
import '../css/Courses.css'; import '../css/Courses.css';
import Modals from "../../modals/Modals"; import Modals from "../../modals/Modals";
import Guide from './CoursesGuide';
import AddStudentModal from '../members/modal/AddStudentModal' import AddStudentModal from '../members/modal/AddStudentModal'
import AddTeacherModal from '../members/modal/AddTeacherModal' import AddTeacherModal from '../members/modal/AddTeacherModal'
@ -43,6 +44,7 @@ class CoursesBanner extends Component {
modalsBottomval: "", modalsBottomval: "",
antIcon:false, antIcon:false,
coursedata:undefined, coursedata:undefined,
is_guide:false
} }
} }
componentDidMount() { componentDidMount() {
@ -323,13 +325,15 @@ class CoursesBanner extends Component {
postsettings=()=>{ postsettings=()=>{
window.location.href = "/courses/" + this.props.match.params.coursesId + "/settings"; window.location.href = "/courses/" + this.props.match.params.coursesId + "/settings";
} }
render() { render() {
let { Addcoursestypes, coursedata, modalsType, modalsTopval, loadtype,modalsBottomval,antIcon} = this.state; let { Addcoursestypes, coursedata, modalsType, modalsTopval, loadtype,modalsBottomval,antIcon,is_guide} = this.state;
return ( return (
<div> <div>
{
is_guide && <Guide></Guide>
}
{ {
coursedata === undefined || coursedata.status===401? <div id="course_info_1309" className="courseHead" style={{height: '206px'}}></div>:<div id="course_info_1309" className="courseHead" style={{height: '206px'}}> coursedata === undefined || coursedata.status===401? <div id="course_info_1309" className="courseHead" style={{height: '206px'}}></div>:<div id="course_info_1309" className="courseHead" style={{height: '206px'}}>

@ -0,0 +1,44 @@
import React, {Component} from 'react';
import '../css/Courses.css';
import {setImagesUrl} from 'educoder';
class CoursesGuide extends Component {
constructor(props) {
super(props)
this.state={
step:1
}
}
render(){
let {step} = this.state;
return(
<div className="guidePanel">
<style>{`
body{
overflow:hidden!important;
}
`}</style>
<div className="educontent">
{
step ==1 &&
<div>
<p className="clearfix"><img className="fr" src="/images/course/guide/1-1.png" width="175px" style={{margin:"205px 38px 0px 0px"}}/></p>
<p className="clearfix pr"><img src="/images/course/guide/1-2.png" className="fr mt20 guideFirstRight"/></p>
<p className="clearfix pr" style={{marginTop:"80px"}}>
<img src="/images/course/guide/1-4.png" className="fl guideFirstLeft"/>
<img src="/images/course/guide/1-3.png" className="fl" style={{marginLeft:"410px"}}/>
</p>
<p className="clearfix">
<img src="/images/course/guide/1-5.png" className="fl mt50"/>
<img src="/images/course/guide/1-6.png" className="fl mt40"/>
<a href="javascript:void(0)"><img src="/images/course/guide/1-7.png" className="fl mt80 ml100"/></a>
</p>
</div>
}
</div>
</div>
)
}
}
export default CoursesGuide;

@ -1520,3 +1520,23 @@ input.ant-input-number-input:focus {
border-bottom: 1px solid transparent !important; border-bottom: 1px solid transparent !important;
} }
/* 指引 */
.guidePanel{
position: fixed;
top:0px;
left: 0px;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
z-index: 10000;
}
.guideFirstRight{
position: absolute;
right: -90px;
}
.guideFirstLeft{
position: absolute;
left: -95px;
top:120px;
}

@ -98,7 +98,7 @@ class SingleEditor extends Component{
} }
} }
if(!answerArray || answerArray.length == 0) { if(!answerArray || answerArray.length == 0) {
this.props.showNotification('请先点击本选择题的正确选项'); return; this.props.showNotification('请先点击选择本选择题的正确选项'); return;
} }
if(!question_title) { if(!question_title) {
this.props.showNotification('请先输入题目题干'); return; this.props.showNotification('请先输入题目题干'); return;

@ -224,11 +224,11 @@ class GraduateTaskItem extends Component{
<span className="mr50"> <span className="mr50">
{/* <a href="/users/innov" className="panel-name-small hide fl mr15 mr30 color-grey3">{discussMessage.author.name}</a> */} {/* <a href="/users/innov" className="panel-name-small hide fl mr15 mr30 color-grey3">{discussMessage.author.name}</a> */}
{discussMessage.commit_count===undefined?"":<span className="mr15 color-grey9">{discussMessage.commit_count} 已交</span>} {discussMessage.commit_count===undefined?"":<span className="mr15 color-grey9 font-14">{discussMessage.commit_count} 已交</span>}
{discussMessage.uncommit_count===undefined?"":<span className="mr15 color-grey9">{discussMessage.uncommit_count} 未交</span>} {discussMessage.uncommit_count===undefined?"":<span className="mr15 color-grey9 font-14">{discussMessage.uncommit_count} 未交</span>}
{/*<span className="mr15 color-grey9">{discussMessage.replies_count} 3 未评</span>*/} {/*<span className="mr15 color-grey9">{discussMessage.replies_count} 3 未评</span>*/}
<Tooltip title={discussMessage.task_status===1?"提交剩余时间":discussMessage.task_status===2?"补交剩余时间":""} placement="bottom"> <Tooltip title={discussMessage.task_status===1?"提交剩余时间":discussMessage.task_status===2?"补交剩余时间":""} placement="bottom">
<span className="mr15 color-grey9">{discussMessage.status_time}</span> <span className="mr15 color-grey9 font-14">{discussMessage.status_time}</span>
</Tooltip> </Tooltip>
{/* { discussMessage.replies_count != 0 && <span className="mr15 color-grey9">{discussMessage.replies_count} </span> } {/* { discussMessage.replies_count != 0 && <span className="mr15 color-grey9">{discussMessage.replies_count} </span> }

@ -33,6 +33,7 @@ function buildColumns(that) {
const { course_groups } = that.state const { course_groups } = that.state
const columns = [{ const columns = [{
title: '序号', title: '序号',
width: 28,
// dataIndex: 'name', // dataIndex: 'name',
key: 'index', key: 'index',
render: (content, item, index) => { render: (content, item, index) => {
@ -40,12 +41,13 @@ function buildColumns(that) {
} }
},{ },{
title: '用户ID', title: '用户ID',
width: 82,
dataIndex: 'login', dataIndex: 'login',
key: 'login' key: 'login'
}, { }, {
title: '姓名', title: '姓名',
dataIndex: 'name', dataIndex: 'name',
width: 160, width: 140,
key: 'name', key: 'name',
render: (name, record) => { render: (name, record) => {
return <a href={`/login/${record.login}`} target="_blank">{name}</a> return <a href={`/login/${record.login}`} target="_blank">{name}</a>
@ -57,7 +59,7 @@ function buildColumns(that) {
}] }]
that.state.course_groups && that.state.course_groups.length && columns.push({ that.state.course_groups && that.state.course_groups.length && columns.push({
title: <Tooltip title="仅能批阅指定分班的作品">管理权限</Tooltip>, title: <Tooltip title="仅能批阅指定分班的作品">管理权限</Tooltip>,
width: 230, // width: 230,
key: 'course_groups', key: 'course_groups',
dataIndex: 'course_groups', dataIndex: 'course_groups',
// onClick={() => that.joinCourseGroup(item.id)} // onClick={() => that.joinCourseGroup(item.id)}
@ -113,6 +115,7 @@ function buildColumns(that) {
if (hasGraduationModule) { if (hasGraduationModule) {
columns.push({ columns.push({
title: '答辩组', title: '答辩组',
width: 74,
key: 'graduation_group', key: 'graduation_group',
dataIndex: 'graduation_group', dataIndex: 'graduation_group',
render: text => ( render: text => (
@ -126,6 +129,7 @@ function buildColumns(that) {
columns.push({ columns.push({
title: '操作', title: '操作',
key: 'action', key: 'action',
width: 150,
align:'center', align:'center',
render: (text, record) => { render: (text, record) => {
if (record.application_id) { if (record.application_id) {

@ -148,13 +148,13 @@ class MemoDetailMDEditor extends Component {
margin-right: 0px !important; margin-right: 0px !important;
} }
.commentInput { .commentInput {
border-bottom: 1px solid #EEEEEE;
} }
.commentInput .editormd{ .commentInput .editormd{
width:100%!important; width:100%!important;
} }
`}</style> `}</style>
<div style={{ display: isInited ? 'none' : ''}} className="mockInputWrapper commentInput" > <div style={{ display: isInited ? 'none' : '', borderBottom: `${this.props.commentsLength == 0 ? 'none' : '1px solid #EEEEEE'}`}}
className="mockInputWrapper commentInput" >
<input onClick={this.onMockInputClick} placeholder={placeholder || '我要回复'}></input> <input onClick={this.onMockInputClick} placeholder={placeholder || '我要回复'}></input>
<a href="javascript:void(0)" <a href="javascript:void(0)"
onClick={this.onMockInputClick} className="commentsbtn task-btn task-btn-blue"> onClick={this.onMockInputClick} className="commentsbtn task-btn task-btn-blue">

@ -7,6 +7,7 @@ import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
// import "antd/dist/antd.css"; // import "antd/dist/antd.css";
import { getImageUrl, toPath, getUrl } from 'educoder'; import { getImageUrl, toPath, getUrl } from 'educoder';
import '../../courses/css/Courses.css'
import axios from 'axios'; import axios from 'axios';

Loading…
Cancel
Save