Merge branches 'dev_aliyun', 'develop' and 'jupyter' of https://bdgit.educoder.net/Hjqreturn/educoder into jupyter
commit
a2ab39335f
@ -1,4 +1,6 @@
|
||||
class ShixunServiceConfig < ApplicationRecord
|
||||
belongs_to :shixun
|
||||
belongs_to :mirror_repository
|
||||
|
||||
validates_presence_of :shixun_id, :mirror_repository_id
|
||||
end
|
||||
|
@ -0,0 +1,104 @@
|
||||
class CreateShixunService < ApplicationService
|
||||
attr_reader :user, :params, :permit_params
|
||||
|
||||
def initialize(user, permit_params, params)
|
||||
@user = user
|
||||
@params = params
|
||||
@permit_params = permit_params
|
||||
end
|
||||
|
||||
def call
|
||||
shixun = Shixun.new(permit_params)
|
||||
identifier = Util::UUID.generate_identifier(Shixun, 8)
|
||||
shixun.identifier= identifier
|
||||
shixun.user_id = user.id
|
||||
main_mirror = MirrorRepository.find params[:main_type]
|
||||
sub_mirrors = MirrorRepository.where(id: params[:sub_type])
|
||||
ActiveRecord::Base.transaction do
|
||||
shixun.save!
|
||||
# 获取脚本内容
|
||||
shixun_script = get_shixun_script(shixun, main_mirror, sub_mirrors)
|
||||
# 创建额外信息
|
||||
ShixunInfo.create!(shixun_id: shixun.id, evaluate_script: shixun_script, description: params[:description])
|
||||
# 创建合作者
|
||||
shixun.shixun_members.create!(user_id: user.id, role: 1)
|
||||
# 创建镜像
|
||||
ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id)
|
||||
# 创建主服务配置
|
||||
ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => main_mirror.id)
|
||||
# 创建子镜像相关数据(实训镜像关联表,子镜像服务配置)
|
||||
sub_mirrors.each do |sub|
|
||||
ShixunMirrorRepository.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id)
|
||||
# 实训子镜像服务配置
|
||||
name = sub.name #查看镜像是否有名称,如果没有名称就不用服务配置
|
||||
ShixunServiceConfig.create!(:shixun_id => shixun.id, :mirror_repository_id => sub.id) if name.present?
|
||||
end
|
||||
# 创建版本库
|
||||
repo_path = repo_namespace(user.login, shixun.identifier)
|
||||
GitService.add_repository(repo_path: repo_path)
|
||||
shixun.update_column(:repo_name, repo_path.split(".")[0])
|
||||
# 如果是云上实验室,创建相关记录
|
||||
if !Laboratory.current.main_site?
|
||||
Laboratory.current.laboratory_shixuns.create!(shixun: shixun, ownership: true)
|
||||
end
|
||||
return shixun
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_shixun_script shixun, main_mirror, sub_mirrors
|
||||
if !shixun.is_jupyter?
|
||||
mirror = main_mirror.mirror_scripts
|
||||
if main_mirror.blank?
|
||||
modify_shixun_script shixun, mirror.first&.(:script)
|
||||
else
|
||||
sub_name = sub_mirrors.pluck(:type_name)
|
||||
if main_mirror.type_name == "Java" && sub_name.include?("Mysql")
|
||||
mirror.last.try(:script)
|
||||
else
|
||||
shixun_script = mirror.first&.script
|
||||
modify_shixun_script shixun, shixun_script
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def modify_shixun_script shixun, script
|
||||
if script.present?
|
||||
source_class_name = []
|
||||
challenge_program_name = []
|
||||
shixun.challenges.map(&:exec_path).each do |exec_path|
|
||||
challenge_program_name << "\"#{exec_path}\""
|
||||
if shixun.main_mirror_name == "Java"
|
||||
if exec_path.nil? || exec_path.split("src/")[1].nil?
|
||||
source = "\"\""
|
||||
else
|
||||
source = "\"#{exec_path.split("src/")[1].split(".java")[0]}\""
|
||||
end
|
||||
logger.info("----source: #{source}")
|
||||
source_class_name << source.gsub("/", ".") if source.present?
|
||||
elsif shixun.main_mirror_name.try(:first) == "C#"
|
||||
if exec_path.nil? || exec_path.split(".")[1].nil?
|
||||
source = "\"\""
|
||||
else
|
||||
source = "\"#{exec_path.split(".")[0]}.exe\""
|
||||
end
|
||||
source_class_name << source if source.present?
|
||||
end
|
||||
end
|
||||
script = if script.include?("sourceClassName") && script.include?("challengeProgramName")
|
||||
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{source_class_name.reject(&:blank?).join(" ")}\)")
|
||||
else
|
||||
script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)")
|
||||
end
|
||||
end
|
||||
return script
|
||||
end
|
||||
|
||||
# 版本库目录空间
|
||||
def repo_namespace(user, shixun_identifier)
|
||||
"#{user}/#{shixun_identifier}.git"
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,10 @@
|
||||
json.data_sets do
|
||||
json.array! @data_sets do |set|
|
||||
json.id set.id
|
||||
json.title set.title
|
||||
json.author set.author.real_name
|
||||
json.created_on set.created_on
|
||||
json.filesize number_to_human_size(set.filesize)
|
||||
end
|
||||
end
|
||||
json.data_sets_count @data_count
|
@ -1,3 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
load Gem.bin_path('bundler', 'bundle')
|
||||
#!/usr/bin/env ruby
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
load Gem.bin_path('bundler', 'bundle')
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env ruby
|
||||
APP_PATH = File.expand_path('../config/application', __dir__)
|
||||
require_relative '../config/boot'
|
||||
require 'rails/commands'
|
||||
#!/usr/bin/env ruby
|
||||
APP_PATH = File.expand_path('../config/application', __dir__)
|
||||
require_relative '../config/boot'
|
||||
require 'rails/commands'
|
||||
|
@ -1,4 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
require_relative '../config/boot'
|
||||
require 'rake'
|
||||
Rake.application.run
|
||||
#!/usr/bin/env ruby
|
||||
require_relative '../config/boot'
|
||||
|
||||
|
||||
require 'rake'
|
||||
Rake.application.run
|
||||
|
@ -0,0 +1,5 @@
|
||||
class AddIsJupyterForShixuns < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :shixuns, :is_jupyter, :boolean, :default => false
|
||||
end
|
||||
end
|
@ -0,0 +1,17 @@
|
||||
class AddIndexForShixunSecretRepositories < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
shixun_ids = ShixunSecretRepository.pluck(:shixun_id).uniq
|
||||
shixuns = Shixun.where(id: shixun_ids)
|
||||
shixuns.find_each do |shixun|
|
||||
id = shixun.shixun_secret_repository.id
|
||||
shixun_secret_repositories = ShixunSecretRepository.where(shixun_id: shixun.id).where.not(id: id)
|
||||
shixun_secret_repositories.destroy_all
|
||||
end
|
||||
|
||||
remove_index :shixun_secret_repositories, :shixun_id
|
||||
add_index :shixun_secret_repositories, :shixun_id, unique: true
|
||||
|
||||
|
||||
|
||||
end
|
||||
end
|
@ -0,0 +1,35 @@
|
||||
version: '3'
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7.17
|
||||
command: --sql-mode=""
|
||||
restart: always
|
||||
volumes:
|
||||
- ./mysql_data/:/var/lib/mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 123456789
|
||||
MYSQL_DATABASE: educoder
|
||||
|
||||
redis:
|
||||
image: redis:3.2
|
||||
container_name: redis
|
||||
restart: always
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- ./redis_data:/data
|
||||
|
||||
web:
|
||||
image: guange/educoder:latest
|
||||
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 4000 -b '0.0.0.0'"
|
||||
stdin_open: true
|
||||
tty: true
|
||||
volumes:
|
||||
- .:/app
|
||||
ports:
|
||||
- "4000:4000"
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
Binary file not shown.
@ -1,114 +1,114 @@
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'development';
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', err => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../config/env');
|
||||
|
||||
const fs = require('fs');
|
||||
const chalk = require('chalk');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const clearConsole = require('react-dev-utils/clearConsole');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const {
|
||||
choosePort,
|
||||
createCompiler,
|
||||
prepareProxy,
|
||||
prepareUrls,
|
||||
} = require('react-dev-utils/WebpackDevServerUtils');
|
||||
const openBrowser = require('react-dev-utils/openBrowser');
|
||||
const paths = require('../config/paths');
|
||||
const config = require('../config/webpack.config.dev');
|
||||
const createDevServerConfig = require('../config/webpackDevServer.config');
|
||||
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
const portSetting = require(paths.appPackageJson).port
|
||||
if ( portSetting ) {
|
||||
process.env.port = portSetting
|
||||
}
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Tools like Cloud9 rely on this.
|
||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3007;
|
||||
const HOST = process.env.HOST || '0.0.0.0';
|
||||
|
||||
if (process.env.HOST) {
|
||||
console.log(
|
||||
chalk.cyan(
|
||||
`Attempting to bind to HOST environment variable: ${chalk.yellow(
|
||||
chalk.bold(process.env.HOST)
|
||||
)}`
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
|
||||
);
|
||||
console.log(`Learn more here: ${chalk.yellow('http://bit.ly/2mwWSwH')}`);
|
||||
console.log();
|
||||
}
|
||||
|
||||
// We attempt to use the default port but if it is busy, we offer the user to
|
||||
// run on a different port. `choosePort()` Promise resolves to the next free port.
|
||||
choosePort(HOST, DEFAULT_PORT)
|
||||
.then(port => {
|
||||
if (port == null) {
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
|
||||
const appName = require(paths.appPackageJson).name;
|
||||
const urls = prepareUrls(protocol, HOST, port);
|
||||
// Create a webpack compiler that is configured with custom messages.
|
||||
const compiler = createCompiler(webpack, config, appName, urls, useYarn);
|
||||
// Load proxy config
|
||||
const proxySetting = require(paths.appPackageJson).proxy;
|
||||
console.log('-------------------------proxySetting:', proxySetting)
|
||||
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
|
||||
// Serve webpack assets generated by the compiler over a web sever.
|
||||
const serverConfig = createDevServerConfig(
|
||||
proxyConfig,
|
||||
urls.lanUrlForConfig
|
||||
);
|
||||
const devServer = new WebpackDevServer(compiler, serverConfig);
|
||||
// Launch WebpackDevServer.
|
||||
devServer.listen(port, HOST, err => {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
}
|
||||
if (isInteractive) {
|
||||
clearConsole();
|
||||
}
|
||||
console.log(chalk.cyan('Starting the development server...\n'));
|
||||
openBrowser(urls.localUrlForBrowser);
|
||||
});
|
||||
|
||||
['SIGINT', 'SIGTERM'].forEach(function(sig) {
|
||||
process.on(sig, function() {
|
||||
devServer.close();
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
'use strict';
|
||||
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.BABEL_ENV = 'development';
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
// ignoring them. In the future, promise rejections that are not handled will
|
||||
// terminate the Node.js process with a non-zero exit code.
|
||||
process.on('unhandledRejection', err => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Ensure environment variables are read.
|
||||
require('../config/env');
|
||||
|
||||
const fs = require('fs');
|
||||
const chalk = require('chalk');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const clearConsole = require('react-dev-utils/clearConsole');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const {
|
||||
choosePort,
|
||||
createCompiler,
|
||||
prepareProxy,
|
||||
prepareUrls,
|
||||
} = require('react-dev-utils/WebpackDevServerUtils');
|
||||
const openBrowser = require('react-dev-utils/openBrowser');
|
||||
const paths = require('../config/paths');
|
||||
const config = require('../config/webpack.config.dev');
|
||||
const createDevServerConfig = require('../config/webpackDevServer.config');
|
||||
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
const portSetting = require(paths.appPackageJson).port
|
||||
if ( portSetting ) {
|
||||
process.env.port = portSetting
|
||||
}
|
||||
|
||||
// Warn and crash if required files are missing
|
||||
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Tools like Cloud9 rely on this.
|
||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3007;
|
||||
const HOST = process.env.HOST || '0.0.0.0';
|
||||
|
||||
if (process.env.HOST) {
|
||||
console.log(
|
||||
chalk.cyan(
|
||||
`Attempting to bind to HOST environment variable: ${chalk.yellow(
|
||||
chalk.bold(process.env.HOST)
|
||||
)}`
|
||||
)
|
||||
);
|
||||
console.log(
|
||||
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
|
||||
);
|
||||
console.log(`Learn more here: ${chalk.yellow('http://bit.ly/2mwWSwH')}`);
|
||||
console.log();
|
||||
}
|
||||
|
||||
// We attempt to use the default port but if it is busy, we offer the user to
|
||||
// run on a different port. `choosePort()` Promise resolves to the next free port.
|
||||
choosePort(HOST, DEFAULT_PORT)
|
||||
.then(port => {
|
||||
if (port == null) {
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
|
||||
const appName = require(paths.appPackageJson).name;
|
||||
const urls = prepareUrls(protocol, HOST, port);
|
||||
// Create a webpack compiler that is configured with custom messages.
|
||||
const compiler = createCompiler(webpack, config, appName, urls, useYarn);
|
||||
// Load proxy config
|
||||
const proxySetting = require(paths.appPackageJson).proxy;
|
||||
console.log('-------------------------proxySetting:', proxySetting)
|
||||
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
|
||||
// Serve webpack assets generated by the compiler over a web sever.
|
||||
const serverConfig = createDevServerConfig(
|
||||
proxyConfig,
|
||||
urls.lanUrlForConfig
|
||||
);
|
||||
const devServer = new WebpackDevServer(compiler, serverConfig);
|
||||
// Launch WebpackDevServer.
|
||||
devServer.listen(port, HOST, err => {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
}
|
||||
if (isInteractive) {
|
||||
clearConsole();
|
||||
}
|
||||
console.log(chalk.cyan('Starting the development server...\n'));
|
||||
openBrowser(urls.localUrlForBrowser);
|
||||
});
|
||||
|
||||
['SIGINT', 'SIGTERM'].forEach(function(sig) {
|
||||
process.on(sig, function() {
|
||||
devServer.close();
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
if (err && err.message) {
|
||||
console.log(err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
export function isDev() {
|
||||
return window.location.port === "3007";
|
||||
}
|
||||
|
||||
// const isMobile
|
||||
export const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
|
||||
|
||||
// const isWeiXin = (/MicroMessenger/i.test(navigator.userAgent.toLowerCase()));
|
||||
export function isDev() {
|
||||
return window.location.port === "3007";
|
||||
}
|
||||
|
||||
// const isMobile
|
||||
export const isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
|
||||
|
||||
// const isWeiXin = (/MicroMessenger/i.test(navigator.userAgent.toLowerCase()));
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,54 +1,63 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Challenges from './shixunchild/Challenges/Challenges'
|
||||
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMChallenge extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { loadingContent, shixun, user, match
|
||||
} = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="educontent clearfix mt30 mb80">
|
||||
|
||||
<div className="with65 fl edu-back-white" >
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
></TPMNav>
|
||||
<Challenges
|
||||
{...this.props}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection
|
||||
{...this.props}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMChallenge;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Challenges from './shixunchild/Challenges/Challenges'
|
||||
import Challengesjupyter from './shixunchild/Challenges/Challengesjupyter'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMChallenge extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { loadingContent, shixun, user, match,jupyterbool,is_jupyter
|
||||
} = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="educontent clearfix mt30 mb80">
|
||||
|
||||
<div className="with65 fl edu-back-white" >
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
{
|
||||
is_jupyter===true?
|
||||
<Challengesjupyter
|
||||
{...this.props}
|
||||
/>
|
||||
:
|
||||
<Challenges
|
||||
{...this.props}
|
||||
/>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection
|
||||
{...this.props}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMChallenge;
|
||||
|
@ -1,53 +1,54 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Collaborators from './shixunchild/Collaborators/Collaborators'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMCollaborators extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="educontent clearfix mt30 mb80">
|
||||
|
||||
<div className="with65 fl edu-back-white" >
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
></TPMNav>
|
||||
<Collaborators
|
||||
{...this.props}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection
|
||||
{...this.props}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMCollaborators;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Collaborators from './shixunchild/Collaborators/Collaborators'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMCollaborators extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="educontent clearfix mt30 mb80">
|
||||
|
||||
<div className="with65 fl edu-back-white" >
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
<Collaborators
|
||||
{...this.props}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection
|
||||
{...this.props}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMCollaborators;
|
||||
|
@ -1,47 +1,47 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMCollaborators from './TPMCollaborators'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMChallengeContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.props.showShixun();
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMCollaborators
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
|
||||
>
|
||||
</TPMCollaborators>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMChallengeContainer;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMCollaborators from './TPMCollaborators'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMChallengeContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.props.showShixun();
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMCollaborators
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
>
|
||||
</TPMCollaborators>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMChallengeContainer;
|
||||
|
@ -0,0 +1,545 @@
|
||||
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: '220px',
|
||||
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) => {
|
||||
debugger
|
||||
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) => {
|
||||
debugger
|
||||
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) => {
|
||||
debugger
|
||||
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}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
|
||||
<div className="padding20 edu-back-white mt20 " style={{minHeight: '463px'}}>
|
||||
<div className="sortinxdirection">
|
||||
<div className="tpmwidth">
|
||||
<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?
|
||||
<div className="edu-table edu-back-white ysltableowss">
|
||||
<style>
|
||||
{
|
||||
`
|
||||
.ant-table-tbody{
|
||||
display:none;
|
||||
}
|
||||
.ant-table-placeholder{
|
||||
display:none;
|
||||
}
|
||||
.ant-table table {
|
||||
border-bottom: 1px solid #eeeeee !important;
|
||||
}
|
||||
|
||||
`
|
||||
}
|
||||
</style>
|
||||
<Table
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
className="mysjysltable4"
|
||||
rowSelection={rowSelection}
|
||||
rowClassName={this.rowClassName}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
<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;
|
@ -1,50 +1,50 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMForklist from './TPMForklist'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMRanking_listContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
tpmLoading: true,
|
||||
creator: {
|
||||
owner_id: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.showShixun();
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMForklist
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
|
||||
>
|
||||
</TPMForklist>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRanking_listContainer;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMForklist from './TPMForklist'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMRanking_listContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
tpmLoading: true,
|
||||
creator: {
|
||||
owner_id: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.showShixun();
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMForklist
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
>
|
||||
</TPMForklist>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRanking_listContainer;
|
||||
|
@ -1,63 +1,64 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Shixunfork_list from './shixunchild/Shixunfork_list'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMForklist extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
|
||||
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>
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
|
||||
|
||||
<Shixunfork_list/>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMForklist;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Shixunfork_list from './shixunchild/Shixunfork_list'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMForklist extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
|
||||
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}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
|
||||
|
||||
<Shixunfork_list/>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMForklist;
|
||||
|
@ -1,74 +1,75 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Propaedeutics from './shixunchild/Propaedeutics/Propaedeu_tics'
|
||||
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMPropaedeutics extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
shixunId: undefined
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
// <Comments
|
||||
// {...this.props}
|
||||
// user={_user}
|
||||
// onPaginationChange={this.onPaginationChange}
|
||||
// ></Comments>
|
||||
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.state}
|
||||
{...this.props}
|
||||
/>
|
||||
|
||||
<Propaedeutics
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMPropaedeutics;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Propaedeutics from './shixunchild/Propaedeutics/Propaedeu_tics'
|
||||
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMPropaedeutics extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
shixunId: undefined
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
// <Comments
|
||||
// {...this.props}
|
||||
// user={_user}
|
||||
// onPaginationChange={this.onPaginationChange}
|
||||
// ></Comments>
|
||||
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.state}
|
||||
{...this.props}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
/>
|
||||
|
||||
<Propaedeutics
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMPropaedeutics;
|
||||
|
@ -1,39 +1,40 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMPropaedeutics from './TPMPropaedeutics'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMPropaedeuticsComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
// tpmLoading: true,
|
||||
// creator: {
|
||||
// owner_id: ''
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMPropaedeutics
|
||||
{...this.props}
|
||||
>
|
||||
</TPMPropaedeutics>
|
||||
}
|
||||
</React.Fragment>
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMPropaedeuticsComponent ;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMPropaedeutics from './TPMPropaedeutics'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMPropaedeuticsComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
// tpmLoading: true,
|
||||
// creator: {
|
||||
// owner_id: ''
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMPropaedeutics
|
||||
{...this.props}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
>
|
||||
</TPMPropaedeutics>
|
||||
}
|
||||
</React.Fragment>
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMPropaedeuticsComponent ;
|
||||
|
@ -1,59 +1,60 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Ranking_list from './shixunchild/Ranking_list/Ranking_list'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMRanking_list extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
|
||||
// <Comments
|
||||
// {...this.props}
|
||||
// user={_user}
|
||||
// onPaginationChange={this.onPaginationChange}
|
||||
// ></Comments>
|
||||
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>
|
||||
|
||||
<Ranking_list
|
||||
{...this.props}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRanking_list;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Ranking_list from './shixunchild/Ranking_list/Ranking_list'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
class TPMRanking_list extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
|
||||
// <Comments
|
||||
// {...this.props}
|
||||
// user={_user}
|
||||
// onPaginationChange={this.onPaginationChange}
|
||||
// ></Comments>
|
||||
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}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
|
||||
<Ranking_list
|
||||
{...this.props}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRanking_list;
|
||||
|
@ -1,37 +1,40 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMRanking_list from './TPMRanking_list'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMRanking_listContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMRanking_list
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
>
|
||||
</TPMRanking_list>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRanking_listContainer;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMRanking_list from './TPMRanking_list'
|
||||
|
||||
import axios from 'axios';
|
||||
import TPMNav from "./component/TPMNav";
|
||||
|
||||
class TPMRanking_listContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMRanking_list
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
|
||||
>
|
||||
</TPMRanking_list>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRanking_listContainer;
|
||||
|
@ -1,58 +1,59 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Repository from './shixunchild/Repository/Repository'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
// import RepositoryChooseModal from './component/modal/RepositoryChooseModal'
|
||||
|
||||
class TPMRepository extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match, isContentWidth100
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="tpmComment educontent clearfix mt30 mb80">
|
||||
{/* 可能会影响到其他页面的样式,需要测试、协商 */}
|
||||
<div className={`${isContentWidth100 ? 'width100': 'with65'} fl edu-back-white`}
|
||||
style={{background: 'transparent'}}>
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
></TPMNav>
|
||||
{/* <RepositoryChooseModal {...this.props}></RepositoryChooseModal> */}
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
|
||||
<Repository
|
||||
{...this.props}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
{ !isContentWidth100 && <div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRepository;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import Repository from './shixunchild/Repository/Repository'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
// import RepositoryChooseModal from './component/modal/RepositoryChooseModal'
|
||||
|
||||
class TPMRepository extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match, isContentWidth100
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="tpmComment educontent clearfix mt30 mb80">
|
||||
{/* 可能会影响到其他页面的样式,需要测试、协商 */}
|
||||
<div className={`${isContentWidth100 ? 'width100': 'with65'} fl edu-back-white`}
|
||||
style={{background: 'transparent'}}>
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
{/* <RepositoryChooseModal {...this.props}></RepositoryChooseModal> */}
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
|
||||
<Repository
|
||||
{...this.props}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
{ !isContentWidth100 && <div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMRepository;
|
||||
|
@ -1,72 +1,73 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import ShixunDiscuss from './shixunchild/ShixunDiscuss/ShixunDiscuss'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
import Comments from '../comment/Comments'
|
||||
import { commentHOC } from '../comment/CommentsHOC'
|
||||
|
||||
class TPMShixunDiscuss extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// TODO 加了HOC后 mount了两次
|
||||
this.props.fetchCommentIfNotFetched &&
|
||||
this.props.fetchCommentIfNotFetched();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
|
||||
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>
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
|
||||
<Comments
|
||||
{...this.props}
|
||||
user={user}
|
||||
showHiddenButton={true}
|
||||
></Comments>
|
||||
// onPaginationChange={this.onPaginationChange}
|
||||
// <ShixunDiscuss
|
||||
// {...this.props}
|
||||
// />
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default commentHOC ( TPMShixunDiscuss );
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import './TPMShixunDiscuss.css'
|
||||
|
||||
import ShixunDiscuss from './shixunchild/ShixunDiscuss/ShixunDiscuss'
|
||||
import TPMRightSection from './component/TPMRightSection'
|
||||
import TPMNav from './component/TPMNav'
|
||||
|
||||
import Comments from '../comment/Comments'
|
||||
import { commentHOC } from '../comment/CommentsHOC'
|
||||
|
||||
class TPMShixunDiscuss extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// TODO 加了HOC后 mount了两次
|
||||
this.props.fetchCommentIfNotFetched &&
|
||||
this.props.fetchCommentIfNotFetched();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
|
||||
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}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3} style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/> :
|
||||
<Comments
|
||||
{...this.props}
|
||||
user={user}
|
||||
showHiddenButton={true}
|
||||
></Comments>
|
||||
// onPaginationChange={this.onPaginationChange}
|
||||
// <ShixunDiscuss
|
||||
// {...this.props}
|
||||
// />
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default commentHOC ( TPMShixunDiscuss );
|
||||
|
@ -1,45 +1,45 @@
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMShixunDiscuss from './TPMShixunDiscuss'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMShixunDiscussContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMShixunDiscuss
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
|
||||
>
|
||||
</TPMShixunDiscuss>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMShixunDiscussContainer;
|
||||
import React, { Component } from 'react';
|
||||
import { Redirect } from 'react-router';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import TPMShixunDiscuss from './TPMShixunDiscuss'
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
class TPMShixunDiscussContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps, newContext) {
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { tpmLoading } = this.props;
|
||||
const user = this.props.current_user;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ tpmLoading ? <div style={{ minHeight: '886px'}}></div> :
|
||||
<TPMShixunDiscuss
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
user={user}
|
||||
aboutFocus={this.props.aboutFocus}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
>
|
||||
</TPMShixunDiscuss>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TPMShixunDiscussContainer;
|
||||
|
@ -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 className="educontent mb50 edu-back-white padding10-20">
|
||||
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,316 @@
|
||||
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);
|
||||
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.status === 200) {
|
||||
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{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
var jupyter_port="";
|
||||
try{
|
||||
jupyter_port= parseInt(this.state.jupyter_port);
|
||||
}catch (e) {
|
||||
jupyter_port=this.state.jupyter_port;
|
||||
|
||||
}
|
||||
const url=`/jupyters/save_with_tpm.json`;
|
||||
const data={
|
||||
identifier:id,
|
||||
jupyter_port: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>
|
||||
{
|
||||
this.props.jupyter_url === null || this.props.jupyter_url === undefined ?
|
||||
""
|
||||
:
|
||||
<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.jupyter_url===null || this.props.jupyter_url===undefined?
|
||||
""
|
||||
:
|
||||
<iframe src={this.props.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;
|
@ -1,145 +1,146 @@
|
||||
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 axios from 'axios';
|
||||
|
||||
import TPMNav from '../../component/TPMNav'
|
||||
import TPMRightSection from '../../component/TPMRightSection'
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import { trace_collapse } from 'educoder'
|
||||
const $ = window.$;
|
||||
|
||||
// 点击按钮复制功能
|
||||
function jsCopy(){
|
||||
var e = document.getElementById("copy_rep_content");
|
||||
e.select();
|
||||
document.execCommand("Copy");
|
||||
}
|
||||
class TPMRepositoryCommits extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
RepositoryList: undefined,
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
let id = this.props.match.params.shixunId;
|
||||
|
||||
let collaborators=`/shixuns/`+id+`/commits.json`;
|
||||
axios.post(collaborators, {
|
||||
secret_repository: this.props.secret_repository_tab
|
||||
}).then((response)=> {
|
||||
|
||||
if(response.status===200){
|
||||
this.setState({
|
||||
RepositoryList: response.data
|
||||
});
|
||||
}
|
||||
trace_collapse('repo commits res', response.data)
|
||||
|
||||
}).catch((error)=>{
|
||||
console.log(error)
|
||||
});
|
||||
|
||||
}
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
let { RepositoryList } = this.state;
|
||||
return (
|
||||
<React.Fragment>
|
||||
|
||||
<div className="tpmComment educontent clearfix mt30 mb80">
|
||||
{/* 可能会影响到其他页面的样式,需要测试、协商 */}
|
||||
<div className="with65 fl edu-back-white commentsDelegateParent"
|
||||
style={{background: 'transparent'}}>
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
></TPMNav>
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3}
|
||||
style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/>
|
||||
:
|
||||
|
||||
<div className="" >
|
||||
<div className="edu-back-white font-16 mb10 clearfix padding20">
|
||||
<span className="fl"><i className="iconfont icon-tijiaojilu mr5"></i>
|
||||
提交记录
|
||||
</span>
|
||||
{/* 35 */}
|
||||
<span className="color-grey-9 fr">
|
||||
<Link to={`/shixuns/${match.params.shixunId}/repository/${match.params.repoId}`}
|
||||
className="font-14 color-grey-9">返回</Link>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
{`
|
||||
a.pullreques_name:hover {
|
||||
color: #666 !important
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<div className="edu-back-white font-16 mb10 clearfix padding20">
|
||||
<ul className="pullreques_pull_list">
|
||||
{ RepositoryList === undefined ? "" : RepositoryList.commits.map( (item, key)=>{
|
||||
return (
|
||||
<li className="clear" key={ key }>
|
||||
<a
|
||||
style={{ cursor: 'inherit' }}
|
||||
className="fl color-grey-6 font-16 pullreques_name task-hide"
|
||||
target="_blank">{item.email}</a>
|
||||
<p className="pullreques_pull_txt ml10 fl" style={{lineHeight: '32px'}}>
|
||||
{item.title}
|
||||
</p>
|
||||
<a style={{ cursor: 'inherit' }}
|
||||
className="fr mr15 color-blue">{item.time}</a>
|
||||
|
||||
<div className="cl"></div>
|
||||
</li>)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
{ RepositoryList === undefined ? "" : RepositoryList.commits.map( (item, key)=>{
|
||||
// {"email":"李暾","title":"2\n","id":"80cb6fc55a14bdd64a9c99913f416966238ed3de","time":"49年前"}
|
||||
return (
|
||||
<div>
|
||||
<div>{item.email}</div>
|
||||
<div>{item.title}</div>
|
||||
<div>{item.id}</div>
|
||||
<div>{item.time}</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
*/
|
||||
export default TPMRepositoryCommits;
|
||||
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 axios from 'axios';
|
||||
|
||||
import TPMNav from '../../component/TPMNav'
|
||||
import TPMRightSection from '../../component/TPMRightSection'
|
||||
import { CircularProgress } from 'material-ui/Progress';
|
||||
|
||||
import { trace_collapse } from 'educoder'
|
||||
const $ = window.$;
|
||||
|
||||
// 点击按钮复制功能
|
||||
function jsCopy(){
|
||||
var e = document.getElementById("copy_rep_content");
|
||||
e.select();
|
||||
document.execCommand("Copy");
|
||||
}
|
||||
class TPMRepositoryCommits extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
RepositoryList: undefined,
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
let id = this.props.match.params.shixunId;
|
||||
|
||||
let collaborators=`/shixuns/`+id+`/commits.json`;
|
||||
axios.post(collaborators, {
|
||||
secret_repository: this.props.secret_repository_tab
|
||||
}).then((response)=> {
|
||||
|
||||
if(response.status===200){
|
||||
this.setState({
|
||||
RepositoryList: response.data
|
||||
});
|
||||
}
|
||||
trace_collapse('repo commits res', response.data)
|
||||
|
||||
}).catch((error)=>{
|
||||
console.log(error)
|
||||
});
|
||||
|
||||
}
|
||||
render() {
|
||||
const { loadingContent, creator, shixun, myshixun, recommend_shixuns, current_user, watched,
|
||||
aboutFocus, user, match
|
||||
} = this.props;
|
||||
let { RepositoryList } = this.state;
|
||||
return (
|
||||
<React.Fragment>
|
||||
|
||||
<div className="tpmComment educontent clearfix mt30 mb80">
|
||||
{/* 可能会影响到其他页面的样式,需要测试、协商 */}
|
||||
<div className="with65 fl edu-back-white commentsDelegateParent"
|
||||
style={{background: 'transparent'}}>
|
||||
<TPMNav
|
||||
match={match}
|
||||
user={user}
|
||||
shixun={shixun}
|
||||
{...this.props}
|
||||
is_jupyter={this.props.is_jupyter}
|
||||
></TPMNav>
|
||||
{ loadingContent ?
|
||||
<CircularProgress size={40} thickness={3}
|
||||
style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '200px', display: 'block' }}/>
|
||||
:
|
||||
|
||||
<div className="" >
|
||||
<div className="edu-back-white font-16 mb10 clearfix padding20">
|
||||
<span className="fl"><i className="iconfont icon-tijiaojilu mr5"></i>
|
||||
提交记录
|
||||
</span>
|
||||
{/* 35 */}
|
||||
<span className="color-grey-9 fr">
|
||||
<Link to={`/shixuns/${match.params.shixunId}/repository/${match.params.repoId}`}
|
||||
className="font-14 color-grey-9">返回</Link>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
{`
|
||||
a.pullreques_name:hover {
|
||||
color: #666 !important
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<div className="edu-back-white font-16 mb10 clearfix padding20">
|
||||
<ul className="pullreques_pull_list">
|
||||
{ RepositoryList === undefined ? "" : RepositoryList.commits.map( (item, key)=>{
|
||||
return (
|
||||
<li className="clear" key={ key }>
|
||||
<a
|
||||
style={{ cursor: 'inherit' }}
|
||||
className="fl color-grey-6 font-16 pullreques_name task-hide"
|
||||
target="_blank">{item.email}</a>
|
||||
<p className="pullreques_pull_txt ml10 fl" style={{lineHeight: '32px'}}>
|
||||
{item.title}
|
||||
</p>
|
||||
<a style={{ cursor: 'inherit' }}
|
||||
className="fr mr15 color-blue">{item.time}</a>
|
||||
|
||||
<div className="cl"></div>
|
||||
</li>)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="with35 fr pl20">
|
||||
<TPMRightSection {...this.props}></TPMRightSection>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</React.Fragment>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
{ RepositoryList === undefined ? "" : RepositoryList.commits.map( (item, key)=>{
|
||||
// {"email":"李暾","title":"2\n","id":"80cb6fc55a14bdd64a9c99913f416966238ed3de","time":"49年前"}
|
||||
return (
|
||||
<div>
|
||||
<div>{item.email}</div>
|
||||
<div>{item.title}</div>
|
||||
<div>{item.id}</div>
|
||||
<div>{item.time}</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
*/
|
||||
export default TPMRepositoryCommits;
|
||||
|
@ -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: 220px;
|
||||
}
|
||||
.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