Merge branch 'jupyter' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_jupyter
commit
4bf67843a8
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 引入阿里图标库
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-12-10 09:03:48
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-12-10 09:05:41
|
||||||
|
*/
|
||||||
|
import { Icon } from 'antd';
|
||||||
|
|
||||||
|
const MyIcon = Icon.createFromIconfontCN({
|
||||||
|
scriptUrl: '//at.alicdn.com/t/font_1535266_ss6796i6f6j.js'
|
||||||
|
});
|
||||||
|
|
||||||
|
export default MyIcon;
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 用户头像及昵称
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-12-09 17:11:28
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-12-09 17:36:55
|
||||||
|
*/
|
||||||
|
import './index.scss';
|
||||||
|
import React from 'react';
|
||||||
|
import { getImageUrl } from 'educoder'
|
||||||
|
|
||||||
|
function UserInfo (props) {
|
||||||
|
const {image_url, name} = props.userInfo;
|
||||||
|
return (
|
||||||
|
<div className={'avator_nicker'}>
|
||||||
|
<img alt="用户头像" className={'student_img'} src={getImageUrl(`images/${image_url}` || 'images/educoder/headNavLogo.png?1526520218')} />
|
||||||
|
<span className={'student_nicker'}>
|
||||||
|
{name || ''}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserInfo
|
||||||
|
export {
|
||||||
|
UserInfo
|
||||||
|
};
|
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
.avator_nicker{
|
||||||
|
position: absolute;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 65px;
|
||||||
|
// height: 65px;
|
||||||
|
.student_img,
|
||||||
|
.student_nicker{
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student_nicker{
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student_img{
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,18 @@
|
|||||||
@import '../split_pane_resizer.scss';
|
@import '../split_pane_resizer.scss';
|
||||||
|
|
||||||
|
.new_add_task_wrap {
|
||||||
|
.split-pane-area{
|
||||||
|
height: calc(100vh - 121px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.new_add_task_ctl{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 56px;
|
||||||
|
background: #333333;
|
||||||
|
> button{
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,215 +0,0 @@
|
|||||||
/*
|
|
||||||
* @Description: 右侧代码块
|
|
||||||
* @Author: tangjiang
|
|
||||||
* @Date: 2019-11-18 08:42:04
|
|
||||||
* @Last Modified by: tangjiang
|
|
||||||
* @Last Modified time: 2019-11-20 00:00:34
|
|
||||||
*/
|
|
||||||
|
|
||||||
import './index.scss';
|
|
||||||
|
|
||||||
import React, { Fragment, useState, useRef, useEffect } from 'react';
|
|
||||||
import { Icon, Drawer, Tabs, Button, notification } from 'antd';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import MonacoEditor from '@monaco-editor/react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import InitTabCtx from './initTabCtx';
|
|
||||||
import SettingDrawer from '../../components/monacoSetting';
|
|
||||||
import CONST from '../../../../constants';
|
|
||||||
import actions from '../../../../redux/actions';
|
|
||||||
|
|
||||||
const { fontSetting, opacitySetting } = CONST;
|
|
||||||
|
|
||||||
const { TabPane } = Tabs;
|
|
||||||
|
|
||||||
const RightPaneCode = (props) => {
|
|
||||||
|
|
||||||
const [showDrawer, setShowDrawer] = useState(false); // 控制配置滑框
|
|
||||||
const [defaultActiveKey, setDefaultActiveKey] = useState('1'); // 当前选中的tab
|
|
||||||
const [showTextResult, setShowTextResult] = useState(false); // 是否点击控制台按钮
|
|
||||||
const [editCode, setEditCode] = useState(()=> {
|
|
||||||
return '#include <stdio.h>';
|
|
||||||
}); // monaco编辑器内容
|
|
||||||
const [language, setLanguage] = useState('C')
|
|
||||||
const [fontSize,setFontSize] = useState(12);
|
|
||||||
const editorRef = useRef(null); // 编辑器ref
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.language) {
|
|
||||||
// console.log('当前输入的代码:', editCode);
|
|
||||||
// console.log('当前输入的语言:', props.language);
|
|
||||||
setLanguage(props.language)
|
|
||||||
}
|
|
||||||
}, [props.language]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [props.testCases]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
}, [editCode]);
|
|
||||||
|
|
||||||
// 监听store中编辑器内容变化
|
|
||||||
useEffect(() => {
|
|
||||||
setEditCode(props.code);
|
|
||||||
}, [props.code]);
|
|
||||||
|
|
||||||
// 打开设置
|
|
||||||
const handleShowDrawer = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setShowDrawer(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭设置
|
|
||||||
const handleDrawerClose = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setShowDrawer(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换tab
|
|
||||||
const handleTabChange = (key) => {
|
|
||||||
setDefaultActiveKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示/隐藏tab
|
|
||||||
const handleShowControl = () => {
|
|
||||||
setShowTextResult(!showTextResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 侧边栏改变字体大小
|
|
||||||
const handleFontSizeChange = (value) => {
|
|
||||||
setFontSize(value);
|
|
||||||
}
|
|
||||||
// 文本框内容变化时,记录文本框内容
|
|
||||||
const handleEditorChange = (origin, monaco) => {
|
|
||||||
editorRef.current = monaco; // 获取当前monaco实例
|
|
||||||
setEditCode(origin); // 保存编辑器初始值
|
|
||||||
editorRef.current.onDidChangeModelContent(e => { // 监听编辑器内容的变化
|
|
||||||
// TODO 需要优化 节流
|
|
||||||
const val = editorRef.current.getValue();
|
|
||||||
setEditCode(val);
|
|
||||||
// 保存当前代码
|
|
||||||
props.saveOjFormCode(val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提交按钮点击
|
|
||||||
const handleSubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (!editCode) {
|
|
||||||
notification['error']({
|
|
||||||
message: '必填',
|
|
||||||
description: '代码块内容必须输入!'
|
|
||||||
});
|
|
||||||
editorRef.current.focus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
props.changePublishLoadingStatus(true);
|
|
||||||
const { onSubmitForm } = props;
|
|
||||||
onSubmitForm(editCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调试测试代码
|
|
||||||
// const handleTestCode = () => {
|
|
||||||
// // 打开控制台信息
|
|
||||||
// setShowTextResult(true);
|
|
||||||
// this.formRef.handleTestCodeFormSubmit(() => {
|
|
||||||
// // 当验证通过后 切换tab 到代码执行结果
|
|
||||||
// setDefaultActiveKey('2');
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 控制台点击时 添加active属性
|
|
||||||
const classNames = `control_tab ${showTextResult ? 'move_up move_up_final' : 'move_down_final'}`;
|
|
||||||
|
|
||||||
// 配置编辑器属性
|
|
||||||
const editorOptions = {
|
|
||||||
selectOnLineNumbers: true,
|
|
||||||
automaticLayout: true,
|
|
||||||
fontSize: `${fontSize}px`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回渲染值
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<div className={'right_pane_code_wrap'}>
|
|
||||||
<div className={'code-title'}>
|
|
||||||
<span></span>
|
|
||||||
<Icon className={'code-icon'} type="setting" onClick={handleShowDrawer}/>
|
|
||||||
</div>
|
|
||||||
{/** 代码编辑器 */}
|
|
||||||
<MonacoEditor
|
|
||||||
height={showTextResult ? 'calc(100% - 382px)' : 'calc(100% - 112px)'}
|
|
||||||
width="100%"
|
|
||||||
language={language.toLowerCase()}
|
|
||||||
value={editCode}
|
|
||||||
options={editorOptions}
|
|
||||||
theme="dark"
|
|
||||||
editorDidMount={handleEditorChange}
|
|
||||||
/>
|
|
||||||
{/* 控制台信息 */}
|
|
||||||
<div className="pane_control_area">
|
|
||||||
<Tabs
|
|
||||||
className={classNames}
|
|
||||||
activeKey={defaultActiveKey}
|
|
||||||
tabBarStyle={{ backgroundColor: '#000', color: '#fff' }}
|
|
||||||
onChange={handleTabChange}
|
|
||||||
>
|
|
||||||
<TabPane tab={'自定义测试用例'} key={'1'} style={{ height: '280px', overflowY: 'auto' }}>
|
|
||||||
<InitTabCtx wrappedComponentRef={(form) => this.formRef = form }/>
|
|
||||||
</TabPane>
|
|
||||||
<TabPane tab={'代码执行结果'} key={'2'} style={{ height: '280px', overflowY: 'auto' }}>
|
|
||||||
<h2>代码执行结果</h2>
|
|
||||||
</TabPane>
|
|
||||||
</Tabs>
|
|
||||||
<div className="pane_control_opts">
|
|
||||||
<Button type="link" style={{ color: '#fff' }} onClick={handleShowControl}>控制台 <Icon type={ showTextResult ? "down" : "up" } /></Button>
|
|
||||||
<p>
|
|
||||||
{/* <Button ghost
|
|
||||||
style={{ marginRight: '10px', color: '#28BD8B', borderColor: '#28BD8B' }}
|
|
||||||
onClick={handleTestCode}
|
|
||||||
disabled={!props.identifier || props.testCases.length === 0}
|
|
||||||
>调试代码</Button> */}
|
|
||||||
<Button
|
|
||||||
loading={props.submitLoading}
|
|
||||||
type="primary"
|
|
||||||
onClick={handleSubmit}
|
|
||||||
>{props.identifier ? '更新' : '提交'}</Button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Drawer
|
|
||||||
className={'setting_drawer'}
|
|
||||||
placement="right"
|
|
||||||
closable={false}
|
|
||||||
onClose={handleDrawerClose}
|
|
||||||
visible={showDrawer}
|
|
||||||
>
|
|
||||||
<SettingDrawer {...fontSetting} onChangeFontSize={handleFontSizeChange}/>
|
|
||||||
<SettingDrawer {...opacitySetting}/>
|
|
||||||
</Drawer>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
|
||||||
const { ojForm, testCases, identifier, code } = state.ojFormReducer;
|
|
||||||
const { submitLoading } = state.commonReducer;
|
|
||||||
return {
|
|
||||||
language: ojForm.language,
|
|
||||||
testCases,
|
|
||||||
identifier,
|
|
||||||
code,
|
|
||||||
submitLoading
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
|
||||||
saveOjFormCode: (code) => dispatch(actions.saveOjFormCode(code)),
|
|
||||||
changePublishLoadingStatus: (flag) => dispatch(actions.changeSubmitLoadingStatus(flag))
|
|
||||||
});
|
|
||||||
//
|
|
||||||
export default connect(
|
|
||||||
mapStateToProps,
|
|
||||||
mapDispatchToProps
|
|
||||||
)(RightPaneCode);
|
|
@ -1,4 +0,0 @@
|
|||||||
.quill_editor_area{
|
|
||||||
height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
@ -0,0 +1,50 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
|
||||||
|
class Bottomsubmit extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cannelfun=()=>{
|
||||||
|
window.location.href=this.props.url
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<style>
|
||||||
|
{
|
||||||
|
`
|
||||||
|
.newFooter{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div className="clearfix bor-bottom-greyE edu-back-white orderingbox newshixunbottombtn">
|
||||||
|
<div className=" edu-txt-center padding13-30">
|
||||||
|
<button type="button" className="ant-btn mr20 newshixunmode backgroundFFF" onClick={()=>this.cannelfun()}><span>取 消</span></button>
|
||||||
|
<button type="button" className="ant-btn newshixunmode mr40 ant-btn-primary" type="primary" htmlType="submit" onClick={()=>this.props.onSubmits()}><span>确 定</span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default Bottomsubmit;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,531 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {Redirect} from 'react-router';
|
||||||
|
import {List, Typography, Tag, Modal, Radio, Checkbox, Table, Pagination,Upload,notification} from 'antd';
|
||||||
|
import { NoneData } from 'educoder'
|
||||||
|
|
||||||
|
import TPMRightSection from './component/TPMRightSection';
|
||||||
|
import TPMNav from './component/TPMNav';
|
||||||
|
import axios from 'axios';
|
||||||
|
import './tpmmodel/tpmmodel.css'
|
||||||
|
import {getUploadActionUrl} from 'educoder';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
const confirm = Modal.confirm;
|
||||||
|
|
||||||
|
class TPMDataset extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
this.state = {
|
||||||
|
datas: [0, 1, 2, 3, 4, 5],
|
||||||
|
value: undefined,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '文件',
|
||||||
|
dataIndex: 'number',
|
||||||
|
key: 'number',
|
||||||
|
align: 'left',
|
||||||
|
className: " font-14 wenjiantit",
|
||||||
|
width: '200px',
|
||||||
|
render: (text, record) => (
|
||||||
|
<div>
|
||||||
|
{record.title}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '最后修改时间',
|
||||||
|
dataIndex: 'number',
|
||||||
|
key: 'number',
|
||||||
|
align: 'center',
|
||||||
|
className: "edu-txt-center font-14 zuihoushijian",
|
||||||
|
width: '150px',
|
||||||
|
render: (text, record) => (
|
||||||
|
<div>
|
||||||
|
{record.timedata}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '最后修改人',
|
||||||
|
dataIndex: 'number',
|
||||||
|
key: 'number',
|
||||||
|
align: 'center',
|
||||||
|
className: "edu-txt-center font-14 ",
|
||||||
|
render: (text, record) => (
|
||||||
|
<div>
|
||||||
|
{record.author}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '文件大小',
|
||||||
|
dataIndex: 'number',
|
||||||
|
key: 'number',
|
||||||
|
align: 'center',
|
||||||
|
className: "edu-txt-center font-14 ",
|
||||||
|
render: (text, record) => (
|
||||||
|
<div>
|
||||||
|
{record.filesize}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
],
|
||||||
|
page: 1,
|
||||||
|
limit: 10,
|
||||||
|
selectedRowKeys: [],
|
||||||
|
mylistansum:30,
|
||||||
|
collaboratorList:[],
|
||||||
|
fileList:[],
|
||||||
|
file:null,
|
||||||
|
datalist:[],
|
||||||
|
data_sets_count:0,
|
||||||
|
selectedRowKeysdata:[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.getdatas()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mysonChange = (e) => {
|
||||||
|
console.log(`全选checked = ${e.target.checked}`);
|
||||||
|
if (e.target.checked === true) {
|
||||||
|
let mydata=[];
|
||||||
|
let datas=[];
|
||||||
|
for(let i=0;i<this.state.collaboratorList.data_sets.length;i++){
|
||||||
|
mydata.push(this.state.collaboratorList.data_sets[i].id);
|
||||||
|
datas.push(i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
selectedRowKeysdata:mydata,
|
||||||
|
selectedRowKeys: datas,
|
||||||
|
})
|
||||||
|
console.log(mydata);
|
||||||
|
console.log(datas);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
selectedRowKeys: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getdatas = () => {
|
||||||
|
let id=this.props.match.params.shixunId;
|
||||||
|
|
||||||
|
let collaborators=`/shixuns/${id}/jupyter_data_sets.json`;
|
||||||
|
axios.get(collaborators,{params:{
|
||||||
|
page:1,
|
||||||
|
limit:10,
|
||||||
|
}}).then((response)=> {
|
||||||
|
if(response.status===200){
|
||||||
|
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
|
||||||
|
|
||||||
|
}else{
|
||||||
|
let datalists=[];
|
||||||
|
for(let i=0;i<response.data.data_sets.length;i++){
|
||||||
|
const datas=response.data.data_sets;
|
||||||
|
var timedata = moment(datas[i].created_on).format('YYYY-MM-DD HH:mm');
|
||||||
|
datalists.push({
|
||||||
|
timedata:timedata,
|
||||||
|
author:datas[i].author,
|
||||||
|
filesize:datas[i].filesize,
|
||||||
|
id:datas[i].id,
|
||||||
|
title:datas[i].title,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
collaboratorList: response.data,
|
||||||
|
data_sets_count:response.data.data_sets_count,
|
||||||
|
datalist:datalists,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}).catch((error)=>{
|
||||||
|
console.log(error)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getdatastwo = (page,limit) => {
|
||||||
|
let id=this.props.match.params.shixunId;
|
||||||
|
|
||||||
|
let collaborators=`/shixuns/${id}/jupyter_data_sets.json`;
|
||||||
|
axios.get(collaborators,{params:{
|
||||||
|
page:page,
|
||||||
|
limit:limit,
|
||||||
|
}}).then((response)=> {
|
||||||
|
if(response.status===200){
|
||||||
|
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
|
||||||
|
|
||||||
|
}else{
|
||||||
|
let datalists=[];
|
||||||
|
for(let i=0;i<response.data.data_sets.length;i++){
|
||||||
|
const datas=response.data.data_sets;
|
||||||
|
var timedata = moment(datas[i].created_on).format('YYYY-MM-DD HH:mm');
|
||||||
|
datalists.push({
|
||||||
|
timedata:timedata,
|
||||||
|
author:datas[i].author,
|
||||||
|
filesize:datas[i].filesize,
|
||||||
|
id:datas[i].id,
|
||||||
|
title:datas[i].title,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
collaboratorList: response.data,
|
||||||
|
data_sets_count:response.data.data_sets_count,
|
||||||
|
datalist:datalists,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}).catch((error)=>{
|
||||||
|
console.log(error)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
showModal = (id, status) => {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
handleOk = (id, editid) => {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
handleCancel = (e) => {
|
||||||
|
|
||||||
|
};
|
||||||
|
paginationonChanges = (pageNumber) => {
|
||||||
|
// //console.log('Page: ');
|
||||||
|
this.setState({
|
||||||
|
page: pageNumber,
|
||||||
|
})
|
||||||
|
this.getdatastwo(pageNumber,10);
|
||||||
|
}
|
||||||
|
onSelectChange = (selectedRowKeys, selectedRows) => {
|
||||||
|
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
selectedRowKeys
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let mydata=[];
|
||||||
|
for(let i=0;i<selectedRows.length;i++){
|
||||||
|
mydata.push(selectedRows[i].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
selectedRowKeysdata:mydata,
|
||||||
|
})
|
||||||
|
console.log(mydata);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
rowClassName = (record, index) => {
|
||||||
|
let className = 'light-row';
|
||||||
|
if (index % 2 === 1) className = 'dark-row';
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 附件相关 START
|
||||||
|
handleChange = (info) => {
|
||||||
|
if(info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||||
|
let {fileList} = this.state;
|
||||||
|
|
||||||
|
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||||
|
console.log("handleChange1");
|
||||||
|
// if(fileList.length===0){
|
||||||
|
let fileLists = info.fileList;
|
||||||
|
this.setState({
|
||||||
|
// fileList:appendFileSizeToUploadFileAll(fileList),
|
||||||
|
fileList: fileLists,
|
||||||
|
deleteisnot: false
|
||||||
|
});
|
||||||
|
this.getdatas();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onAttachmentRemove = (file) => {
|
||||||
|
if(!file.percent || file.percent == 100){
|
||||||
|
confirm({
|
||||||
|
title: '确定要删除这个附件吗?',
|
||||||
|
okText: '确定',
|
||||||
|
cancelText: '取消',
|
||||||
|
// content: 'Some descriptions',
|
||||||
|
onOk: () => {
|
||||||
|
console.log("665")
|
||||||
|
this.deleteAttachment(file)
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
console.log('Cancel');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteRemovedata(){
|
||||||
|
debugger
|
||||||
|
console.log("删除");
|
||||||
|
console.log(this.state.selectedRowKeysdata);
|
||||||
|
const url = `/attachments/destroy_files.json`;
|
||||||
|
axios.delete(url, {
|
||||||
|
id:this.state.selectedRowKeysdata,
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
const { status } = response.data;
|
||||||
|
if (status == 0) {
|
||||||
|
this.props.showNotification(`删除成功`);
|
||||||
|
this.getdatas()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
deleteAttachment = (file) => {
|
||||||
|
console.log(file);
|
||||||
|
let id=file.response ==undefined ? file.id : file.response.id
|
||||||
|
const url = `/attachements/destroy_files.json`
|
||||||
|
axios.delete(url, {
|
||||||
|
id:[id],
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
const { status } = response.data;
|
||||||
|
if (status == 0) {
|
||||||
|
// console.log('--- success')
|
||||||
|
|
||||||
|
this.setState((state) => {
|
||||||
|
|
||||||
|
const index = state.fileList.indexOf(file);
|
||||||
|
const newFileList = state.fileList.slice();
|
||||||
|
newFileList.splice(index, 1);
|
||||||
|
return {
|
||||||
|
fileList: newFileList,
|
||||||
|
deleteisnot:true
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {tpmLoading, shixun, user, match} = this.props;
|
||||||
|
const {columns, datas, page, limit, selectedRowKeys,mylistansum,fileList,datalist,data_sets_count} = this.state;
|
||||||
|
const rowSelection = {
|
||||||
|
selectedRowKeys,
|
||||||
|
onChange: this.onSelectChange,
|
||||||
|
};
|
||||||
|
// getCheckboxProps: record => ({
|
||||||
|
// disabled: record.name === 'Disabled User', // Column configuration not to be checked
|
||||||
|
// name: record.name,
|
||||||
|
// }),
|
||||||
|
let id=this.props.match.params.shixunId;
|
||||||
|
const uploadProps = {
|
||||||
|
width: 600,
|
||||||
|
fileList,
|
||||||
|
data:{
|
||||||
|
attachtype: 2,
|
||||||
|
container_id:this.props.match.params.shixunId,
|
||||||
|
container_type: "Shixun",
|
||||||
|
},
|
||||||
|
multiple: true,
|
||||||
|
// https://github.com/ant-design/ant-design/issues/15505
|
||||||
|
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
|
||||||
|
// showUploadList: false,
|
||||||
|
action: `${getUploadActionUrl()}`,
|
||||||
|
onChange: this.handleChange,
|
||||||
|
onRemove: this.onAttachmentRemove,
|
||||||
|
beforeUpload: (file, fileList) => {
|
||||||
|
|
||||||
|
if (this.state.fileList.length >= 1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// console.log('beforeUpload', file.name);
|
||||||
|
const isLt150M = file.size / 1024 / 1024 < 50;
|
||||||
|
if (!isLt150M) {
|
||||||
|
// this.props.showNotification(`文件大小必须小于50MB`);
|
||||||
|
notification.open(
|
||||||
|
{
|
||||||
|
message: '提示',
|
||||||
|
description:
|
||||||
|
'文件大小必须小于50MB',
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if(this.state.file !== undefined){
|
||||||
|
console.log("763")
|
||||||
|
this.setState({
|
||||||
|
file:file
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
this.setState({
|
||||||
|
file:file
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("handleChange2");
|
||||||
|
return isLt150M;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div className="tpmComment educontent clearfix mt30 mb80">
|
||||||
|
|
||||||
|
<div className="with65 fl edu-back-white commentsDelegateParent">
|
||||||
|
|
||||||
|
<TPMNav
|
||||||
|
match={match}
|
||||||
|
user={user}
|
||||||
|
shixun={shixun}
|
||||||
|
{...this.props}
|
||||||
|
></TPMNav>
|
||||||
|
|
||||||
|
<div className="padding20 edu-back-white mt20 " style={{minHeight: '463px'}}>
|
||||||
|
<div className="sortinxdirection">
|
||||||
|
<div className="tpmwidth">
|
||||||
|
{ data_sets_count>0?
|
||||||
|
<Checkbox onChange={this.mysonChange}>全选</Checkbox>:""}
|
||||||
|
</div>
|
||||||
|
<div className="tpmwidth xaxisreverseorder">
|
||||||
|
<style>
|
||||||
|
{
|
||||||
|
`
|
||||||
|
.ant-upload-list{
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div className="deletebuttom intermediatecenter "> <Upload {...uploadProps}><p className="deletebuttomtest">
|
||||||
|
|
||||||
|
上传文件</p> </Upload></div>
|
||||||
|
{
|
||||||
|
data_sets_count>0?
|
||||||
|
<div
|
||||||
|
className={selectedRowKeys.length > 0 ? "deletebutomtextcode intermediatecenter mr21" : "deletebutom intermediatecenter mr21"} onClick={()=>this.deleteRemovedata()}>
|
||||||
|
<p className="deletebutomtext" >删除</p></div>
|
||||||
|
:""
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt24">
|
||||||
|
<style>{`
|
||||||
|
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
|
||||||
|
top: 72%;}
|
||||||
|
}
|
||||||
|
.edu-table .ant-table-tbody > tr > td {
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
.edu-table .ant-table-thead > tr > th{
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
.ysltableowss .ant-table-thead > tr > th{
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
.ysltableowss .ant-table-tbody > tr > td{
|
||||||
|
height: 42px;
|
||||||
|
}
|
||||||
|
.ysltableowss .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
||||||
|
padding: 9px;
|
||||||
|
}
|
||||||
|
.mysjysltable4 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
.ant-table-thead .ant-table-selection-column span{
|
||||||
|
visibility:hidden;
|
||||||
|
}
|
||||||
|
.ant-table-thead > tr > th {
|
||||||
|
background:#FFFFFF !important;
|
||||||
|
}
|
||||||
|
.ant-table table {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 0;
|
||||||
|
border-left: 1px solid #eeeeee;
|
||||||
|
border-top: 1px solid #eeeeee;
|
||||||
|
border-right: 1px solid #eeeeee;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
{data_sets_count===0?
|
||||||
|
<style>
|
||||||
|
{
|
||||||
|
`
|
||||||
|
.ant-table-tbody{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.ant-table table {
|
||||||
|
border-bottom: 1px solid #eeeeee !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
:
|
||||||
|
<div className="edu-table edu-back-white ysltableowss">
|
||||||
|
<Table
|
||||||
|
dataSource={datalist}
|
||||||
|
columns={columns}
|
||||||
|
pagination={false}
|
||||||
|
className="mysjysltable4"
|
||||||
|
rowSelection={rowSelection}
|
||||||
|
rowClassName={this.rowClassName}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
data_sets_count>=11?
|
||||||
|
<div className="edu-txt-center mt40 mb20">
|
||||||
|
<Pagination showQuickJumper current={page}
|
||||||
|
onChange={this.paginationonChanges} pageSize={limit}
|
||||||
|
total={data_sets_count}
|
||||||
|
></Pagination>
|
||||||
|
</div>
|
||||||
|
:""
|
||||||
|
}
|
||||||
|
|
||||||
|
{ data_sets_count===0?
|
||||||
|
<NoneData style={{width: '100%'}}></NoneData>:""
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="with35 fr pl20">
|
||||||
|
<TPMRightSection
|
||||||
|
{...this.props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TPMDataset;
|
@ -0,0 +1,33 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Icon,DatePicker,Breadcrumb,Upload,Button,notification, Tooltip,Tabs} from 'antd';
|
||||||
|
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import './css/TPMsettings.css';
|
||||||
|
|
||||||
|
import { getImageUrl, toPath, getUrl ,appendFileSizeToUploadFileAll, getUploadActionUrl} from 'educoder';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default class Shixuninformation extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
this.state = {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
1111
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* @Description: jupyter tpi
|
||||||
|
* @Author: tangjiang
|
||||||
|
* @Github:
|
||||||
|
* @Date: 2019-12-11 08:35:23
|
||||||
|
* @LastEditors: tangjiang
|
||||||
|
* @LastEditTime: 2019-12-11 09:13:09
|
||||||
|
*/
|
||||||
|
import './index.scss';
|
||||||
|
import React from 'react';
|
||||||
|
import SplitPane from 'react-split-pane';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
|
||||||
|
import UserInfo from '../../developer/components/userInfo';
|
||||||
|
|
||||||
|
function JupyterTPI (props) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="jupyter_area">
|
||||||
|
<div className="jupyter_header">
|
||||||
|
<UserInfo userInfo={{}} />
|
||||||
|
<p className="jupyter_title">
|
||||||
|
<span className="title_desc">MySQL数据库编程开发实训(基础篇)</span>
|
||||||
|
<span className="title_time">时间</span>
|
||||||
|
</p>
|
||||||
|
<p className="jupyter_btn">
|
||||||
|
{/* sync | poweroff */}
|
||||||
|
<Button className="btn_common" type="link" icon="sync">重置实训</Button>
|
||||||
|
<Button className="btn_common" type="link" icon="poweroff">退出实训</Button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="jupyter_ctx">
|
||||||
|
<SplitPane split="vertical" minSize={350} maxSize={-350} defaultSize="30%">
|
||||||
|
<div className={'split-pane-left'}>
|
||||||
|
左侧内容
|
||||||
|
</div>
|
||||||
|
<SplitPane split="vertical" defaultSize="100%" allowResize={false}>
|
||||||
|
<div>右侧内容</div>
|
||||||
|
<div />
|
||||||
|
</SplitPane>
|
||||||
|
</SplitPane>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JupyterTPI;
|
@ -0,0 +1,93 @@
|
|||||||
|
.Resizer {
|
||||||
|
background: #000;
|
||||||
|
opacity: 0.2;
|
||||||
|
z-index: 1;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-moz-background-clip: padding;
|
||||||
|
-webkit-background-clip: padding;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer:hover {
|
||||||
|
-webkit-transition: all 2s ease;
|
||||||
|
transition: all 2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.horizontal {
|
||||||
|
height: 11px;
|
||||||
|
margin: -5px 0;
|
||||||
|
border-top: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
border-bottom: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
cursor: row-resize;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.horizontal:hover {
|
||||||
|
border-top: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.vertical {
|
||||||
|
width: 11px;
|
||||||
|
margin: 0 -5px;
|
||||||
|
border-left: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
border-right: 5px solid rgba(255, 255, 255, 0);
|
||||||
|
cursor: col-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Resizer.vertical:hover {
|
||||||
|
border-left: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
border-right: 5px solid rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.Resizer.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.Resizer.disabled:hover {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jupyter_area{
|
||||||
|
|
||||||
|
.jupyter_header{
|
||||||
|
position: relative;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
background-color: #070F1A;
|
||||||
|
|
||||||
|
.jupyter_title{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
// justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
color: #fff;
|
||||||
|
.title_desc{
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.title_time{
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
// text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jupyter_btn{
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 14px;
|
||||||
|
|
||||||
|
.btn_common:hover{
|
||||||
|
// background-color: #29BD8B;
|
||||||
|
color: #29BD8B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.jupyter_ctx{
|
||||||
|
position: relative;
|
||||||
|
height: calc(100vh - 60px);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,111 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import {Button,Form,Input} from 'antd';
|
||||||
|
import axios from 'axios';
|
||||||
|
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
|
||||||
|
class Osshackathonmd extends Component{
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
this.contentMdRef = React.createRef();
|
||||||
|
this.state={
|
||||||
|
title_num: 0,
|
||||||
|
title_value: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
componentDidUpdate =(prevState)=>{
|
||||||
|
// if(prevState!=this.props){
|
||||||
|
// let url=`/osshackathon/edit_hackathon.json`;
|
||||||
|
// axios.get(url).then((result)=>{
|
||||||
|
// if(result.status==200){
|
||||||
|
// this.setState({
|
||||||
|
// title_value:result.data.name
|
||||||
|
// })
|
||||||
|
// this.contentMdRef.current.setValue(result.data.description);
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
componentDidMount(){
|
||||||
|
let url=`/osshackathon/edit_hackathon.json`;
|
||||||
|
axios.get(url).then((result)=>{
|
||||||
|
if(result.status==200){
|
||||||
|
this.setState({
|
||||||
|
title_value:result.data.name
|
||||||
|
})
|
||||||
|
this.contentMdRef.current.setValue(result.data.description === null ? "" : result.data.description);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 输入title
|
||||||
|
changeTitle = (e) => {
|
||||||
|
// title_num: 60 - parseInt(e.target.value.length),
|
||||||
|
this.setState({
|
||||||
|
title_num: e.target.value.length,
|
||||||
|
title_value: e.target.value
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
handleSubmit = () => {
|
||||||
|
let {title_value}=this.state;
|
||||||
|
const mdContnet = this.contentMdRef.current.getValue().trim();
|
||||||
|
// if(mdContnet.length>10000){
|
||||||
|
// this.props.showNotification("内容超过10000个字");
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
let url=`/osshackathon/update_hackathon.json`;
|
||||||
|
axios.post(url,{
|
||||||
|
name:title_value,
|
||||||
|
description:mdContnet,
|
||||||
|
}
|
||||||
|
).then((response) => {
|
||||||
|
if(response.data.status===0){
|
||||||
|
this.props.getosshackathon()
|
||||||
|
this.props.hidehackathonedit()
|
||||||
|
this.props.showNotification(`提交成功`);
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(this.props.tabkey)
|
||||||
|
// console.log(chart_rules)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={"mt20"}>
|
||||||
|
<Form>
|
||||||
|
<Form.Item label="标题">
|
||||||
|
<Input placeholder="请输入标题"
|
||||||
|
value={this.state.title_value}
|
||||||
|
onInput={this.changeTitle}
|
||||||
|
className="searchView searchViewAfter h45input" style={{"width": "100%"}} maxLength="60"
|
||||||
|
addonAfter={String(this.state.title_value === undefined || this.state.title_value === null ? 0 : this.state.title_value.length) + "/60"}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item label="描述">
|
||||||
|
<TPMMDEditor ref={this.contentMdRef} placeholder="请输入描述" mdID={'courseContentMD'} refreshTimeout={1500}
|
||||||
|
className="courseMessageMD"
|
||||||
|
initValue={this.state.description === null ? "" : this.state.description}></TPMMDEditor>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className="clearfix mt30 mb30">
|
||||||
|
<div className={"fr"}>
|
||||||
|
<Button type="primary" onClick={this.handleSubmit} className="defalutSubmitbtn fl mr20">提交</Button>
|
||||||
|
<a className="defalutCancelbtn fl" onClick={() => this.props.hidehackathonedit()}>取消</ a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Osshackathonmd;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,281 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import { Redirect } from 'react-router';
|
||||||
|
|
||||||
|
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
|
||||||
|
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { getImageUrl ,markdownToHTML, configShareForCustom} from 'educoder'
|
||||||
|
|
||||||
|
import { CircularProgress } from 'material-ui/Progress';
|
||||||
|
|
||||||
|
import { Modal, Spin, Tooltip ,message,Icon} from 'antd';
|
||||||
|
|
||||||
|
import 'antd/lib/pagination/style/index.css';
|
||||||
|
|
||||||
|
import '../shixunchildCss/Challenges.css'
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import axios from 'axios';
|
||||||
|
import AccountProfile from"../../../user/AccountProfile";
|
||||||
|
const $ = window.$;
|
||||||
|
|
||||||
|
|
||||||
|
class Challengesjupyter extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
this.state = {
|
||||||
|
ChallengesDataList: undefined,
|
||||||
|
operate: true,
|
||||||
|
startbtns: false,
|
||||||
|
iFrameHeight: '0px',
|
||||||
|
jupyter_port:0,
|
||||||
|
jupyter_url:null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChallengesList = () => {
|
||||||
|
let id = this.props.match.params.shixunId;
|
||||||
|
let ChallengesURL = `/shixuns/` + id + `/challenges.json`;
|
||||||
|
|
||||||
|
axios.get(ChallengesURL).then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
|
||||||
|
|
||||||
|
}else{
|
||||||
|
configShareForCustom(this.props.shixunsDetails.name, response.data.description)
|
||||||
|
this.setState({
|
||||||
|
ChallengesDataList: response.data,
|
||||||
|
sumidtype: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log(error)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
setTimeout(this.ChallengesList(), 1000);
|
||||||
|
|
||||||
|
|
||||||
|
console.log("componentDidMount");
|
||||||
|
console.log("Challengesjupyter");
|
||||||
|
console.log(this.props);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
updatamakedown = (id) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关卡的上移下移操作
|
||||||
|
operations = (sumid, type) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
delOperations = (sumid) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
clonedelOperationss = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
delOperationss = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
startgameid=(id)=>{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hidestartshixunsreplace=(url)=>{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//编辑实训题目选择题
|
||||||
|
EditTraining=(type, ids, path)=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//开始实战按钮
|
||||||
|
startshixunCombat = (type, ids, id) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
hidestartshixunCombattype=()=>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
hideAccountProfile=()=>{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
modifyjupyter=(propsysl)=>{
|
||||||
|
console.log("propsysl");
|
||||||
|
console.log(propsysl);
|
||||||
|
let id=this.props.match.params.shixunId;
|
||||||
|
|
||||||
|
const url=`/shixuns/${id}/update_jupyter.json`;
|
||||||
|
const data={
|
||||||
|
identifier:id,
|
||||||
|
jupyter_port:propsysl.shixunsDetails.jupyter_port
|
||||||
|
}
|
||||||
|
axios.post(url, data)
|
||||||
|
.then((result) => {
|
||||||
|
if (result.data.status == 0) {
|
||||||
|
this.props.showNotification(`应用成功`);
|
||||||
|
}
|
||||||
|
}).catch((error) => {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sendToken=()=>{
|
||||||
|
// console.log("sendToken");
|
||||||
|
// const iframe = document.getElementById('iframe');
|
||||||
|
// console.log("modifyjupyter");
|
||||||
|
// const frameWindow = iframe.contentWindow;
|
||||||
|
// console.log("frameWindow");
|
||||||
|
// console.log(frameWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let{ChallengesDataList}=this.state;
|
||||||
|
let id = this.props.match.params.shixunId;
|
||||||
|
// var deptObjs=document.getElementById("IFRAMEID").contentWindow.document.getElementById("TAGID");
|
||||||
|
// //判断此元素是否存在
|
||||||
|
// if(deptObjs!=null){
|
||||||
|
// //设置该元素的样式或其他属性
|
||||||
|
// deptObjs.setAttribute('style',' height: 20px !important;'); //!important用来提升指定样式条目的应用优先权
|
||||||
|
// }
|
||||||
|
// var submitObj = document.getElementById('submit');
|
||||||
|
// if(submitObj){
|
||||||
|
// submitObj.style.color = 'green';
|
||||||
|
// }
|
||||||
|
// const dom = document.getElementById('shutdown');
|
||||||
|
// ReactDOM.unmountComponentAtNode(dom)
|
||||||
|
// // window.$('#picture_display').hide();
|
||||||
|
// window.$('.data-tip-right').hide()
|
||||||
|
// window.onload=()=>{
|
||||||
|
// debugger
|
||||||
|
// var _iframe = document.getElementById('header');
|
||||||
|
// console.log(_iframe);
|
||||||
|
// // .contentWindow.document.getElementById('shutdown_widget') //get iframe下的id
|
||||||
|
// // _iframe.style.display= "none"; //修改样式
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div className="mt30 pl20 pr20" >
|
||||||
|
<p className="clearfix mb20">
|
||||||
|
<span className="font-16 fl">简介</span>
|
||||||
|
<Tooltip placement="bottom" title={"编辑"}>
|
||||||
|
<a style={{ display: this.props.identity < 5 && ChallengesDataList&&ChallengesDataList.shixun_status < 3 ? "block" : 'none' }}
|
||||||
|
href={"/shixuns/" + id + "/settings?edit=1"} className="ring-green fr">
|
||||||
|
<img src={getImageUrl("images/educoder/icon/edit.svg")} className="fl mt3 ml2" />
|
||||||
|
</a>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="justify break_full_word new_li "
|
||||||
|
id="challenge_editorMd_description">
|
||||||
|
<p id="ReactMarkdown" style={{overflow:'hidden'}}>
|
||||||
|
{ChallengesDataList === undefined ? "" :ChallengesDataList&&ChallengesDataList.description===null?"":
|
||||||
|
<div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML(ChallengesDataList.description).replace(/▁/g,"▁▁▁")}}></div>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
<style>
|
||||||
|
{
|
||||||
|
`
|
||||||
|
.intermediatecenter{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortinxdirection{
|
||||||
|
display: flex;
|
||||||
|
flex-direction:row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xaxisreverseorder{
|
||||||
|
display: flex;
|
||||||
|
flex-direction:row-reverse;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div className="sortinxdirection mt60">
|
||||||
|
<div className="renwuxiangssi sortinxdirection">
|
||||||
|
<div><p className="renwuxiangqdiv">任务详情</p></div> <div><p className="renwuxiangqdivtest ml24">示例</p></div>
|
||||||
|
</div>
|
||||||
|
<div className="renwuxiangssit xaxisreverseorder"><div className="challenbaocun" onClick={()=>this.modifyjupyter(this.props)}><p className="challenbaocuntest">应用到实训</p></div></div>
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
{
|
||||||
|
`
|
||||||
|
iframe {
|
||||||
|
border-width: 0px;
|
||||||
|
border-style: inset;
|
||||||
|
border-color: initial;
|
||||||
|
border-image: initial;
|
||||||
|
}
|
||||||
|
iframe {
|
||||||
|
border-left: 1px solid #eeeeee;
|
||||||
|
border-top: 1px solid #eeeeee;
|
||||||
|
border-right: 1px solid #eeeeee;
|
||||||
|
border-bottom: 1px solid #eeeeee;
|
||||||
|
}
|
||||||
|
#header{
|
||||||
|
visibility:hidden;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div className="mt35">
|
||||||
|
{/*https://48888.jupyter.educoder.net/tree?*/}
|
||||||
|
|
||||||
|
<div className="pb47">
|
||||||
|
{
|
||||||
|
this.props.shixunsDetails===null || this.props.shixunsDetails===undefined||JSON.stringify(this.props.shixunsDetails)==="{}"?
|
||||||
|
""
|
||||||
|
:
|
||||||
|
(
|
||||||
|
this.props&&this.props.shixunsDetails&&this.props.shixunsDetails.jupyter_url?
|
||||||
|
<iframe src={this.props.shixunsDetails.jupyter_url}
|
||||||
|
sandbox="allow-same-origin allow-scripts allow-top-navigation " scrolling="no" id="frame"
|
||||||
|
name="framename" width="100%" height="700" frameBorder="0"
|
||||||
|
></iframe>
|
||||||
|
:""
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</React.Fragment>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Challengesjupyter;
|
@ -0,0 +1,121 @@
|
|||||||
|
.tpmborder{
|
||||||
|
border: 1px solid;
|
||||||
|
}
|
||||||
|
/* 中间居中 */
|
||||||
|
.intermediatecenter{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
/* 简单居中 */
|
||||||
|
.intermediatecenterysls{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.spacearound{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
|
||||||
|
}
|
||||||
|
.spacebetween{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
/* 头顶部居中 */
|
||||||
|
.topcenter{
|
||||||
|
display: -webkit-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* x轴正方向排序 */
|
||||||
|
/* 一 二 三 四 五 六 七 八 */
|
||||||
|
.sortinxdirection{
|
||||||
|
display: flex;
|
||||||
|
flex-direction:row;
|
||||||
|
}
|
||||||
|
/* x轴反方向排序 */
|
||||||
|
/* 八 七 六 五 四 三 二 一 */
|
||||||
|
.xaxisreverseorder{
|
||||||
|
display: flex;
|
||||||
|
flex-direction:row-reverse;
|
||||||
|
}
|
||||||
|
/* 垂直布局 正方向*/
|
||||||
|
/* 一
|
||||||
|
二
|
||||||
|
三
|
||||||
|
四
|
||||||
|
五
|
||||||
|
六
|
||||||
|
七
|
||||||
|
八 */
|
||||||
|
.verticallayout{
|
||||||
|
display: flex;
|
||||||
|
flex-direction:column;
|
||||||
|
}
|
||||||
|
/* 垂直布局 反方向*/
|
||||||
|
.reversedirection{
|
||||||
|
display: flex;
|
||||||
|
flex-direction:column-reverse;
|
||||||
|
}
|
||||||
|
.deletebutom{
|
||||||
|
width:85px;
|
||||||
|
height:30px;
|
||||||
|
background:#C4C4C4;
|
||||||
|
border-radius:3px;
|
||||||
|
}
|
||||||
|
.deletebutomtext{
|
||||||
|
width:28px;
|
||||||
|
height:19px;
|
||||||
|
font-size:14px;
|
||||||
|
color:#FFFFFF;
|
||||||
|
line-height:19px;
|
||||||
|
}
|
||||||
|
.deletebuttom{
|
||||||
|
width:85px;
|
||||||
|
height:30px;
|
||||||
|
background:#29BD8B;
|
||||||
|
border-radius:3px;
|
||||||
|
}
|
||||||
|
.deletebuttomtest{
|
||||||
|
width:56px;
|
||||||
|
height:19px;
|
||||||
|
font-size:14px;
|
||||||
|
color:#FFFFFF;
|
||||||
|
line-height:19px;
|
||||||
|
}
|
||||||
|
.tpmwidth{
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.mr21{
|
||||||
|
margin-right: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wenjiantit{
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
.zuihoushijian{
|
||||||
|
width: 125px;
|
||||||
|
}
|
||||||
|
.zuihouxiugairen{
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
.wenjiandaxiao{
|
||||||
|
width: 56px;
|
||||||
|
}
|
||||||
|
.deletebutomtextcode{
|
||||||
|
width:85px;
|
||||||
|
height:30px;
|
||||||
|
background:#FF5555;
|
||||||
|
border-radius:3px;
|
||||||
|
}
|
||||||
|
.light-row{
|
||||||
|
background: #F7F7F8;
|
||||||
|
}
|
||||||
|
.dark-row{
|
||||||
|
background: #FFFFFF;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue