Merge branch 'dev_aliyun' into dev_cs

topic_bank
caicai8 5 years ago
commit 49923ac3a2

@ -74,7 +74,7 @@ class ExerciseBanksController < ApplicationController
#判断实训是否已选择
def commit_shixun_present
question_shixun_ids = @exercise.exercise_bank_questions.pluck(:shixun_id).reject(&:blank?)
question_shixun_ids = @bank.exercise_bank_questions.pluck(:shixun_id).reject(&:blank?)
shixun_id = params[:shixun_id]
@shixun = Shixun.find_by(id: shixun_id)
if shixun_id.present? && question_shixun_ids.include?(shixun_id)
@ -85,45 +85,47 @@ class ExerciseBanksController < ApplicationController
end
def get_exercise_question_count
@exercise_ques_count = @exercise_questions.size # 全部的题目数
@exercise_ques_scores = @exercise_questions.pluck(:question_score).sum
exercise_questions = @bank.exercise_bank_questions
@exercise_ques_count = exercise_questions.size # 全部的题目数
@exercise_ques_scores = exercise_questions.pluck(:question_score).sum
#单选题的数量及分数
exercise_single_ques = @exercise_questions.find_by_custom("question_type", Exercise::SINGLE)
exercise_single_ques = exercise_questions.find_by_custom("question_type", Exercise::SINGLE)
@exercise_single_ques_count = exercise_single_ques.size
@exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum
#多选题的数量及分数
exercise_double_ques = @exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE)
exercise_double_ques = exercise_questions.find_by_custom("question_type", Exercise::MULTIPLE)
@exercise_double_ques_count = exercise_double_ques.size
@exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum
# 判断题数量及分数
exercise_ques_judge = @exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT)
exercise_ques_judge = exercise_questions.find_by_custom("question_type", Exercise::JUDGMENT)
@exercise_ques_judge_count = exercise_ques_judge.size
@exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum
#填空题数量及分数
exercise_ques_null = @exercise_questions.find_by_custom("question_type", Exercise::COMPLETION)
exercise_ques_null = exercise_questions.find_by_custom("question_type", Exercise::COMPLETION)
@exercise_ques_null_count = exercise_ques_null.size
@exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum
#简答题数量及分数
exercise_ques_main = @exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE)
exercise_ques_main = exercise_questions.find_by_custom("question_type", Exercise::SUBJECTIVE)
@exercise_ques_main_count = exercise_ques_main.size
@exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum
#实训题数量及分数
exercise_ques_shixun = @exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL)
exercise_ques_shixun = exercise_questions.find_by_custom("question_type", Exercise::PRACTICAL)
@exercise_ques_shixun_count = exercise_ques_shixun.size
@exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum
end
def get_poll_question_count
@poll_questions_count = @exercise_questions&.size # 全部的题目数
@poll_question_singles = @exercise_questions.find_by_custom("question_type", 1).size # 单选题
@poll_question_doubles = @exercise_questions.find_by_custom("question_type", 2).size # 多选题
@poll_question_mains = @exercise_questions.find_by_custom("question_type", 3).size #主观题
exercise_questions = @bank.exercise_bank_questions
@poll_questions_count = exercise_questions&.size # 全部的题目数
@poll_question_singles = exercise_questions.find_by_custom("question_type", 1).size # 单选题
@poll_question_doubles = exercise_questions.find_by_custom("question_type", 2).size # 多选题
@poll_question_mains = exercise_questions.find_by_custom("question_type", 3).size #主观题
end
end

@ -59,7 +59,7 @@ class GamesController < ApplicationController
record_onsume_time: record_onsume_time, prev_game: prev_game, next_game: next_game,
praise_count: praise_count, user_praise: user_praise, time_limit: time_limit,
tomcat_url: edu_setting('cloud_tomcat_php'), is_teacher: is_teacher,
myshixun_manager: myshixun_manager}
myshixun_manager: myshixun_manager, git_url: (@shixun.vnc ? repo_url(@myshixun.repo_path) : "")}
if @shixun.vnc
begin
shixun_tomcat = edu_setting('cloud_bridge')

@ -57,8 +57,8 @@ class HomeworkBanksController < ApplicationController
tip_exception("description参数不能为空") if params[:homework_bank][:description].blank?
if @bank.homework_type == 3
tip_exception("base_on_project参数不能为空") if params[:homework_bank][:base_on_project].nil?
tip_exception("min_num参数不能为空") if params[:homework_bank][:min_num].blank?
tip_exception("max_num参数不能为空") if params[:homework_bank][:max_num].blank?
tip_exception("最小人数不能为空") if params[:homework_bank][:min_num].blank?
tip_exception("最大人数参数不能为空") if params[:homework_bank][:max_num].blank?
tip_exception("最小人数不能小于1") if params[:homework_bank][:min_num].to_i < 1
tip_exception("最大人数不能小于最小人数") if params[:homework_bank][:max_num].to_i < params[:homework_bank][:min_num].to_i
end

@ -475,7 +475,7 @@ class StudentWorksController < ApplicationController
# 实训作品的评阅
def shixun_work_comment
tip_exception("评阅不能为空") if params[:comment].blank?
tip_exception("缺少is_hidden参数") if params[:is_hidden].blank? || ![true, false].include?(params[:is_hidden])
tip_exception("缺少is_hidden参数") if params[:is_hidden].blank? || ![1, 0].include?(params[:is_hidden])
comment = @work.student_works_scores.shixun_comment.first || StudentWorksScore.new(student_work_id: @work.id, user_id: current_user.id)
comment.comment = params[:comment]
comment.is_hidden = params[:is_hidden]

@ -85,7 +85,7 @@ class Users::QuestionBankService
def custom_sort(relations, sort_by, sort_direction)
case sort_by
when 'updated_at' then
relations.order("updated_at #{sort_direction}, id desc")
relations.order("updated_at #{sort_direction}, id #{sort_direction}")
when 'name' then
relations.order("CONVERT(name USING gbk) COLLATE gbk_chinese_ci #{sort_direction}")
when 'contributor' then

@ -1,6 +1,6 @@
json.(@base_date, :st, :discusses_count, :game_count, :record_onsume_time, :prev_game, :next_game, :praise_count,
:user_praise, :time_limit, :tomcat_url, :is_teacher, :myshixun_manager, :game, :challenge,
:shixun, :myshixun)
:shixun, :myshixun, :git_url)
if @shixun.vnc
json.vnc_url @vnc_url
end

@ -54,7 +54,7 @@ if @shixun
json.passed_time @work.myshixun&.passed_time
# 评阅信息
json.work_comment @user_course_identity < Course::STUDENT ? @comment&.comment : nil
json.work_comment @user_course_identity < Course::STUDENT || !@comment&.is_hidden ? @comment&.comment : nil
json.work_comment_hidden @comment&.is_hidden
# 图形统计

@ -1,6 +1,9 @@
json.count @count
json.course_list @course_lists, partial: 'users/question_banks/shared/course_list', as: :course_list
json.course_list @course_lists do |course_list|
json.id course_list.id
json.name course_list.name
end
json.question_banks @question_banks do |question_bank|
json.id question_bank.id

@ -32,7 +32,7 @@ module.exports = {
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map",
// 开启调试
// devtool: "source-map", // 开启调试
//devtool: "source-map", // 开启调试
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
// The first two entry points enable "hot" CSS and auto-refreshes for JS.

@ -0,0 +1,146 @@
import React,{ Component } from "react";
import { Modal,Checkbox,Upload,Button,Icon,message,Input,Radio} from "antd";
import { WordNumberTextarea } from 'educoder';
import axios from 'axios';
class AppraiseModal extends Component{
constructor(props){
super(props);
this.state={
group_ids:[],
fileList:[],
textareaval:undefined,
Inputsval:undefined,
valuetype:0,
textareavaltype:false
}
}
componentDidMount() {
this.setState({
valuetype:this.props.work_type===undefined?0:this.props.work_type,
textareaval:this.props.work_comment,
})
}
onChanges=(e)=>{
this.setState({
valuetype:e.target.value
})
}
settextarea=(e)=>{
this.setState({
textareaval:e.target.value
})
}
Saves=()=>{
let{textareaval,valuetype}=this.state;
if(textareaval===undefined||textareaval===null||textareaval===""){
this.setState({
textareavaltype:true
})
return
}
let url=`/student_works/${this.props.match.params.homeworkid}/shixun_work_comment.json`
axios.post(url, {
comment:textareaval,
is_hidden:valuetype
}).then((response) => {
if(response.data.status===0){
this.props.showNotification(response.data.message)
this.props.showCancel(textareaval,valuetype)
}else{
this.props.showNotification(response.data.message)
}
}).catch((error) => {
console.log(error)
});
}
render(){
let {textareaval,Inputsval,textareavaltype,Inputsvaltype}=this.state;
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
return(
<div>
<Modal
keyboard={false}
className={"HomeworkModal"}
title={this.props.work_comment===null||this.props.work_comment===undefined?"评阅":"编辑评阅"}
visible={this.props.visible}
closable={false}
footer={null}
destroyOnClose={true}
>
<div className={"pd015"}>
<style>
{
`
.pd015{
padding: 0px 15px 15px 15px;
}
.font{
width: 48px;
height: 16px;
font-size: 16px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(5,16,26,1);
line-height: 16px;
}
.newfont{
height: 16px;
font-size: 16px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(5,16,26,1);
line-height: 16px;
margin-bottom: 5px;
}
`
}
</style>
<div className="clearfix">
<p className={"font mt10 mb10"}>
权限
</p>
<Radio.Group onChange={this.onChanges} value={this.state.valuetype}>
<Radio value={0} style={radioStyle} className={"newfont"}>可见 (学生查看老师的评阅内容</Radio>
<Radio value={1} style={radioStyle} className={"newfont"}>不可见 (仅对课堂老师可见</Radio>
</Radio.Group>
<p className={"font mt10 mb20"}>
内容
</p>
<WordNumberTextarea
placeholder={"请填写评阅内容"}
onInput={(e)=>this.settextarea(e)}
value={textareaval}
maxlength={500}
/>
<li style={{height:"20px",lineHeight:"20px"}} className={textareavaltype===true?"color-red mt20 mb10":"none"}><span>评阅内容不能为空</span></li>
</div>
<div className={textareavaltype===false?"mt20 clearfix edu-txt-center":"clearfix edu-txt-center"}>
<a className="task-btn color-white mr30" onClick={()=>this.props.Cancel()}>{this.props.Cancelname || '取消'}</a>
<a className="task-btn task-btn-orange" onClick={this.Saves}>{this.props.Savesname || '确定'}</a>
</div>
</div>
</Modal>
</div>
)
}
}
export default AppraiseModal;

@ -848,7 +848,7 @@ a.white-btn.use_scope-btn:hover{
font-family: MicrosoftYaHei;
font-weight: 400;
color: rgba(51,51,51,1);
cursor: pointer;
/*cursor: pointer;*/
max-width: 825px;
overflow: hidden;
text-overflow: ellipsis;

@ -355,12 +355,12 @@ class studentsList extends Component{
searchValue: e.target.value
})
if (this.timeoutHandler) {
clearTimeout(this.timeoutHandler)
}
this.timeoutHandler = setTimeout(() => {
this.fetchAll(1)
}, 1200)
// if (this.timeoutHandler) {
// clearTimeout(this.timeoutHandler)
// }
// this.timeoutHandler = setTimeout(() => {
// this.fetchAll(1)
// }, 1200)
}
onSortTypeChange = (order) => {
this.setState({ order: order }, () => {

@ -19,7 +19,7 @@ const CheckboxGroup = Checkbox.Group
const Option = Select.Option;
const maps = {1: "未发布", 2: "提交中", 3: "已截止"}
const confirm = Modal.confirm;
const $ = window.$;
class PollNew extends Component {
// 问卷新建和编辑
//

@ -1077,13 +1077,13 @@ class Listofworksstudentone extends Component {
// debugger
let urll = `/homework_commons/${homeworkid}/works_list.json`;
var datasysl = {
search: "",
order: "",
search: this.state.searchtext,
order: this.state.orders,
b_order: "desc",
page: 1,
limit: 20,
work_status: "",
course_group: "",
page: this.state.page,
limit: this.state.limit,
work_status: this.state.course_groupyslstwo,
course_group: this.state.checkedValuesineinfo,
}
axios.post(urll, datasysl).then((result) => {
console.log("980000000____________________");
@ -1449,7 +1449,9 @@ class Listofworksstudentone extends Component {
this.setState({
userids: e.myid,
})
this.viewtraining(e.myid);
window.open(`/courses/${this.state.props.match.params.coursesId}/shixun_homeworks/${e.myid}/shixun_work_report`, '_blank');
// this.viewtraining(e.myid);
}
viewtraining = (userids) => {
// console.log("viewtraining")
@ -2104,7 +2106,8 @@ class Listofworksstudentone extends Component {
this.setState({
userids: e.myid,
})
this.viewtrainingt(e.myid);
// this.viewtrainingt(e.myid);
window.open(`/courses/${this.state.props.match.params.coursesId}/shixun_homeworks/${e.myid}/shixun_work_report`, '_blank');
}
// 关闭调分
cancelModulationModels = () => {
@ -2600,29 +2603,31 @@ class Listofworksstudentone extends Component {
color:rgba(255,104,0,1);
}
.computeTime{
width: 73px;
height: 24px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 13px;
color: #4CACFF;
border: 1px solid #4CACFF;
cursor: pointer;
}
.computeTime {
width: 122px;
height: 31px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 20px;
color: #FE6B21;
border: 1px solid #FE6B21;
cursor: pointer;
border-radius: 4px;
}
.computeTimes{
width: 73px;
height: 24px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 13px;
color: #C5C5C5;
border: 1px solid #EDEDED;
background:#EDEDED;
cursor: pointer;
.computeTimes{
width: 122px;
height: 31px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 20px;
color: #C5C5C5;
border: 1px solid #EDEDED;
background:#EDEDED;
cursor: pointer;
border-radius: 4px;
}
.shixunSpin{
color:#FF6801;
@ -2641,19 +2646,21 @@ class Listofworksstudentone extends Component {
<ul className="clearfix" style={{padding: '20px 15px 10px 20px'}}>
<li className="clearfix ">
<span className="fl mr10 color-grey-6 ">计算成绩时间{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}</span>
{course_is_end===true?"":<span>
{teacherdata&&teacherdata.publish_immediately===false&&computeTimetype===true?
(this.props.isNotMember()===false?<div className={"computeTime font-13"} onClick={this.setComputeTimet}>
计算成绩
</div>:""):
teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":
(this.props.isNotMember()===false?<div className={"computeTimes font-13"}>
计算成绩
</div>:"")
}
</span>}
<div className="fr mr5 search-newysl" style={{marginBottom: '1px'}}>
{course_is_end===true?"":<span>
{teacherdata&&teacherdata.publish_immediately===false&&computeTimetype===true?
(this.props.isNotMember()===false?<div className={"computeTime font-16"} onClick={this.setComputeTimet}>
查看最新成绩
</div>:""):
teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":
(this.props.isNotMember()===false?<div className={"computeTimes font-16"}>
查看最新成绩
</div>:"")
}
</span>}
<span className="search-newyslw fr ml20">
<Search
placeholder="请输入姓名或学号搜索"
id="subject_search_input"
@ -2663,6 +2670,7 @@ class Listofworksstudentone extends Component {
onInput={this.inputSearchValuest}
onSearch={this.searchValuest}
></Search>
</span>
</div>
</li>
@ -2842,30 +2850,32 @@ class Listofworksstudentone extends Component {
font-weight:400;
color:rgba(255,104,0,1);
}
.computeTime{
width: 73px;
height: 24px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 13px;
color: #4CACFF;
border: 1px solid #4CACFF;
cursor: pointer;
}
.computeTime {
width: 122px;
height: 31px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 20px;
color: #FE6B21;
border: 1px solid #FE6B21;
cursor: pointer;
border-radius: 4px;
}
.computeTimes{
width: 73px;
height: 24px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 13px;
color: #C5C5C5;
border: 1px solid #EDEDED;
background:#EDEDED;
cursor: pointer;
}
.computeTimes{
width: 122px;
height: 31px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 20px;
color: #C5C5C5;
border: 1px solid #EDEDED;
background:#EDEDED;
cursor: pointer;
border-radius: 4px;
}
`}
</style>
{visibles === true ?
@ -2949,15 +2959,15 @@ class Listofworksstudentone extends Component {
{ course_is_end===true?"":teacherdata&&teacherdata.task_operation[0]==="开启挑战"?"":<span>
{computeTimetype===true?
(this.props.isNotMember()===false?
<div className={"computeTime font-13"} onClick={this.setComputeTime}>
计算成绩
<div className={"computeTime font-16"} onClick={this.setComputeTime}>
查看最新成绩
</div>
:"")
:
(teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":
this.props.isNotMember()===false?
<div className={"computeTimes font-13"}>
计算成绩
<div className={"computeTimes font-16"}>
查看最新成绩
</div>
:"")
}
@ -3127,29 +3137,31 @@ class Listofworksstudentone extends Component {
font-weight:400;
color:rgba(255,104,0,1);
}
.computeTime{
width: 73px;
height: 24px;
.computeTime {
width: 122px;
height: 31px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 13px;
color: #4CACFF;
border: 1px solid #4CACFF;
line-height: 20px;
color: #FE6B21;
border: 1px solid #FE6B21;
cursor: pointer;
}
border-radius: 4px;
}
.computeTimes{
width: 73px;
height: 24px;
width: 122px;
height: 31px;
display: inline-block;
padding: 5px;
text-align: center;
line-height: 13px;
line-height: 20px;
color: #C5C5C5;
border: 1px solid #EDEDED;
background:#EDEDED;
cursor: pointer;
border-radius: 4px;
}
`}
</style>
@ -3158,15 +3170,26 @@ class Listofworksstudentone extends Component {
<span className="fl mr10 color-grey-6 ">计算成绩时间{teacherdata&&teacherdata.calculation_time==null?"--": moment(teacherdata&&teacherdata.calculation_time).format('YYYY-MM-DD HH:mm')}</span>
{ course_is_end===true?"":teacherdata&&teacherdata.task_operation&&teacherdata.task_operation[0]==="开启挑战"?"":<span>
{computeTimetype===true?
(this.props.isNotMember()===false?<div className={"computeTime font-13"} onClick={this.setComputeTime}>
计算成绩
(this.props.isNotMember()===false?<div className={"computeTime font-16"} onClick={this.setComputeTime}>
查看最新成绩
</div>:""):
teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":
(this.props.isNotMember()===false?<div className={"computeTimes font-13"}>
计算成绩
(this.props.isNotMember()===false?<div className={"computeTimes font-16"}>
查看最新成绩
</div>:"")
}
</span>}
{/* {teacherdata&&teacherdata.task_operation&&teacherdata.task_operation[0]==="开启挑战"?"":<span>*/}
{/*{computeTimetype===true?*/}
{/* (this.props.isNotMember()===false?<div className={"computeTime font-16"} onClick={this.setComputeTime}>*/}
{/* 查看最新成绩*/}
{/* </div>:""):*/}
{/* teacherdata&&teacherdata.homework_status!==undefined&&teacherdata.homework_status[0]=== "未发布"? "":*/}
{/* (this.props.isNotMember()===false?<div className="computeTimes font-16">*/}
{/* 查看最新成绩*/}
{/* </div>:"")*/}
{/*}*/}
{/*</span>}*/}
</div>
{/*因为计算按钮占了和这个位置,和设计沟通学生视角取消这个按钮*/}

@ -1,14 +1,16 @@
import React, {Component} from "react";
import {WordsBtn,markdownToHTML,ActionBtn,queryString,downloadFile} from 'educoder';
import {WordsBtn,markdownToHTML,ActionBtn,queryString,downloadFile,getImageUrl} from 'educoder';
import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal, Table, Divider,InputNumber, Tag,DatePicker,Radio,Tooltip,Spin} from "antd";
import {Link,Switch,Route,Redirect} from 'react-router-dom';
import axios from 'axios';
import moment from 'moment';
import Modals from "../../modals/Modals";
import ConclusionEvaluation from './shixunreport/ConclusionEvaluation';
import OfficialAcademicTranscript from './shixunreport/OfficialAcademicTranscript';
import Coursesshixundetails from './shixunreport/Coursesshixundetails';
import Shixunechart from './shixunreport/Shixunechart';
import DownloadMessageysl from "../../modals/DownloadMessageysl";
import DownloadMessageysl from "../../modals/DownloadMessageysl"
import AppraiseModal from "../coursesPublic/AppraiseModal";
import {UnControlled as CodeMirror} from 'react-codemirror2';
import 'codemirror/mode/cmake/cmake';
import 'codemirror/mode/xml/xml';
@ -20,6 +22,7 @@ import '../css/Courses.css';
import './style.css';
import 'moment/locale/zh-cn';
class ShixunWorkReport extends Component {
constructor(props) {
@ -29,7 +32,11 @@ class ShixunWorkReport extends Component {
spinning:true,
DownloadType:false,
DownloadMessageval:undefined,
isspinning:false
isspinning:false,
showAppraiseModaltype:false,
work_comment_hidden:false,
showAppraiseModalsshow:true,
work_comment:null
}
}
@ -41,8 +48,7 @@ class ShixunWorkReport extends Component {
if(child!=undefined){
params =child._getRequestParams()!==undefined?child._getRequestParams():{};
}
console.log("170");
console.log(params);
const urll=url+`?${queryString.stringify(params)}`;
axios.get(urll+ '&export=true').then((response) => {
if(response===undefined){
@ -72,6 +78,7 @@ class ShixunWorkReport extends Component {
}
}).catch((error) => {
console.log(error)
this.setState({ isspinning: false })
});
}
Downloadcal=()=>{
@ -100,6 +107,8 @@ class ShixunWorkReport extends Component {
}else{
this.setState({
data:result.data,
work_comment_hidden:result.data.work_comment_hidden,
work_comment:result.data.work_comment,
spinning:false
})
}
@ -145,17 +154,113 @@ class ShixunWorkReport extends Component {
data:newdata
})
}
showAppraiseModal=(sum)=>{
// if(sum===undefined){
// this.setState({
// showAppraiseModaltype:true,
// })
// }else{
// this.setState({
// showAppraiseModaltype:true,
// work_comment:undefined,
// work_type:0,
// })
//
// }
this.setState({
showAppraiseModaltype:true,
})
}
hideAppraiseModal=()=>{
let{data,work_comment}=this.state;
this.setState({
showAppraiseModaltype:false,
work_comment_hidden:data&&data.work_comment_hidden===true?true:work_comment!=null?true:false,
})
}
showAppraiseModals=(list,type)=>{
let{data,work_comment}=this.state;
this.setState({
showAppraiseModaltype:false,
work_comment_hidden:data&&data.work_comment_hidden===true?true:work_comment!=null?true:false,
work_comment:list,
work_type:type,
showAppraiseModals:true,
showAppraiseModalsshow:true
})
}
isdeleteModal=()=>{
this.setState({
modalsType: true,
modalsTopval:"是否确认删除?",
modalSave: ()=>this.isdeleteModals(),
modalCancel:()=>this.hideisdeleteModal(),
})
}
hideisdeleteModal=()=>{
this.setState({
modalsType: false,
modalsTopval:"是否确认删除?",
modalSave: ()=>this.isdeleteModals(),
modalCancel:()=>this.hideisdeleteModal(),
})
}
isdeleteModals=()=>{
let url =`/student_works/${this.props.match.params.homeworkid}/destroy_work_comment.json`
axios.delete(url).then((response) => {
// const { status } = response.data;
if(response.data.status===0){
this.props.showNotification(response.data.message)
this.setState({
showAppraiseModalsshow:false,
work_comment_hidden:false,
work_comment:undefined,
work_type:0,
})
this.hideisdeleteModal()
}else{
this.props.showNotification(response.data.message)
}
})
.catch(function (error) {
console.log(error);
});
}
render() {
let{data} =this.state;
console.log(data)
console.log(this.props)
let{data,showAppraiseModaltype,work_comment_hidden,showAppraiseModalsshow,work_comment} =this.state;
let category_id=data===undefined?"":data.category===null?"":data.category.category_id;
let homework_common_id=data===undefined?"":data.homework_common_id;
let homeworkid=this.props.match.params.homeworkid;
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
// let showAppraiseModals=this.props&&this.props.isAdminOrTeacher()===true?work_comment===null||work_comment===undefined?false:true:work_comment===null||work_comment===undefined?false:true;
let showAppraiseModals=work_comment===null||work_comment===undefined?false:true;
console.log(showAppraiseModals)
return (
data===undefined?"":<Spin indicator={antIcon} spinning={this.state.spinning}><div className="newMain clearfix ">
data===undefined?"":<Spin indicator={antIcon} spinning={this.state.spinning}>
<Modals
modalsType={this.state.modalsType}
modalsTopval={this.state.modalsTopval}
loadtype={this.state.loadtype}
modalSave={this.state.modalSave}
modalCancel={this.state.modalCancel}
></Modals>
{showAppraiseModaltype===true?<AppraiseModal
{...this.props}
{...this.state}
visible={showAppraiseModaltype}
Cancel={()=>this.hideAppraiseModal()}
showCancel={(list,type)=>this.showAppraiseModals(list,type)}
work_comment={this.state.work_comment}
work_type={this.state.work_type}
/>:""}
<div className="newMain clearfix ">
<div className={"educontent mb20" }>
<div className="educontent">
<DownloadMessageysl
@ -181,18 +286,122 @@ class ShixunWorkReport extends Component {
<div style={{ width:'100%',height:'75px'}} >
<p className=" fl color-black mt25 summaryname">{data&&data.shixun_name}</p>
{/*{this.props.isAdmin()?<a className=" fr font-14 ml30 mt10 mr20 color-grey-9 ">导出实训报告数据</a>:""}*/}
<a onClick={this.goback} className="color-grey-6 fr font-16 ml30 mt15 mr20">返回</a>
<a onClick={this.goback} className="color-grey-6 fr font-14 ml20 mt15">返回</a>
{this.props.isAdmin() ? <a
className=" color-blue font-16 fr ml30 mt15"
className=" color-blue font-14 fr ml20 mt15"
onClick={()=>this.confirmysl(`/student_works/${homeworkid}/export_shixun_work_report.pdf`)}
> <Spin size="small" spinning={this.state.isspinning}>导出实训报告数据</Spin></a> : ""}
{/*{this.props.isAdmin() ?work_comment_hidden===true? "":<a*/}
{/*className=" color-blue font-14 fr ml20 mt15"*/}
{/*onClick={()=>this.showAppraiseModal(1)}*/}
{/*>评阅</a> : ""}*/}
{this.props.isAdmin() ?<a
className=" color-blue font-14 fr ml20 mt15"
onClick={()=>this.showAppraiseModal(1)}
>评阅</a>:""}
</div>
{/*{work_comment===null||work_comment===undefined?"评阅":"编辑评阅"}*/}
<style>{
`
.shixunreporttitleboxtop {
border-bottom: 2px solid #fafafa;
text-align: justify;
height: 62px;
line-height: 24px;
padding-left: 28px;
}
.shixunreporttitleboxbom {
text-align: justify;
line-height: 24px;
}
.ml39{
margin-left: 39px;
}
.back_font{
height: 18px;
font-size: 18px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(51,51,51,1);
line-height: 18px;
margin-bottom: 19px;
}
.passfont{
// display: inline-block;
margin-right: 72px;
}
.passfontmid{
// display: inline-block;
margin-right: 36px;
}
.passfontbom{
// display: inline-block;
margin-right: 58px;
}
.passfontbommid{
// display: inline-block;
margin-right: 93px;
}
.color999{
color: #999999;
}
.colorCF3B3B{
color:#CF3B3B;
}
.color333{
color:#333333;
}
.mt19{
margin-top:19px;
}
.passbox{
display: inline-block;
height: 50px;
}
`
}</style>
<div className="stud-class-set">
<div className="clearfix edu-back-white poll_list">
<div className="font-16 color-dark-21 shixunreporttitle ml20 pd20">总体评价</div>
<div className="font-16 color-dark-21 shixunreporttitleboxtop pd20">总体评价</div>
<div className="font-16 color-dark-21 shixunreporttitleboxbom pd20">
<div style={{clear:"both",height:'100px'}}>
<div className="fl edu-back-white ml10 ">
<img alt="头像" className="radius" height="91" id="nh_user_logo" name="avatar_image"
src={ getImageUrl(`images/${data&&data.image_url}`)}
width="91"/>
</div>
<div className={"fl edu-back-white ml39 "}>
<p className={"back_font"}>{data&&data.username}</p>
<p className={"mb16"}>
<span className={"passbox"}>
<div className={"passfont"}><span className={"color999"}>通过关卡</span> <span className={"colorCF3B3B"}>{data&&data.complete_count}/{data&&data.challenges_count}</span></div>
<div className={"passfontbom"}><span className={"color999"}>经验值</span> <span className={"color333"}>{data&&data.myself_experience}/{data&&data.total_experience}</span></div>
</span>
<span className={"passbox"}>
<div className={"passfontmid"}><span className={"color999"}>课堂最高完成效率</span> <span className={data&&data.max_efficiency===null?"color999":"color333"}>{data&&data.max_efficiency===null?'--':data&&data.max_efficiency}</span></div>
<div className={"passfontbommid"}><span className={"color999"}>完成效率</span> <span className={data&&data.efficiency===null?"color999":"color333"}>{data&&data.efficiency===null?'--':data&&data.efficiency}</span></div>
</span>
<span className={"passbox"}>
<div><span className={"color999"}>通关时间</span> <span className={data&&data.passed_time===null?"color999":"color333"}>{data&&data.passed_time===null||data&&data.passed_time=== "--"?'--':moment(data&&data.passed_time).format('YYYY-MM-DD HH:mm')}</span></div>
<div><span className={"color999"}>实战耗时</span> <span className={data&&data.efficiency===null?"color999":"color333"}>{data&&data.time_consuming===null?'--':data&&data.time_consuming}</span></div>
</span>
</p>
</div>
</div>
</div>
<ConclusionEvaluation
data={data}
/>
@ -200,7 +409,7 @@ class ShixunWorkReport extends Component {
</div>
</div>
<div className="stud-class-set">
<div className="stud-class-set mt19">
<div className="clearfix edu-back-white poll_list">
<div className="font-16 color-dark-21 shixunreporttitle ml20 pd20">阶段成绩</div>
@ -216,15 +425,10 @@ class ShixunWorkReport extends Component {
</div>
</div>
<div className="stud-class-set bor-bottom-greyE"
style={{display:data&&data.work_description===null?"none":""}}
>
<div className="clearfix edu-back-white poll_list">
<div className="font-16 color-dark-21 shixunreporttitle ml20 pd20">个人总结</div>
<style>
{`
<style>
{`
.personalsummary{
border:1px solid rgba(235,235,235,1);
border-radius:2px;
}
.pad040{
@ -241,19 +445,62 @@ class ShixunWorkReport extends Component {
color: #999999!important;
font-size: 16px;
}
.pd30{
padding: 30px;
}
`}
</style>
<div className={"pad040"}>
<div className={"personalsummary"}>
</style>
<div className={"markdown-body"}
dangerouslySetInnerHTML={{__html: markdownToHTML(data&&data.work_description).replace(/▁/g, "▁▁▁")}}></div>
<div className="stud-class-set mt17"
style={{display:data&&data.work_description===null?"none":""}}
>
<div className="clearfix edu-back-white poll_list">
<div className="font-16 color-dark-21 shixunreporttitleboxtop pd20 color333">
个人总结
</div>
<div className="font-16 color-dark-21 shixunreporttitleboxbom pd30">
<div style={{minHeight:'50px'}}>
<div className={"personalsummary"}>
<div className={"markdown-body"}
dangerouslySetInnerHTML={{__html: markdownToHTML(data===undefined?"":data.work_description).replace(/▁/g, "▁▁▁")}}
></div>
</div>
</div>
</div>
</div>
</div>
<div className="stud-class-set bor-bottom-greyE">
{showAppraiseModals===true&&showAppraiseModalsshow===true?<div className="stud-class-set mt17">
<div className="clearfix edu-back-white poll_list">
<div className="font-16 color-dark-21 shixunreporttitleboxtop pd20 color333">
老师评阅<span>{work_comment_hidden===true||this.state.work_type===1?"(仅对课堂老师可见)":""}</span>
{this.props&&this.props.isAdminOrTeacher()===true?<a className="color-blue font-14 fr ml20"
onClick={()=>this.isdeleteModal()}
>删除</a>:""}
{this.props&&this.props.isAdminOrTeacher()===true?<a className="color-blue font-14 fr"
onClick={()=>this.showAppraiseModal()}
>编辑</a>:""}
</div>
<div className="font-16 color-dark-21 shixunreporttitleboxbom pd30">
<div style={{minHeight:'50px'}}>
<div className={"personalsummary"}>
<div className={"markdown-body"}
dangerouslySetInnerHTML={{__html: markdownToHTML(work_comment).replace(/▁/g, "▁▁▁")}}></div>
</div>
</div>
</div>
</div>
</div>:""}
<div className="stud-class-set bor-bottom-greyE mt17">
<div className="clearfix edu-back-white poll_list">
<div className="font-16 color-dark-21 shixunreporttitle ml20 pd20">图形统计</div>
<Shixunechart

@ -144,8 +144,17 @@ class ConclusionEvaluation extends Component {
.ant-table-tbody > tr{
height:64px;
}
// .Tablebox .ant-table-body table .ant-table-tbody > tr > td{
// border: none;
// }
.Tablebox .ant-table-body table .ant-table-thead > tr > th{
background: #fff;
border-bottom: 3px solid #fafafa !important;
}
`}</style>
<Table
className={"Tablebox"}
dataSource={datas}
columns={columns}
pagination={false}

@ -10,9 +10,12 @@
/*margin-right: 35px;*/
}
.search-newysl {
width:237px!important;
height: 30px;
margin-bottom: 30px;
}
.search-newyslw{
width:237px!important;
}
.search-new-input {
padding-left: 16px;

@ -36,7 +36,7 @@
.WordNumberTextarea-count {
display: inline-block;
float: right;
font-size: 0.28rem;
font-size: 16px;
color: #adadad;
padding-right: 0.25rem;
}

@ -14,7 +14,7 @@ render() {
onInput={(e)=>this.props.onInput(e)}
maxlength={this.props.maxlength}
/>
<div className="WordNumberTextarea-count"><span>{this.props.value===undefined?0:this.props.value.length}</span>/{this.props.maxlength}</div>
<div className="WordNumberTextarea-count"><span>{this.props.value===undefined||this.props.value===null?0:this.props.value.length}</span>/{this.props.maxlength}</div>
</div>
)
}

@ -219,6 +219,7 @@ class Index extends Component {
praisePlus={context.praisePlus}
git_url={context.git_url}
mirror_name={context.mirror_name}
challenge={context.challenge}
myshixun={context.myshixun}

@ -13,7 +13,7 @@ import ChooseEvaluateView from './main/ChooseEvaluateView'
import { CircularProgress } from 'material-ui/Progress';
import Button from 'material-ui/Button';
import VNCDisplay from './VNCDisplay'
import VNCContainer from './VNCContainer'
import './tpiPage.css';
import './tpiPageForMobile.css';
@ -94,9 +94,13 @@ class MainContent extends Component {
<div className="fl pr tip-right-con" id="update_game_tip"></div>
</div>*/}
{ showIframeContent && vnc_url ? <VNCDisplay
vnc_url={vnc_url}
></VNCDisplay>
{ showIframeContent && vnc_url ?
<CodeRepositoryViewContainer { ...this.props } isOnlyContainer={true}>
<VNCContainer
vnc_url={vnc_url}
{...this.props}
></VNCContainer>
</CodeRepositoryViewContainer>
:
<React.Fragment>

@ -0,0 +1,17 @@
.float_button {
background-image: url(./images/float_switch.jpg);
height: 112px;
width: 38px;
position: absolute;
left: -38px;
top: 32%;
cursor: pointer;
}
.float_button .text {
position: relative;
writing-mode: vertical-rl;
top: 36px;
color: #fff;
left: 13px;
user-select: none;
}

@ -0,0 +1,187 @@
import React, { Component } from 'react';
import axios from 'axios'
import { Spin } from 'antd'
import ClipboardJS from 'clipboard'
import VNCDisplay from './VNCDisplay'
import FloatButton from './component/FloatButton'
import SecondDrawer from './component/SecondDrawer'
import RepoTree from './component/repo/RepoTree'
import TPIMonaco from './component/monaco/TPIMonaco'
import notEditablePathImg from '../../images/tpi/notEditablePath.png'
import './VNC.css'
const $ = window.$;
const firstDrawerWidth = 260;
class VNCContainer extends Component {
constructor(props) {
super(props)
this.state = {
fileTreeSelectedKeys: [],
repositoryCode: ''
}
}
componentDidMount() {
if (!this.clipboard) {
const clipboard = new ClipboardJS('.copybtn');
clipboard.on('success', (e) => {
this.props.showSnackbar('复制成功')
});
this.clipboard = clipboard
}
}
getSecondDrawerWidth = () => {
return $('#game_right_contents').width() - firstDrawerWidth
}
renderSecondDrawerChildren = () => {
const { readingCodeLoading, repositoryCode } = this.state;
const height = $(window).height() - 130
const isEditablePath = false;
return (
<Spin tip="加载中..." spinning={readingCodeLoading}>
<div style={{ height: `${height}px` }}>
<div className="codemirrorBackground"
style={{ backgroundImage: `url('${notEditablePathImg}')`, display: (isEditablePath ? 'none' : 'block') }}></div>
<TPIMonaco
{...this.state}
codeLoading={readingCodeLoading}
repositoryCode={repositoryCode}
isEditablePath={false}
></TPIMonaco>
</div>
</Spin>);
}
fetchReadRepositoryCode = (path) => {
const status = 1
const fetchRepoCodeUrl = `/tasks/${this.props.game.identifier}/rep_content.json?path=${path}&status=${status}`
this.setState({ readingCodeLoading: true });
axios.get(fetchRepoCodeUrl, {
}).then((fetchReadRepositoryCodeResponse) => {
if (fetchReadRepositoryCodeResponse.data.content || fetchReadRepositoryCodeResponse.data.content == "") {
this.setState({
repositoryCode: fetchReadRepositoryCodeResponse.data.content,
readingCodeLoading: false
})
} else {
this.setState({ readingCodeLoading: false });
}
// this.setState({ isEditablePath, currentPath: path });
}).catch(error =>{
console.log(error)
this.setState({ readingCodeLoading: false });
this.props.showSnackbar(`服务端异常,请联系管理员!`);
})
}
onTreeSelect = (selectedKeys, info) => {
const isLeaf = info.node.props.isLeaf;
if (isLeaf) { // 叶子节点
selectedKeys.length && this.setState({
fileTreeSelectedKeys: selectedKeys
})
this.refs["secondDrawer"].showSecondDrawer()
console.log('leaf clicked')
const nodePath = info.node.props.eventKey;
if (nodePath) {
const filetype = nodePath.split('.').pop().toLowerCase();
if (filetype == 'jpg' || filetype == 'png' || filetype == 'gif' || filetype == 'jpeg'
|| filetype == 'jar' || filetype == 'exe'
|| filetype == 'doc' || filetype == 'pdf' || filetype == 'xsl' || filetype == 'ppt') {
this.props.showSnackbar(`不支持加载${filetype}类型的文件。`)
return;
}
this.fetchReadRepositoryCode(nodePath);
} else {
console.error('no eventKey:', info.node)
}
}
}
/*
selectedKeys={fileTreeSelectedKeys}
onSelect={onTreeSelect}
*/
render() {
const { challenge, vnc_url, git_url } = this.props
const secondDrawerChildren = this.renderSecondDrawerChildren();
return (
<React.Fragment>
<SecondDrawer
ref="secondDrawer"
floatText={'版本库'}
maskClosable={false}
secondDrawerChildren={secondDrawerChildren}
firstDrawerWidth={firstDrawerWidth}
getSecondDrawerWidth={this.getSecondDrawerWidth}
firstDrawerClassName="repoFilesDrawer vncDrawer"
secondDrawerClassName="codeInDrawer"
>
<style>{`
.vncDrawer .ant-drawer-body {
padding: 0px;
}
.vncDrawer .rc-tree {
padding: 16px;
max-width: 220px;
color: #CBCBCB;
}
.vncDrawer .ant-drawer-wrapper-body {
background: #242324;
}
.codeInDrawer .ant-drawer-wrapper-body {
background: #1D1C1D;
}
.vncDrawer .ant-drawer-header, .codeInDrawer .ant-drawer-header {
border-bottom: 0;
}
.vncDrawer > div:nth-child(1) {
opacity: 1 !important;
}
.vncDrawer > div:nth-child(2) {
top: 0px !important;
height: 100% !important;
min-width: unset;
}
.codeInDrawer .ant-spin-nested-loading > div > .ant-spin .ant-spin-text {
text-shadow: none;
}
`}</style>
<div style={{ 'padding': '16px', 'border-bottom': '1px solid #3A383A' }}>
<div style={{ color: '#888888' }}>网址克隆</div>
<div>
<input value={git_url} readonly={true} style={{ color: '#BABABA', width: '203px', background: 'transparent', border: 'none' }}></input>
<i class="iconfont icon-fuzhi font-14 ml10 copybtn"
style={{color: '#4CACFF', cursor: 'pointer', verticalAlign: 'baseline'}} data-clipboard-text={git_url} ></i>
</div>
</div>
<RepoTree
{...this.props}
fileTreeSelectedKeys={this.state.fileTreeSelectedKeys}
onTreeSelect={this.onTreeSelect}
></RepoTree>
</SecondDrawer>
<FloatButton></FloatButton>
<VNCDisplay
{...this.props}
></VNCDisplay>
</React.Fragment>
);
}
}
export default VNCContainer;

@ -131,19 +131,19 @@ class VNCDisplay extends Component {
return (
<div className="" style={{height: '100%'}}>
<div className="vncDisply" style={{height: '100%'}}>
<style>{`
#top_bar {
.vncDisply #top_bar {
background-color: #6e84a3;
color: white;
font: bold 12px Helvetica;
padding: 6px 5px 4px 5px;
border-bottom: 1px outset;
}
#status {
.vncDisply #status {
text-align: center;
}
#sendCtrlAltDelButton {
.vncDisply #sendCtrlAltDelButton {
position: fixed;
top: 0px;
right: 0px;
@ -151,10 +151,14 @@ class VNCDisplay extends Component {
padding: 5px 5px 4px 5px;
cursor: pointer;
}
#screen {
.vncDisply #screen {
height: 100%;
flex: 1; /* fill remaining space */
overflow: hidden;
background: #666;
}
.vncDisply #screen > div {
background: #666 !important;
}
`}</style>
<div id="top_bar">

@ -0,0 +1,24 @@
import React, { Component } from 'react';
const $ = window.$;
class FloatButton extends Component {
componentDidMount() {
}
render() {
const { challenge, vnc_url, children } = this.props
return (
<div className="float_button" onClick={this.props.onClick}>
<style>{`
`}</style>
<span class="text">{children || '版本库'}</span>
</div>
);
}
}
export default FloatButton;

@ -0,0 +1,101 @@
import React from "react";
import ReactDOM from "react-dom";
import { Drawer } from "antd";
import FloatButton from './FloatButton'
import PropTypes from 'prop-types';
class SecondDrawer extends React.Component {
state = { visible: false, childrenDrawer: false };
showDrawer = () => {
this.setState({
visible: true
});
};
onClose = () => {
this.setState({
visible: false
});
};
showSecondDrawer = () => {
this.setState({
childrenDrawer: true
});
};
onChildrenDrawerClose = () => {
this.setState({
childrenDrawer: false
});
};
swtichFirstDrawer = () => {
this.setState({
visible: !this.state.visible,
childrenDrawer: false
});
};
componentDidMount() {
this.setState({ visible: true }, () => {
this.setState({ visible: false });
});
}
render() {
const { floatText, maskClosable, children, secondDrawerChildren, firstDrawerWidth, getSecondDrawerWidth
,firstDrawerClassName, secondDrawerClassName
} = this.props
const secondDrawerWidth = getSecondDrawerWidth();
// 180 不知道为什么会偏移 180px
return (
<Drawer
mask={!this.state.visible}
title=" "
width={this.state.childrenDrawer ? secondDrawerWidth + firstDrawerWidth - 180 : firstDrawerWidth}
closable={false}
onClose={this.onClose}
visible={this.state.visible}
maskClosable={maskClosable}
className={firstDrawerClassName}
getContainer={false}
>
{/* <button type="primary" onClick={this.showSecondDrawer}>
Two-level drawer
</button> */}
<FloatButton onClick={this.swtichFirstDrawer}>{floatText}</FloatButton>
{ children }
<Drawer
mask={false}
title=" "
width={secondDrawerWidth}
closable={false}
onClose={this.onChildrenDrawerClose}
visible={this.state.childrenDrawer}
className={secondDrawerClassName}
>
{ secondDrawerChildren }
{/* <button
style={{
marginRight: 8
}}
onClick={this.onChildrenDrawerClose}
>
Cancel
</button> */}
</Drawer>
</Drawer>
);
}
}
SecondDrawer.propTypes = {
floatText: PropTypes.string,
maskClosable: PropTypes.bool,
secondDrawerChildren: PropTypes.element,
};
// firstDrawerWidth={firstDrawerWidth}
// getSecondDrawerWidth={this.getSecondDrawerWidth}
export default SecondDrawer

@ -271,6 +271,7 @@ class TPIMonaco extends Component {
const lang = getLanguageByMirrorName(this.props.mirror_name);
const editor = window.monaco.editor.create(document.getElementById('extend-challenge-file-edit'), {
value: value,
readOnly: !this.props.isEditablePath,
// 属性说明
// http://testeduplus2.educoder.net/react/build/static/node_modules/_monaco-editor@0.15.6@monaco-editor/esm/vs/editor/common/config/commonEditorConfig.js
// https://github.com/Microsoft/monaco-editor/issues/29
@ -303,7 +304,7 @@ class TPIMonaco extends Component {
notCallCodeMirrorOnChangeFlag = false
return;
}
this.props.onRepositoryCodeUpdate(editor.getValue())
this.props.onRepositoryCodeUpdate && this.props.onRepositoryCodeUpdate(editor.getValue())
})
this.props.codemirrorDidMount && this.props.codemirrorDidMount()

@ -0,0 +1,54 @@
import React, { useState, useEffect, useContext, useRef, memo } from 'react';
// import { Tree } from 'antd';
// const { TreeNode } = Tree;
import Tree, { TreeNode } from 'rc-tree';
import 'rc-tree/assets/index.css';
const $ = window.$;
export default function RepoTree(props) {
const { fileTreeData, onLoadData, onTreeSelect, fileTreeSelectedKeys, loadRepoFiles } = props;
const [expandedKeys, setExpandedKeys] = useState([])
useEffect(() => {
loadRepoFiles()
}, [])
if (!fileTreeData || fileTreeData.length === 0) {
return ""
}
const onExpand = (expandedKeys) => {
// console.log('onExpand', arguments);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
setExpandedKeys(expandedKeys)
}
const loop = (data) => {
return data.map((item) => {
if (item.children) {
return <TreeNode title={item.name} key={item.key}>{loop(item.children)}</TreeNode>;
}
return (
<TreeNode title={item.name} key={item.key} isLeaf={item.isLeaf} />
);
});
};
const treeNodes = loop(fileTreeData);
// selectable={false}
return (
<Tree
onExpand={onExpand}
expandedKeys={expandedKeys}
// autoExpandParent={this.state.autoExpandParent}
loadData={onLoadData}
selectedKeys={fileTreeSelectedKeys}
onSelect={onTreeSelect}
>
{treeNodes}
</Tree>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -101,6 +101,11 @@ class CodeRepositoryViewContainer extends Component {
drawerOpen: open,
})
}
loadRepoFiles = () => {
if (!this.state.fileTreeData) {
this.fetchRepoFiles();
}
}
componentWillReceiveProps(newProps, oldProps) {
@ -269,18 +274,34 @@ class CodeRepositoryViewContainer extends Component {
}
// /shixuns/mnf6b7z3/shixun_discuss?challenge_id=88
render() {
return (
<CodeRepositoryView {...this.props}
{...this.state}
showFilesDrawer={this.showFilesDrawer}
onLoadData={this.onLoadData}
onTreeSelect={ this.onTreeSelect }
onRepositoryViewExpand={this.onRepositoryViewExpand}
tabIndexChange={this.tabIndexChange}
showSettingDrawer={this.showSettingDrawer}
<React.Fragment>
{this.props.isOnlyContainer == true ?
React.Children.map(this.props.children, child => {
if(!child) {
return ''
}
return React.cloneElement(child, Object.assign({...this.state}, {
loadRepoFiles: this.loadRepoFiles,
onTreeSelect: this.onTreeSelect,
onLoadData: this.onLoadData,
}))
})
></CodeRepositoryView>
:
<CodeRepositoryView {...this.props}
{...this.state}
showFilesDrawer={this.showFilesDrawer}
loadRepoFiles={this.loadRepoFiles}
onLoadData={this.onLoadData}
onTreeSelect={ this.onTreeSelect }
onRepositoryViewExpand={this.onRepositoryViewExpand}
tabIndexChange={this.tabIndexChange}
showSettingDrawer={this.showSettingDrawer}
></CodeRepositoryView> }
</React.Fragment>
);
}
}

Loading…
Cancel
Save