Merge remote-tracking branch 'origin/dev_jupyter' into dev_jupyter

chromesetting
杨树明 5 years ago
commit 09ada81439

@ -327,7 +327,7 @@ module.exports = {
},
compress: {
drop_debugger: true,
drop_console: false
drop_console: true
}
}
}),

@ -617,7 +617,11 @@ class App extends Component {
{/* jupyter */}
<Route path="/tasks/:identifier/jupyter/"
component={JupyterTPI}
render={
(props) => {
return (<JupyterTPI {...this.props} {...props} {...this.state}/>)
}
}
/>
<Route path="/tasks/:stageId" component={IndexWrapperComponent}/>

@ -4,12 +4,12 @@
* @Github:
* @Date: 2019-12-10 09:03:48
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-10 09:05:41
* @LastEditTime: 2019-12-12 10:53:47
*/
import { Icon } from 'antd';
const MyIcon = Icon.createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_1535266_ss6796i6f6j.js'
scriptUrl: '//at.alicdn.com/t/font_1535266_i4ilpm93kp.js'
});
export default MyIcon;

@ -314,12 +314,14 @@ class TPMDataset extends Component {
}
deleteRemovedata(){
if(this.state.selectedRowKeysdata===undefined || this.state.selectedRowKeysdata===null ||this.state.selectedRowKeysdata.length===0){
this.props.showNotification(`请选择要删除的文件`);
return
}
confirm({
title: '确定要删除文件吗?',
okText: '确定',

@ -4,46 +4,164 @@
* @Github:
* @Date: 2019-12-11 08:35:23
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 09:26:17
* @LastEditTime: 2019-12-12 18:00:03
*/
import './index.scss';
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import SplitPane from 'react-split-pane';
import { Button } from 'antd';
import { Button, Modal } from 'antd';
import {
connect
} from 'react-redux';
import UserInfo from '../../developer/components/userInfo';
import actions from '../../../redux/actions';
import LeftPane from './leftPane';
import RightPane from './rightPane';
function JupyterTPI (props) {
// 获取 identifier 值
const {
match: {
params = {}
},
url,
loading, // 保存按钮状态
jupyter_info,
getJupyterInfo,
syncJupyterCode,
jupyter_tpi_url_state,
// getJupyterTpiDataSet,
getJupyterTpiUrl,
saveJupyterTpi,
changeLoadingState,
changeGetJupyterUrlState
} = props;
const {identifier} = params;
const [userInfo, setUserInfo] = useState({});
const [jupyterInfo, setJupyterInfo] = useState({});
const [updateTip, setUpdateTip] = useState(true);
const [myIdentifier, setMyIdentifier] = useState('');
useEffect(() => {
// 获取数据集
/* jupyter TPI
* 获取 用户信息,
* 实训的 identifier, 状态 名称 是否被修改等信息
*/
getJupyterInfo(identifier);
}, [identifier]);
useEffect(() => {
// 设置jupyter信息
setJupyterInfo(jupyter_info || {});
const {user, tpm_modified, myshixun_identifier} = jupyter_info;
if (user) {
setUserInfo(user);
}
if (myshixun_identifier) {
setMyIdentifier(myshixun_identifier);
}
// 同步代码
if (tpm_modified && updateTip && myshixun_identifier) {
setUpdateTip(false);
Modal.confirm({
title: '更新通知',
content: (<div className="update_notice">
<p className="update_txt">关卡任务的代码文件有更新啦</p>
<p className="update_txt">更新操作将保留已完成的评测记录和成绩</p>
<p className="update_txt">还未完成评测的任务代码请自行保存</p>
</div>),
okText: '确定',
cancelText: '取消',
onOk () {
syncJupyterCode(myshixun_identifier, '同步成功');
}
})
}
}, [props]);
// 重置实训
const handleClickResetTpi = () => {
Modal.confirm({
title: '重置实训',
content: (
<p style={{ lineHeight: '24px' }}>
你在本文件中修改的内容将丢失,<br />
是否确定重新加载初始代码
</p>
),
okText: '确定',
cancelText: '取消',
onOk () {
console.log('调用重置代码....', myIdentifier);
if (myIdentifier) {
syncJupyterCode(myIdentifier, '重置成功');
}
}
})
}
// 退出实训
const handleClickQuitTpi = () => {
// console.log(jupyterInfo);
const { identifier } = jupyterInfo;
props.history.push(`/shixuns/${identifier}/challenges`);
}
// 重新获取 jupyter url
const handleOnReloadUrl = (id) => {
// console.log('jupyter 信息: ', jupyterInfo);
// 改变加载状态值
changeGetJupyterUrlState(-1);
getJupyterTpiUrl({identifier: myIdentifier});
}
// 保存代码
const handleOnSave = () => {
// 改变按钮状态
changeLoadingState(true);
saveJupyterTpi();
}
// 获取jupyter地址
}, []);
return (
<div className="jupyter_area">
<div className="jupyter_header">
<UserInfo userInfo={{}} />
<UserInfo userInfo={userInfo} />
<p className="jupyter_title">
<span className="title_desc">MySQL数据库编程开发实训(基础篇)</span>
<span className="title_time">时间</span>
<span className="title_desc" style={{ marginTop: '20px' }}>{jupyterInfo.name}</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>
<Button
className="btn_common"
type="link"
icon="sync"
onClick={handleClickResetTpi}
>重置实训</Button>
<Button
className="btn_common"
type="link"
icon="poweroff"
onClick={handleClickQuitTpi}
>退出实训</Button>
</p>
</div>
<div className="jupyter_ctx">
<SplitPane split="vertical" minSize={350} maxSize={-350} defaultSize="30%">
<div className={'split-pane-left'}>
左侧内容
<LeftPane dataSets={[]} />
</div>
<SplitPane split="vertical" defaultSize="100%" allowResize={false}>
<div>右侧内容</div>
<RightPane
identifier={myIdentifier}
status={jupyter_tpi_url_state}
url={url}
loading={loading}
onReloadUrl={handleOnReloadUrl}
onSave={handleOnSave}
/>
<div />
</SplitPane>
</SplitPane>
@ -53,17 +171,31 @@ function JupyterTPI (props) {
}
const mapStateToProps = (state) => {
const {jupyter_tpi_url, jupyter_data_set, jupyter_identifier} = state.jupyterReducer;
const {
jupyter_info,
jupyter_tpi_url,
jupyter_data_set,
jupyter_tpi_url_state
} = state.jupyterReducer;
const { loading } = state.commonReducer;
return {
loading,
jupyter_info,
url: jupyter_tpi_url,
dataSets: jupyter_data_set,
identifier: jupyter_identifier
jupyter_tpi_url_state
};
}
const mapDispatchToProps = (dispatch) => ({
getJupyterTpiDataSet: (identifier) => dispatch(actions.getJupyterTpiDataSet(identifier)),
getJupyterTpiUrl: (identifier) => dispatch(actions.getJupyterTpiUrl(identifier))
changeGetJupyterUrlState: (status) => dispatch(actions.changeGetJupyterUrlState(status)),
getJupyterInfo: (identifier) => dispatch(actions.getJupyterInfo(identifier)),
// 重置代码
syncJupyterCode: (identifier, msg) => dispatch(actions.syncJupyterCode(identifier, msg)),
// getJupyterTpiDataSet: (identifier) => dispatch(actions.getJupyterTpiDataSet(identifier)),
getJupyterTpiUrl: (identifier) => dispatch(actions.getJupyterTpiUrl(identifier)),
saveJupyterTpi: () => dispatch(actions.saveJupyterTpi()),
changeLoadingState: (flag) => dispatch(actions.changeLoadingState(flag))
});
export default connect(

@ -55,7 +55,7 @@
height: 60px;
line-height: 60px;
background-color: #070F1A;
padding-left: 30px;
.jupyter_title{
display: flex;
flex-direction: column;
@ -90,4 +90,12 @@
position: relative;
height: calc(100vh - 60px);
}
.update_notice{
text-align: center;
.update_txt{
line-height: 18px;
font-size: 14px;
}
}
}

@ -0,0 +1,55 @@
/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-12-12 10:34:03
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 11:22:11
*/
import './index.scss';
import React from 'react';
import {Icon, Empty} from 'antd';
import MyIcon from '../../../../common/components/MyIcon';
function LeftPane (props) {
// 获取数据集
const { dataSets = [] } = props;
// 渲染数据集
const renderList = () => {
// 空数据
if (dataSets.length === 0) {
return <div className="jupyter_empty">
<Empty />
</div>
} else {
// 渲染列表
const oList = dataSets.map((item, i) => {
return (
<li className="jupyter_item" key={`key_${i}`}>
<Icon type="file-text" className="jupyter_icon"/>
<span className="jupyter_name">{item.title}</span>
</li>
);
});
return (
<ul className="jupyter_data_list">
{ oList }
</ul>
);
}
}
return (
<div className="jupyter_data_sets_area">
<h2 className="jupyter_h2_title">
<MyIcon type="iconwenti" className="jupyter_data_icon"/> 数据集
</h2>
{renderList()}
</div>
)
}
export default LeftPane;

@ -0,0 +1,50 @@
.jupyter_data_sets_area{
height: 100%;
.jupyter_h2_title{
height: 50px;
line-height: 50px;
background-color: #EEEEEE;
padding: 0 30px;
.jupyter_data_icon{
color: #7286ff;
font-size: 24px;
position: relative;
top: 2px;
transform: scale(1.5);
}
}
.jupyter_data_list,
.jupyter_empty{
height: calc(100vh - 110px);
}
.jupyter_data_list{
.jupyter_item{
line-height:45px;
border-bottom: 1px solid rgba(238,238,238, 1);
padding: 0 30px 0 60px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
cursor: pointer;
.jupyter_icon{
color: rgb(74, 188, 125);
font-size: 16px;
transform: scale(1.2);
margin-right: 5px;
}
.jupyter_name{
color: #000;
font-size: 16px;
}
}
}
.jupyter_empty{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
}

@ -0,0 +1,90 @@
/*
* @Description:
* @Author: tangjiang
* @Github:
* @Date: 2019-12-12 15:04:20
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 17:41:41
*/
import './index.scss';
import React, { useEffect, useState } from 'react';
import { Spin, Button } from 'antd';
function RightPane (props) {
const {
status,
url,
onReloadUrl,
onSave,
loading
} = props;
const [renderCtx, setRenderCtx] = useState(() => loadInit);
// 重新获取 url
const handleClickReload = () => {
onReloadUrl && onReloadUrl();
}
const loadInit = (
<div className="jupyter_loading_init">
<Spin tip="加载中..."></Spin>
</div>
);
const loadError = (
<div className="jupyter_load_url_error">
<p className="jupyter_error_txt">
加载实训出错是否
<span
className="jupyter_reload"
onClick={handleClickReload}
>重新加载</span>
</p>
</div>
);
// 保存
const handleClickSubmit = () => {
console.log('调用了保存接口....');
onSave && onSave();
}
useEffect(() => {
if (status === -1) {
setRenderCtx(() => loadInit);
} else if (status === 0 && url) {
setRenderCtx(() => (
<div className="jupyter_result">
<div className="jupyter_iframe">
<iframe
title=" "
width="100%"
height="100%"
src={url}
className='jupyter_iframe_style'
></iframe>
</div>
<div className="jupyter_submit">
<Button
loading={loading}
type="primary"
onClick={handleClickSubmit}
>保存</Button>
</div>
</div>
));
} else {
setRenderCtx(() => loadError);
}
}, [status, url, loading]);
return (
<div className="jupyter_right_pane_area">
{ renderCtx }
</div>
)
}
export default RightPane;

@ -0,0 +1,62 @@
.jupyter_right_pane_area{
position: relative;
height: calc(100vh - 60px);
// background: pink;
.jupyter_load_url_error,
.jupyter_loading_init{
display: flex;
position: relative;
align-items: center;
justify-content: center;
height: 100%;
&::before{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
content: '';
}
}
.jupyter_loading_init{
&::before{
background-color: rgba(0,0,0,.2);
}
}
.jupyter_load_url_error{
// &::before{
// background-color: rgba(0,0,0,.2);
// }
.jupyter_error_txt{
position: relative;
z-index: 1;
.jupyter_reload{
cursor: pointer;
color: #1890ff;
}
}
}
.jupyter_result{
height: 100%;
.jupyter_iframe{
height: calc(100% - 56px);
// background: pink;
.jupyter_iframe_style{
border: none;
outline: none;
}
}
.jupyter_submit{
display: flex;
align-items: center;
height: 56px;
justify-content: flex-end;
padding-right: 30px;
}
}
}

@ -34,6 +34,8 @@ class Challengesjupyter extends Component {
jupyter_port:0,
jupyter_url:null,
username:"",
booljupyterurls:false,
loading:false,
}
}
@ -54,41 +56,35 @@ class Challengesjupyter extends Component {
}
}
}).catch((error) => {
console.log(error)
//console.log(error)
});
}
componentDidMount() {
setTimeout(this.ChallengesList(), 1000);
let id = this.props.match.params.shixunId;
let ChallengesURL = `/jupyters/get_info_with_tpm.json`;
let datas={
identifier:id,
}
axios.get(ChallengesURL, {params: datas}).then((response) => {
debugger
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
// console.log("componentDidMountChallengesjupyter");
// console.log(response.data);
if(response.data.status===0){
this.setState({
jupyter_url:response.data.url,
jupyter_port:response.data.port,
})
}else{
}
}
this.setState({
booljupyterurls:true,
})
}).catch((error) => {
console.log(error)
this.setState({
booljupyterurls:true,
})
});
@ -96,7 +92,36 @@ class Challengesjupyter extends Component {
}
updatamakedown = (id) => {
updatamakedowns = () => {
this.setState({
loading:true,
})
let id = this.props.match.params.shixunId;
let ChallengesURL = `/jupyters/get_info_with_tpm.json`;
let datas={
identifier:id,
}
axios.get(ChallengesURL, {params: datas}).then((response) => {
if (response.data.status === 403||response.data.status === 401||response.data.status === 500) {
}else{
if(response.data.status===0){
this.setState({
jupyter_url:response.data.url,
jupyter_port:response.data.port,
})
}else{
}
}
this.setState({
booljupyterurls:true,
loading:false,
})
}).catch((error) => {
this.setState({
booljupyterurls:true,
loading:false,
})
});
}
@ -148,8 +173,8 @@ class Challengesjupyter extends Component {
};
modifyjupyter=()=>{
// console.log("propsysl");
// console.log(propsysl);
// //console.log("propsysl");
// //console.log(propsysl);
let id=this.props.match.params.shixunId;
var jupyter_port="";
try{
@ -173,16 +198,16 @@ class Challengesjupyter extends Component {
}
sendToken=()=>{
// console.log("sendToken");
// //console.log("sendToken");
// const iframe = document.getElementById('iframe');
// console.log("modifyjupyter");
// //console.log("modifyjupyter");
// const frameWindow = iframe.contentWindow;
// console.log("frameWindow");
// console.log(frameWindow);
// //console.log("frameWindow");
// //console.log(frameWindow);
}
render() {
let{ChallengesDataList}=this.state;
let{ChallengesDataList,booljupyterurls}=this.state;
let id = this.props.match.params.shixunId;
// var deptObjs=document.getElementById("IFRAMEID").contentWindow.document.getElementById("TAGID");
// //判断此元素是否存在
@ -201,7 +226,7 @@ class Challengesjupyter extends Component {
// window.onload=()=>{
// debugger
// var _iframe = document.getElementById('header');
// console.log(_iframe);
// //console.log(_iframe);
// // .contentWindow.document.getElementById('shutdown_widget') //get iframe下的id
// // _iframe.style.display= "none"; //修改样式
// }
@ -213,6 +238,7 @@ class Challengesjupyter extends Component {
return (
<React.Fragment>
<div className="mt30 pl20 pr20" >
<Spin spinning={this.state.loading}>
<p className="clearfix mb20">
<span className="font-16 fl">简介</span>
<Tooltip placement="bottom" title={"编辑"}>
@ -231,6 +257,23 @@ class Challengesjupyter extends Component {
<div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML(ChallengesDataList.description).replace(/▁/g,"▁▁▁")}}></div>
}
</p>
{
booljupyterurls===true?
(
this.state.jupyter_url === null?
<div className="mt50">
<p className="intermediatecenter sortinxdirection"><p className="colorbluetest">加载实训出错是否</p><p className="colorbluetwo" onClick={()=>this.updatamakedowns()}></p></p>
</div>
:""
)
:""
}
<style>
{
`
@ -299,8 +342,6 @@ class Challengesjupyter extends Component {
{
is_teacher===true?
<div className="mt35">
{/*https://48888.jupyter.educoder.net/tree?*/}
<div className="pb47">
{
this.state.jupyter_url===null || this.state.jupyter_url===undefined?
@ -316,6 +357,7 @@ class Challengesjupyter extends Component {
:""
}
</div>
</Spin>
</div>
</React.Fragment>

@ -64,3 +64,13 @@
.pb47{
padding-bottom: 47px;
}
.colorbluetwo{
color: #1E8FFD;
font-size: 12px;
cursor:pointer;
}
.colorbluetest{
color: #06101A;
font-size: 12px;
cursor:default
}

@ -54,6 +54,9 @@ const types = {
GET_JUPYTER_DATA_SETS: 'GET_JUPYTER_DATA_SETS', // jupyter 数据集
GET_JUPYTER_TPI_URL: 'GET_JUPYTER_TPI_URL', // 获取 jupyter url
SAVE_JUPYTER_IDENTIFIER: 'SAVE_JUPYTER_IDENTIFIER', // 保存jupyter identifier
SAVE_JUPYTER_INFO: 'SAVE_JUPYTER_INFO', // 保存 jupyter 信息
CHANGE_JUPYTER_URL_STATE: 'CHANGE_JUPYTER_URL_STATE', // 获取url返回的状态值
SAVE_JUPYTER_TPI: 'SAVE_JUPYTER_TPI', // 保存 jupyter tpi
}
export default types;

@ -64,7 +64,11 @@ import {
import {
getJupyterTpiDataSet,
getJupyterTpiUrl
getJupyterTpiUrl,
getJupyterInfo,
syncJupyterCode,
changeGetJupyterUrlState,
saveJupyterTpi
} from './jupyter';
export default {
@ -111,6 +115,10 @@ export default {
saveEditorCodeForDetail,
// jupyter
getJupyterTpiDataSet,
getJupyterTpiUrl
getJupyterTpiUrl,
getJupyterInfo,
syncJupyterCode,
changeGetJupyterUrlState,
saveJupyterTpi
// isUpdateCodeCtx
}

@ -4,31 +4,81 @@
* @Github:
* @Date: 2019-12-12 09:01:30
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 09:30:53
* @LastEditTime: 2019-12-12 17:58:38
*/
import types from "./actionTypes";
import { fetchJupyterTpiDataSet, fetchJupyterTpiUrl } from "../../services/jupyterServer";
import { message } from 'antd';
import {
fetchJupyterTpiDataSet,
fetchJupyterTpiUrl,
fetchJupyterInfo,
fetchSyncJupyterCode,
fetchSaveJupyterTpi
} from "../../services/jupyterServer";
// 获取 jupyter 相关信息
export const getJupyterInfo = (id) => {
return (dispatch) => {
fetchJupyterInfo(id).then(res => {
if (res.data.status === 401) return;
if (res.status === 200) {
const { data } = res;
console.log(data);
if (data.status === 0) {
dispatch({
type: types.SAVE_JUPYTER_INFO,
payload: data
});
const { identifier, myshixun_identifier } = data;
// 调用获取数据集接口
dispatch(getJupyterTpiDataSet(identifier));
// 调用获取url接口
dispatch(getJupyterTpiUrl({identifier: myshixun_identifier}));
}
}
})
}
}
// 获取 jupyter tpi 数据集
export const getJupyterTpiDataSet = (identifier) => {
return (dispatch) => {
fetchJupyterTpiDataSet(identifier).then(res => {
if (res.data.status === 401) return; // 用户未登录
console.log('数据集:', res);
if (res.status === 200) {
const {data_sets} = res.data;
dispatch({
type: types.GET_JUPYTER_DATA_SETS,
payload: data_sets
});
}
});
}
}
// 获取 jupyter tpi 地址
export const getJupyterTpiUrl = (identifier) => {
return (dispatch) => {
fetchJupyterTpiUrl(identifier).then(res => {
export const getJupyterTpiUrl = (obj) => {
return (dispatch, getState) => {
const {jupyter_info} = getState().jupyterReducer;
console.log(obj.identifier, jupyter_info.myshixun_identifier);
if (!obj.identifier && !jupyter_info.myshixun_identifier) return;
const id = obj.identifier || jupyter_info.myshixun_identifier;
fetchJupyterTpiUrl({identifier: id}).then(res => {
if (res.data.status === 401) return; // 用户未登录
console.log('获取url', res);
if (res.status === 200) {
const { status, url = '', port } = res.data;
dispatch({
type: types.GET_JUPYTER_TPI_URL,
payload: {
status,
url,
port
}
})
}
})
}
}
// 保存 jupyter identifer
export const saveJupyterIdentifier = (identifier) => {
return {
@ -36,3 +86,54 @@ export const saveJupyterIdentifier = (identifier) => {
payload: identifier
}
}
// 重置代码
export const syncJupyterCode = (identifier, msg) => {
return (dispatch) => {
fetchSyncJupyterCode(identifier).then(res => {
// console.log('同步代码成功: ', res);
if (res.data.status === 401) return;
if (res.status === 200) {
const {status} = res.data
if (status === 0) message.success(msg);
}
})
}
}
// 改变状态值
export const changeGetJupyterUrlState = (status) => {
return {
type: types.CHANGE_JUPYTER_URL_STATE,
payload: status
}
}
// 保存 jupyter tpi
export const saveJupyterTpi = () => {
return (dispatch, getState) => {
const { jupyter_tpi_code, jupyter_info }= getState().jupyterReducer;
// console.log(jupyter_info.myshixun_identifier, jupyter_tpi_code);
if (!jupyter_info.myshixun_identifier) return;
const params = {
identifier: jupyter_info.myshixun_identifier,
jupyter_port: jupyter_tpi_code
};
console.log(params);
fetchSaveJupyterTpi(params).then(res => {
dispatch({
type: types.LOADING_STATUS,
payload: false
});
if (res.status === 200) {
const { data } = res;
if (data.status === 0) {
message.success('保存成功!')
}
}
}).catch(() => {
dispatch({
type: types.LOADING_STATUS,
payload: false
});
});
}
}

@ -4,7 +4,7 @@
* @Github:
* @Date: 2019-11-27 16:27:09
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-03 11:00:19
* @LastEditTime: 2019-12-12 17:36:51
*/
import types from "../actions/actionTypes";

@ -4,14 +4,17 @@
* @Github:
* @Date: 2019-12-12 09:01:39
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 09:29:49
* @LastEditTime: 2019-12-12 17:23:54
*/
import types from "../actions/actionTypes";
const initState = {
jupyter_tpi_url: '',
jupyter_info: {}, // 保存用户信息及实训相关的内容
jupyter_data_set: [],
jupyter_identifier: ''
jupyter_identifier: '',
jupyter_tpi_url_state: -1, // 获取 url 状态值: 0 成功, 其它 失败
jupyter_tpi_code: '' // 端口号
};
const JupyterReducer = (state = initState, action) => {
@ -22,15 +25,28 @@ const JupyterReducer = (state = initState, action) => {
jupyter_data_set: action.payload
}
case types.GET_JUPYTER_TPI_URL:
const {url, status, port} = action.payload;
return {
...state,
jupyter_tpi_url: action.payload
jupyter_tpi_url: url,
jupyter_tpi_url_state: status,
jupyter_tpi_code: port
}
case types.SAVE_JUPYTER_IDENTIFIER:
return {
...state,
jupyter_identifier: action.payload
}
case types.SAVE_JUPYTER_INFO:
return {
...state,
jupyter_info: action.payload
}
case types.CHANGE_JUPYTER_URL_STATE:
return {
...state,
jupyter_tpi_url_state: action.payload
}
default:
return {
...state

@ -4,10 +4,15 @@
* @Github:
* @Date: 2019-12-12 09:07:07
* @LastEditors: tangjiang
* @LastEditTime: 2019-12-12 09:10:58
* @LastEditTime: 2019-12-12 17:46:17
*/
import axios from 'axios';
// 获取 jupyter实训相关的内容
export async function fetchJupyterInfo (identifier) {
const url = `/tasks/${identifier}/jupyter.json`;
return axios.get(url);
}
// 获取数据集
export async function fetchJupyterTpiDataSet (identifier) {
const url = `/shixuns/${identifier}/jupyter_data_sets.json`;
@ -18,3 +23,13 @@ export async function fetchJupyterTpiUrl (params) {
const url = `/jupyters/get_info_with_tpi.json`;
return axios.get(url, { params });
}
// 同步代码功能
export async function fetchSyncJupyterCode (identifier) {
const url = `/myshixuns/${identifier}/sync_code.json`;
return axios.post(url);
}
// jupyter 保存
export async function fetchSaveJupyterTpi (params) {
const url = `/jupyters/save_with_tpi.json`;
return axios.get(url, { params });
}
Loading…
Cancel
Save