forked from Gitlink/forgeplus-react
Compare commits
45 Commits
master
...
standalone
Author | SHA1 | Date |
---|---|---|
|
465c4cc8c7 | |
|
37668ddcd4 | |
|
7102594444 | |
|
b2f2df65bb | |
|
8a577fb263 | |
|
5c491071b6 | |
|
c554237076 | |
|
d22a741bf7 | |
|
383b3f5d74 | |
|
63da7adcf9 | |
|
3243aeebc6 | |
|
1a86a75345 | |
|
3b6cc99d49 | |
|
d872ffc606 | |
|
3b69c01ead | |
|
1e0608aa14 | |
|
9b6816e346 | |
|
6ee257231d | |
|
70edb73f6c | |
|
5c7553d4aa | |
|
278701f24b | |
|
97ab819bf9 | |
|
d870f17b85 | |
|
91ac6c2357 | |
|
3702d1c1a5 | |
|
93d48c359e | |
|
80dace18e9 | |
|
375cbb37df | |
|
10d933e037 | |
|
4fdd3f6f80 | |
|
458b56e33b | |
|
c256887132 | |
|
6a588db7f6 | |
|
6c4e1c6665 | |
|
c554d2c00d | |
|
b69bf5974a | |
|
ecb1691b4d | |
|
6a9f2b31a6 | |
|
4947cd8456 | |
|
8429effe16 | |
|
49ebe450be | |
|
e3c926da77 | |
|
af48da2eb3 | |
|
6630309466 | |
|
a7c3dee7e3 |
|
@ -499,7 +499,6 @@
|
||||||
<option value="$PROJECT_DIR$/src/forge/Main/Detail.js" />
|
<option value="$PROJECT_DIR$/src/forge/Main/Detail.js" />
|
||||||
<option value="$PROJECT_DIR$/src/forge/Main/CoderRootCommit.js" />
|
<option value="$PROJECT_DIR$/src/forge/Main/CoderRootCommit.js" />
|
||||||
<option value="$PROJECT_DIR$/src/forge/Activity/ActivityItem.js" />
|
<option value="$PROJECT_DIR$/src/forge/Activity/ActivityItem.js" />
|
||||||
<option value="$PROJECT_DIR$/src/forge/Main/CoderRootDirectory.js" />
|
|
||||||
<option value="$PROJECT_DIR$/src/forge/Branch/CloneAddress.js" />
|
<option value="$PROJECT_DIR$/src/forge/Branch/CloneAddress.js" />
|
||||||
<option value="$PROJECT_DIR$/src/forge/Version/version.js" />
|
<option value="$PROJECT_DIR$/src/forge/Version/version.js" />
|
||||||
<option value="$PROJECT_DIR$/public/css/css_min_all.css" />
|
<option value="$PROJECT_DIR$/public/css/css_min_all.css" />
|
||||||
|
@ -1020,16 +1019,6 @@
|
||||||
</state>
|
</state>
|
||||||
</provider>
|
</provider>
|
||||||
</entry>
|
</entry>
|
||||||
<entry file="file://$PROJECT_DIR$/src/forge/Main/CoderRootDirectory.js">
|
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
|
||||||
<state relative-caret-position="153">
|
|
||||||
<caret line="9" column="50" lean-forward="true" selection-start-line="9" selection-start-column="50" selection-end-line="9" selection-end-column="50" />
|
|
||||||
<folding>
|
|
||||||
<element signature="n#CoderRootDirectory#0" />
|
|
||||||
</folding>
|
|
||||||
</state>
|
|
||||||
</provider>
|
|
||||||
</entry>
|
|
||||||
<entry file="file://$PROJECT_DIR$/src/modules/user/usersInfo/InfosBanner.js">
|
<entry file="file://$PROJECT_DIR$/src/modules/user/usersInfo/InfosBanner.js">
|
||||||
<provider selected="true" editor-type-id="text-editor">
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
<state relative-caret-position="192">
|
<state relative-caret-position="192">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "forge",
|
"name": "educoder",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
|
@ -3888,6 +3888,11 @@
|
||||||
"randomfill": "^1.0.3"
|
"randomfill": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"crypto-js": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw="
|
||||||
|
},
|
||||||
"crypto-random-string": {
|
"crypto-random-string": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
|
||||||
|
@ -20475,16 +20480,6 @@
|
||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"xterm": {
|
|
||||||
"version": "4.8.1",
|
|
||||||
"resolved": "https://registry.npm.taobao.org/xterm/download/xterm-4.8.1.tgz",
|
|
||||||
"integrity": "sha1-FVoXKaQ+Gom0BlJOIsVjQznjnKE="
|
|
||||||
},
|
|
||||||
"xterm-addon-fit": {
|
|
||||||
"version": "0.4.0",
|
|
||||||
"resolved": "https://registry.npm.taobao.org/xterm-addon-fit/download/xterm-addon-fit-0.4.0.tgz",
|
|
||||||
"integrity": "sha1-BuDF0KaqrPsAnvVl76HIHpPZAZM="
|
|
||||||
},
|
|
||||||
"y18n": {
|
"y18n": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||||
|
|
|
@ -111,9 +111,7 @@
|
||||||
"webpack-dev-server": "^3.10.3",
|
"webpack-dev-server": "^3.10.3",
|
||||||
"webpack-manifest-plugin": "^2.2.0",
|
"webpack-manifest-plugin": "^2.2.0",
|
||||||
"whatwg-fetch": "2.0.3",
|
"whatwg-fetch": "2.0.3",
|
||||||
"wrap-md-editor": "^0.2.20",
|
"wrap-md-editor": "^0.2.20"
|
||||||
"xterm": "4.8.1",
|
|
||||||
"xterm-addon-fit": "0.4.0"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --max_old_space_size=15360 scripts/start.js",
|
"start": "node --max_old_space_size=15360 scripts/start.js",
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 27 KiB |
|
@ -10,7 +10,7 @@ import {
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import LoginDialog from './modules/login/LoginDialog';
|
import LoginDialog from './modules/login/LoginDialog';
|
||||||
import 'babel-polyfill';
|
import 'babel-polyfill';
|
||||||
import Loading from './Loading'
|
import Loading from './Loading';
|
||||||
|
|
||||||
import Loadable from 'react-loadable';
|
import Loadable from 'react-loadable';
|
||||||
import marked from './common/marked';
|
import marked from './common/marked';
|
||||||
|
|
|
@ -2,7 +2,7 @@ import axios from 'axios';
|
||||||
import { requestProxy } from "./indexEduplus2RequestProxy";
|
import { requestProxy } from "./indexEduplus2RequestProxy";
|
||||||
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
|
||||||
import { notification } from 'antd';
|
import { notification } from 'antd';
|
||||||
|
import cookie from 'react-cookies';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
let message501 = false;
|
let message501 = false;
|
||||||
|
@ -11,8 +11,10 @@ broadcastChannelOnmessage('refreshPage', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
function locationurl(list) {
|
function locationurl(list) {
|
||||||
if (window.location.port !== "3007") {
|
if (window.location.port === "3007") {
|
||||||
window.location.href = list
|
|
||||||
|
} else {
|
||||||
|
window.location.href = list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO 开发期多个身份切换
|
// TODO 开发期多个身份切换
|
||||||
|
@ -24,22 +26,53 @@ if (isDev) {
|
||||||
parsed = queryString.parse(_search);
|
parsed = queryString.parse(_search);
|
||||||
}
|
}
|
||||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || ''
|
||||||
}
|
}
|
||||||
|
function clearAllCookie() {
|
||||||
|
cookie.remove('_educoder_session', { path: '/' });
|
||||||
|
cookie.remove('autologin_trustie', { path: '/' });
|
||||||
|
setpostcookie()
|
||||||
|
}
|
||||||
|
clearAllCookie();
|
||||||
|
function setpostcookie() {
|
||||||
|
const str = window.location.pathname;
|
||||||
|
if (str.indexOf("/wxcode") !== -1) {
|
||||||
|
cookie.remove('_educoder_session', { path: '/' });
|
||||||
|
cookie.remove('autologin_trustie', { path: '/' });
|
||||||
|
const _params = window.location.search;
|
||||||
|
if (_params) {
|
||||||
|
let _search = _params.split('?')[1];
|
||||||
|
let _educoder_sessions = _search.split('&')[0].split('=');
|
||||||
|
cookie.save('_educoder_session', _educoder_sessions[1], { domain: '.educoder.net', path: '/' });
|
||||||
|
let autologin_trusties = _search.split('&')[1].split('=');
|
||||||
|
cookie.save('autologin_trustie', autologin_trusties[1], { domain: '.educoder.net', path: '/' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setpostcookie();
|
||||||
|
|
||||||
window._debugType = debugType;
|
window._debugType = debugType;
|
||||||
export function initAxiosInterceptors(props) {
|
export function initAxiosInterceptors(props) {
|
||||||
// 判断网络是否连接
|
|
||||||
initOnlineOfflineListener();
|
initOnlineOfflineListener();
|
||||||
|
var proxy = "http://localhost:3000";
|
||||||
|
proxy = "http://192.168.1.37:3000";
|
||||||
|
|
||||||
var proxy = "https://testforgeplus.trustie.net";
|
const requestMap = {};
|
||||||
|
window.setfalseInRequestMap = function (keyName) {
|
||||||
|
requestMap[keyName] = false;
|
||||||
|
}
|
||||||
//响应前的设置
|
//响应前的设置
|
||||||
axios.interceptors.request.use(
|
axios.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
if(config.url.indexOf("http") !== -1) {
|
setpostcookie()
|
||||||
|
clearAllCookie()
|
||||||
|
|
||||||
|
if (config.url.indexOf(proxy) !== -1) {
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
requestProxy(config);
|
requestProxy(config)
|
||||||
|
|
||||||
let url = `/api${config.url}`;
|
let url = `/api${config.url}`;
|
||||||
|
|
||||||
if (`${config[0]}` !== `true`) {
|
if (`${config[0]}` !== `true`) {
|
||||||
|
@ -53,6 +86,12 @@ export function initAxiosInterceptors(props) {
|
||||||
} else {
|
} else {
|
||||||
config.url = url;
|
config.url = url;
|
||||||
}
|
}
|
||||||
|
setpostcookie();
|
||||||
|
}
|
||||||
|
if (config.url.indexOf('update_file') === -1) {
|
||||||
|
requestMap[config.url] = true;
|
||||||
|
|
||||||
|
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
|
@ -107,6 +146,8 @@ export function initAxiosInterceptors(props) {
|
||||||
message501 = false
|
message501 = false
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
requestMap[response.config.url] = false;
|
||||||
|
setpostcookie();
|
||||||
return response;
|
return response;
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
|
|
|
@ -162,28 +162,28 @@ export function getmyUrl(geturl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadActionUrl(path, goTest) {
|
export function getUploadActionUrl(path, goTest) {
|
||||||
return `${getUrl()}/api/attachments.json${isDev ?`${isDev ?`?debug=${window._debugType || 'admin'}` : ""}` : ""}`;
|
return `${getUrl()}/api/attachments.json?debug=${window._debugType || 'admin'}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadLogoActionUrl() {
|
export function getUploadLogoActionUrl() {
|
||||||
return `${getUrl()}/api/resumes/logo.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`;
|
return `${getUrl()}/api/resumes/logo.json?debug=${window._debugType || 'admin'}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadActionUrltwo(id) {
|
export function getUploadActionUrltwo(id) {
|
||||||
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUploadActionUrlthree() {
|
export function getUploadActionUrlthree() {
|
||||||
return `${getUrlmys()}/api/jupyters/import_with_tpm.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrlmys()}/api/jupyters/import_with_tpm.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getupload_git_file(id) {
|
export function getupload_git_file(id) {
|
||||||
return `${getUrlmys()}/api/shixuns/${id}/upload_git_file.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrlmys()}/api/shixuns/${id}/upload_git_file.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getUploadActionUrlOfAuth(id) {
|
export function getUploadActionUrlOfAuth(id) {
|
||||||
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
|
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json?debug=${window._debugType || 'admin'}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRandomNumber(type) {
|
export function getRandomNumber(type) {
|
||||||
|
|
|
@ -102,7 +102,7 @@ export default (({ projectsId , branch , owner , changeBranch , branchList , tag
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
return(
|
return(
|
||||||
<Popover placement='bottomLeft' visible={flag} content={menu} onClick={()=>setFlag(!flag)} overlayClassName="branch-tagBox-list">
|
<Popover placement="bottom" visible={flag} content={menu} onClick={()=>setFlag(!flag)} overlayClassName="branch-tagBox-list">
|
||||||
<div className="branch-tagBox">
|
<div className="branch-tagBox">
|
||||||
{/* {nav === 0 ?"分支":"标签"} */}
|
{/* {nav === 0 ?"分支":"标签"} */}
|
||||||
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
|
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
|
||||||
|
|
|
@ -112,9 +112,6 @@ li.ant-menu-item{
|
||||||
right:240px;
|
right:240px;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
.laterest{
|
|
||||||
color: #05690d;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1800px){
|
@media screen and (max-width: 1800px){
|
||||||
.handleBox{
|
.handleBox{
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
.ant-modal-mask{
|
|
||||||
z-index: 10000;
|
|
||||||
}
|
|
||||||
.ant-modal-wrap{
|
|
||||||
z-index: 10001;
|
|
||||||
.ant-form-explain{
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
import React , {forwardRef, useEffect} from 'react';
|
|
||||||
import { Modal , Form , Input , Button } from 'antd';
|
|
||||||
import './EAccount.scss';
|
|
||||||
|
|
||||||
function EducoderAccount({form , visible , onOk , email}){
|
|
||||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
if(email){
|
|
||||||
setFieldsValue({email})
|
|
||||||
}
|
|
||||||
},[email])
|
|
||||||
|
|
||||||
function onSure(){
|
|
||||||
validateFields((error,values)=>{
|
|
||||||
if(!error){
|
|
||||||
onOk(values);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const layout = {
|
|
||||||
labelCol: { span: 5 },
|
|
||||||
wrapperCol: { span: 18 },
|
|
||||||
};
|
|
||||||
return(
|
|
||||||
<Modal
|
|
||||||
visible={visible}
|
|
||||||
title="提示"
|
|
||||||
width="500px"
|
|
||||||
closable={false}
|
|
||||||
footer={
|
|
||||||
<Button type="primary" onClick={onSure}>确定</Button>
|
|
||||||
}
|
|
||||||
centered
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<p className="mb15 edu-txt-center" style={{maxWidth:"350px",margin:"0px auto"}}>
|
|
||||||
为确保您能正常使用平台功能,请确认以下信息:
|
|
||||||
</p>
|
|
||||||
<Form {...layout}>
|
|
||||||
<Form.Item label="邮箱">
|
|
||||||
{getFieldDecorator("email",{
|
|
||||||
rules:[{required:true,message:"请输入邮箱账号"}]
|
|
||||||
})(
|
|
||||||
<Input placeholder="请输入您的邮箱账号" width="220px"/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="密码">
|
|
||||||
{getFieldDecorator("password",{
|
|
||||||
rules:[{required:true,message:"请输入邮箱密码"}]
|
|
||||||
})(
|
|
||||||
<Input.Password placeholder="请输入您的邮箱密码" width="220px"/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Form.create()(forwardRef(EducoderAccount));
|
|
|
@ -20,13 +20,10 @@ function Releases({owner,projectsId,releaseVersions}){
|
||||||
releaseVersions && releaseVersions.total_count>0 ?
|
releaseVersions && releaseVersions.total_count>0 ?
|
||||||
releaseVersions.list.map((item,key)=>{
|
releaseVersions.list.map((item,key)=>{
|
||||||
return(
|
return(
|
||||||
key === 0 &&<AlignTop className="mt10">
|
<AlignTop className="mt10">
|
||||||
<i className="iconfont icon-biaoqian3 color-grey-6 font-18 mr10"></i>
|
<i className="iconfont icon-biaoqian3 color-grey-6 font-18 mr10"></i>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-16 color-grey-6">
|
<p className="font-16 color-grey-6"><Link to={`/projects/${owner}/${projectsId}/releases/8/update`}>{item.name}</Link></p>
|
||||||
<Link to={`/projects/${owner}/${projectsId}/releases/8/update`}>{item.name}</Link>
|
|
||||||
<span className="font-12 laterest ml5">最新</span>
|
|
||||||
</p>
|
|
||||||
<p className="color-grey-9 font-13">{item.created_at}</p>
|
<p className="color-grey-9 font-13">{item.created_at}</p>
|
||||||
</div>
|
</div>
|
||||||
</AlignTop>
|
</AlignTop>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
export default ({ url , name , column , id , login })=>{
|
|
||||||
|
export default ({ url , name , column })=>{
|
||||||
const Img = styled.span`
|
const Img = styled.span`
|
||||||
display:flex;
|
display:flex;
|
||||||
${column && "flex-direction: column;text-align:center;"}
|
${column && "flex-direction: column;text-align:center;"}
|
||||||
|
@ -19,14 +19,6 @@ export default ({ url , name , column , id , login })=>{
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return(
|
return(
|
||||||
id?
|
|
||||||
<Link to={`/users/${login}`}>
|
|
||||||
<Img>
|
|
||||||
{ url && <img src={url} alt=""/> }
|
|
||||||
<span>{name}</span>
|
|
||||||
</Img>
|
|
||||||
</Link>
|
|
||||||
:
|
|
||||||
<Img>
|
<Img>
|
||||||
{ url && <img src={url} alt=""/> }
|
{ url && <img src={url} alt=""/> }
|
||||||
<span>{name}</span>
|
<span>{name}</span>
|
||||||
|
|
|
@ -36,7 +36,8 @@ function About(props, ref) {
|
||||||
const [ disabled, setDisabled ] = useState(false);
|
const [ disabled, setDisabled ] = useState(false);
|
||||||
const [ typeFlag, setTypeFlag] = useState(false);
|
const [ typeFlag, setTypeFlag] = useState(false);
|
||||||
|
|
||||||
const AuthorLogin = props.projectDetail && props.projectDetail.author && props.projectDetail.author.login;
|
|
||||||
|
const AuthorLogin = props.author && props.author.login;
|
||||||
const CurrentLogin = props.current_user && props.current_user.login;
|
const CurrentLogin = props.current_user && props.current_user.login;
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(CurrentLogin === AuthorLogin){
|
if(CurrentLogin === AuthorLogin){
|
||||||
|
@ -55,6 +56,11 @@ function About(props, ref) {
|
||||||
setIsSpining(false);
|
setIsSpining(false);
|
||||||
if(result && result.data ){
|
if(result && result.data ){
|
||||||
setStep(result.data.step);
|
setStep(result.data.step);
|
||||||
|
// setStep(0);
|
||||||
|
// setFieldsValue({...result.data.cloud_account});
|
||||||
|
// if(result.data.cloud_account){
|
||||||
|
// setDisabled(true);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}).catch(error=>{
|
}).catch(error=>{
|
||||||
setIsSpining(false);
|
setIsSpining(false);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { Spin , Menu } from "antd";
|
import { Spin } from "antd";
|
||||||
import { FlexAJ, AlignCenter } from "../Component/layout";
|
import { FlexAJ, AlignCenter } from "../Component/layout";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import CodeSSH from './ssh/Index';
|
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
data,
|
data,
|
||||||
|
@ -18,8 +17,6 @@ export default ({
|
||||||
const [spining, setSpining] = useState(true);
|
const [spining, setSpining] = useState(true);
|
||||||
const [stage, setStage] = useState(undefined);
|
const [stage, setStage] = useState(undefined);
|
||||||
const [step, setStep] = useState(undefined);
|
const [step, setStep] = useState(undefined);
|
||||||
const [nav, setNav] = useState("0");
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSpining(rightSpin);
|
setSpining(rightSpin);
|
||||||
}, [rightSpin]);
|
}, [rightSpin]);
|
||||||
|
@ -38,7 +35,6 @@ export default ({
|
||||||
: p[0];
|
: p[0];
|
||||||
|
|
||||||
setStep(sub);
|
setStep(sub);
|
||||||
setNav("0");
|
|
||||||
if (sub && sub.status !== "skipped") {
|
if (sub && sub.status !== "skipped") {
|
||||||
getStep(pre.number, sub.number);
|
getStep(pre.number, sub.number);
|
||||||
}
|
}
|
||||||
|
@ -69,55 +65,43 @@ export default ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<Spin spinning={spining}>
|
||||||
{/* <Menu className="devopsNav" onClick={(e)=>{setNav(e.key)}} selectedKeys={[nav]} mode="horizontal">
|
<div className="rightMainContent">
|
||||||
<Menu.Item key={'0'} value="0">开发流水线</Menu.Item>
|
{data && data.status !== "error" ? (
|
||||||
<Menu.Item key={'1'} value="1">命令行</Menu.Item>
|
<div>
|
||||||
</Menu> */}
|
<FlexAJ className="items">
|
||||||
{
|
<span>{step && step.name}</span>
|
||||||
nav === "0" &&
|
<AlignCenter>
|
||||||
<Spin spinning={spining}>
|
{step && step.duration_time}
|
||||||
<div className="rightMainContent">
|
<i className="iconfont icon-sanjiaoxing-down"></i>
|
||||||
{data && data.status !== "error" ? (
|
</AlignCenter>
|
||||||
<div>
|
</FlexAJ>
|
||||||
<FlexAJ className="items">
|
<div>
|
||||||
<span>{step && step.name}</span>
|
{coders && coders.length > 0 ? (
|
||||||
<AlignCenter>
|
coders.map((item, key) => {
|
||||||
{step && step.duration_time}
|
return (
|
||||||
<i className="iconfont icon-sanjiaoxing-down"></i>
|
|
||||||
</AlignCenter>
|
|
||||||
</FlexAJ>
|
|
||||||
<div>
|
|
||||||
{coders && coders.length > 0 ? (
|
|
||||||
coders.map((item, key) => {
|
|
||||||
return (
|
|
||||||
<div className="opsDetailOut">
|
|
||||||
<span>{key + 1}</span>
|
|
||||||
<p>{item.out}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
) : empty ? (
|
|
||||||
<div className="opsDetailOut">
|
<div className="opsDetailOut">
|
||||||
<span>1</span>
|
<span>{key + 1}</span>
|
||||||
<p>
|
<p>{item.out}</p>
|
||||||
{stage && stage.name} – {step && step.name}: Skipped
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
);
|
||||||
""
|
})
|
||||||
)}
|
) : empty ? (
|
||||||
|
<div className="opsDetailOut">
|
||||||
|
<span>1</span>
|
||||||
|
<p>
|
||||||
|
{stage && stage.name} – {step && step.name}: Skipped
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
) : (
|
||||||
) : (
|
""
|
||||||
<div style={{ color: "red" }}>error:{data && data.error}</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Spin>
|
) : (
|
||||||
}
|
<div style={{ color: "red" }}>error:{data && data.error}</div>
|
||||||
{
|
)}
|
||||||
nav === "1" && <CodeSSH />
|
</div>
|
||||||
}
|
</Spin>
|
||||||
</React.Fragment>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,6 @@ function Structure(props,ref){
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
author:item.author && item.author.name,
|
author:item.author && item.author.name,
|
||||||
image_url:item.author && item.author.image_url,
|
|
||||||
message: {
|
message: {
|
||||||
branch: item.branch_target,
|
branch: item.branch_target,
|
||||||
message: item.message,
|
message: item.message,
|
||||||
|
@ -245,7 +244,7 @@ function Structure(props,ref){
|
||||||
{meg.sha && <span className="color-orange">{meg.sha}</span>}
|
{meg.sha && <span className="color-orange">{meg.sha}</span>}
|
||||||
</div>
|
</div>
|
||||||
<AlignCenter>
|
<AlignCenter>
|
||||||
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} alt="" src={`${item.image_url && getUrl(`/images/${item.image_url}`)}`} />
|
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} src={`${current_user && getUrl(`/images/${current_user.image_url}`)}`} />
|
||||||
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
|
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
|
||||||
{meg.message}
|
{meg.message}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -194,18 +194,6 @@
|
||||||
&.rightSection{
|
&.rightSection{
|
||||||
width:100%;
|
width:100%;
|
||||||
background-color: #081930;
|
background-color: #081930;
|
||||||
.devopsNav{
|
|
||||||
background-color: #111c24;
|
|
||||||
border-bottom: none;
|
|
||||||
.ant-menu-item{
|
|
||||||
color: #ccc;
|
|
||||||
padding:0px;
|
|
||||||
margin:0px 20px!important;
|
|
||||||
}
|
|
||||||
.ant-menu-item.ant-menu-item-selected{
|
|
||||||
color: #1890ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.rightMainContent{
|
.rightMainContent{
|
||||||
padding:24px 30px;
|
padding:24px 30px;
|
||||||
height:100vh;
|
height:100vh;
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
import React, { useState, useEffect } from "react";
|
|
||||||
import XmlPanel from "./XmlPanel";
|
|
||||||
import mediator from "./mediator";
|
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
// const defaulturl = `http://47.111.130.18:48088`;
|
|
||||||
const defaultValue = {
|
|
||||||
host: "106.75.231.63",
|
|
||||||
port: "2021",
|
|
||||||
ws_url: "wss://pre-webssh.educoder.net/ws",
|
|
||||||
username: "root",
|
|
||||||
secret: "Dron_123123",
|
|
||||||
};
|
|
||||||
function Index() {
|
|
||||||
const [sshConfigData, setSshConfigData] = useState(undefined);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!sshConfigData) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
mediator.publish("create-socket", 1);
|
|
||||||
}, 300);
|
|
||||||
}, [sshConfigData]);
|
|
||||||
|
|
||||||
// 获取服务器连接信息
|
|
||||||
function init() {
|
|
||||||
const url = `/api/ci/pipelines/ssh_server.json`;
|
|
||||||
axios.get(url).then(result=>{
|
|
||||||
if(result && result.data){
|
|
||||||
setSshConfigData({...result.data})
|
|
||||||
}
|
|
||||||
}).catch(error=>{})
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<XmlPanel
|
|
||||||
sshConfigData={sshConfigData||{}}
|
|
||||||
sid={1}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export default Index;
|
|
|
@ -1,219 +0,0 @@
|
||||||
import React, { useRef, useEffect, useState } from 'react';
|
|
||||||
import { Base64 } from 'js-base64';
|
|
||||||
|
|
||||||
import { Terminal } from 'xterm';
|
|
||||||
import 'xterm/css/xterm.css';
|
|
||||||
import mediator from './mediator';
|
|
||||||
import ResizeObserver from 'resize-observer-polyfill';
|
|
||||||
|
|
||||||
function getColsAndRows(width, height, term) {
|
|
||||||
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
|
|
||||||
let h = term._core._renderService.dimensions.actualCellHeight || 18;
|
|
||||||
const rows = Math.floor(height / h);
|
|
||||||
const cols = Math.floor(width / w);
|
|
||||||
return [cols, rows];
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLayout(term, el) {
|
|
||||||
const ro = new ResizeObserver(entries => {
|
|
||||||
console.log(entries);
|
|
||||||
for (let entry of entries) {
|
|
||||||
if (entry.target.offsetHeight > 0 || entry.target.offsetWidth > 0) {
|
|
||||||
const [cols, rows] = getColsAndRows(
|
|
||||||
entry.target.offsetWidth,
|
|
||||||
entry.target.offsetHeight,
|
|
||||||
term,
|
|
||||||
);
|
|
||||||
console.log('cols, rows', cols, rows);
|
|
||||||
term.resize(cols, rows);
|
|
||||||
mediator.publish('ssh-xterm-resize', {
|
|
||||||
columns: cols,
|
|
||||||
rows: rows,
|
|
||||||
width: entry.target.offsetWidth,
|
|
||||||
height: entry.target.offsetHeight,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ro.observe(el);
|
|
||||||
return ro;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TimeTicket = 30000;
|
|
||||||
|
|
||||||
//建立 websockt 来交互
|
|
||||||
//根据容器大小计算行数和列数并做到自适应
|
|
||||||
//socket 与 term 需要分开初始化 因为socket 可能重置连接
|
|
||||||
//mediator 监听消息,如果和id匹配,则建立连接,重置,或关闭连接
|
|
||||||
|
|
||||||
export default ({ sshConfigData, sid }) => {
|
|
||||||
const [term, setTerm] = useState(null);
|
|
||||||
|
|
||||||
const { ws_url, password, port, secret } = sshConfigData;
|
|
||||||
const el = useRef();
|
|
||||||
const socket = useRef();
|
|
||||||
const isFirstConnected = useRef(false);
|
|
||||||
|
|
||||||
//term init
|
|
||||||
useEffect(() => {
|
|
||||||
if (el.current && ws_url) {
|
|
||||||
const term = new Terminal({ fontSize: 16, rendererType: 'dom' });
|
|
||||||
term.open(el.current);
|
|
||||||
|
|
||||||
term.onData(data => {
|
|
||||||
if (socket.current) {
|
|
||||||
if (socket.current.readyState === 1) {
|
|
||||||
socket.current.send(JSON.stringify({ tp: 'client', data: data }));
|
|
||||||
mediator.publish('on-operating-ssh'); //有操作则自动延时
|
|
||||||
} else {
|
|
||||||
//断开连接后重连
|
|
||||||
// socket.current = null
|
|
||||||
// mediator.publish('create-socket', sid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
term.write('Connecting...');
|
|
||||||
setTerm(term);
|
|
||||||
const ro = onLayout(term, el.current);
|
|
||||||
return () => {
|
|
||||||
term.dispose();
|
|
||||||
ro.unobserve(el.current);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [ws_url, el.current]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (term && ws_url) {
|
|
||||||
function createSocket() {
|
|
||||||
const socketInstance = new WebSocket(ws_url);
|
|
||||||
socket.current = socketInstance;
|
|
||||||
|
|
||||||
socketInstance.onopen = () => {
|
|
||||||
let container = term.element.parentElement;
|
|
||||||
if (container) {
|
|
||||||
let width = container.offsetWidth;
|
|
||||||
let height = container.offsetHeight;
|
|
||||||
console.log('init', {
|
|
||||||
tp: 'init',
|
|
||||||
data: {
|
|
||||||
...sshConfigData,
|
|
||||||
secret: secret,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
rows: term.rows,
|
|
||||||
columns: term.cols,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
socketInstance.send(
|
|
||||||
JSON.stringify({
|
|
||||||
tp: 'init',
|
|
||||||
data: {
|
|
||||||
...sshConfigData,
|
|
||||||
secret: secret,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
rows: term.rows,
|
|
||||||
columns: term.cols,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
term.focus();
|
|
||||||
};
|
|
||||||
socketInstance.onerror = error => {
|
|
||||||
console.log(
|
|
||||||
'------in socket error----',
|
|
||||||
error,
|
|
||||||
socketInstance,
|
|
||||||
ws_url,
|
|
||||||
);
|
|
||||||
//连接报错后,重新请求资源
|
|
||||||
// mediator.publish('on-recreate-socket')
|
|
||||||
};
|
|
||||||
socketInstance.onmessage = event => {
|
|
||||||
if (!isFirstConnected.current) {
|
|
||||||
term.write('\r');
|
|
||||||
// term.focus()
|
|
||||||
setTimeout(() => {
|
|
||||||
// term.clear();
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
isFirstConnected.current = true;
|
|
||||||
console.log('event:', event);
|
|
||||||
|
|
||||||
const data = Base64.decode(event.data.toString());
|
|
||||||
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
|
|
||||||
|
|
||||||
console.log('data:', data, w, term);
|
|
||||||
term.write(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
socketInstance.onclose = evt => {
|
|
||||||
if (tid) {
|
|
||||||
clearInterval(tid);
|
|
||||||
}
|
|
||||||
term.write('\r\nconnection closed');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const tid = setInterval(() => {
|
|
||||||
if (socket.current) {
|
|
||||||
socket.current.send(JSON.stringify({ tp: 'h' }));
|
|
||||||
}
|
|
||||||
}, TimeTicket);
|
|
||||||
|
|
||||||
const unSubCreate = mediator.subscribe('create-socket', id => {
|
|
||||||
if (sid === id) {
|
|
||||||
if (socket.current && socket.current.readyState === 1) {
|
|
||||||
term.focus();
|
|
||||||
} else {
|
|
||||||
createSocket();
|
|
||||||
}
|
|
||||||
term.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const unSubClose = mediator.subscribe('close-socket', id => {
|
|
||||||
if (sid === id) {
|
|
||||||
if (socket.current) {
|
|
||||||
socket.current.close();
|
|
||||||
isFirstConnected.current = false;
|
|
||||||
term.clear();
|
|
||||||
}
|
|
||||||
socket.current = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const unSubResize = mediator.subscribe('ssh-xterm-resize', option => {
|
|
||||||
if (socket.current && socket.current.readyState === 1) {
|
|
||||||
socket.current.send(
|
|
||||||
JSON.stringify({ tp: 'resize', data: { ...option } }),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const unSubAddTime = mediator.subscribe('ssh-add-connect-time', () => {
|
|
||||||
if (socket.current && socket.current.readyState === 1) {
|
|
||||||
socket.current.send(JSON.stringify({ tp: 'overtime' }));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
unSubClose();
|
|
||||||
unSubCreate();
|
|
||||||
unSubResize();
|
|
||||||
unSubAddTime();
|
|
||||||
if (socket.current) {
|
|
||||||
socket.current.close();
|
|
||||||
isFirstConnected.current = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [term, ws_url, port]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={el} className="xterm-panel" style={{height:"100%"}}>
|
|
||||||
{!ws_url ? <p style={{ color: '#fff' }}>正在连接命令行服务...</p> : null}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,46 +0,0 @@
|
||||||
function Mediator(obj) {
|
|
||||||
const channels = {};
|
|
||||||
|
|
||||||
const mediator = {
|
|
||||||
subscribe: function(channel, cb) {
|
|
||||||
if (!channels[channel]) {
|
|
||||||
channels[channel] = [];
|
|
||||||
}
|
|
||||||
channels[channel].push(cb);
|
|
||||||
return this.unsubscribe.bind(null, channel, cb);
|
|
||||||
},
|
|
||||||
|
|
||||||
unsubscribe: function(channel, cb) {
|
|
||||||
let rs = channels[channel];
|
|
||||||
let index = -1;
|
|
||||||
if (rs) {
|
|
||||||
for (let i = 0; i < rs.length; i++) {
|
|
||||||
if (rs[i].name === cb.name) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (index >= 0) {
|
|
||||||
channels[channel].splice(index, 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
publish: function(channel) {
|
|
||||||
if (!channels[channel]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
channels[channel].forEach(subscription => {
|
|
||||||
subscription.apply(null, args);
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return obj ? Object.assign(obj, mediator) : mediator;
|
|
||||||
}
|
|
||||||
const mediator = new Mediator();
|
|
||||||
export default mediator;
|
|
|
@ -111,7 +111,7 @@ class NewHeader extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onGlobalSearch=(value,item)=>{
|
onGlobalSearch=(value,item)=>{
|
||||||
window.location.href=`${item}?value=` + value;
|
window.location.href=`${item && item.url}?value=` + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
openNotification = (messge) => {
|
openNotification = (messge) => {
|
||||||
|
@ -403,39 +403,13 @@ class NewHeader extends Component {
|
||||||
visiblemyss: boll,
|
visiblemyss: boll,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getAppdata = () => {
|
|
||||||
try {
|
|
||||||
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
|
|
||||||
var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
|
|
||||||
this.setState({
|
|
||||||
settings: chromesettingArray
|
|
||||||
});
|
|
||||||
if (chromesettingArray.tab_logo_url) {
|
|
||||||
this.gettablogourldata(chromesettingresponseArray);
|
|
||||||
} else {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.geturlsdata();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
geturlsdata = () => {
|
geturlsdata = () => {
|
||||||
let url = "/setting.json";
|
let url = "/setting.json";
|
||||||
axios.get(url).then((response) => {
|
axios.get(url).then((response) => {
|
||||||
if (response && response.data) {
|
if (response && response.data) {
|
||||||
this.setState({ settings: response.data.setting });
|
this.setState({ settings: response.data.setting });
|
||||||
// localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
|
if (response.data.setting.tab_logo_url) {
|
||||||
// localStorage.setItem('chromesettingresponse', JSON.stringify(response));
|
this.gettablogourldata(response);
|
||||||
try {
|
|
||||||
if (response.data.setting.tab_logo_url) {
|
|
||||||
this.gettablogourldata(response);
|
|
||||||
} else {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.gettablogourlnull();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.gettablogourlnull();
|
this.gettablogourlnull();
|
||||||
|
@ -482,19 +456,14 @@ class NewHeader extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { match} = this.props;
|
const { match } = this.props;
|
||||||
let current_user = this.props.user;
|
let current_user = this.props.user;
|
||||||
let { Addcoursestypes,
|
let {
|
||||||
tojoinitemtype,
|
|
||||||
tojoinclasstitle,
|
|
||||||
code_notice,
|
|
||||||
checked_notice,
|
|
||||||
AccountProfiletype,
|
AccountProfiletype,
|
||||||
submitapplications,
|
submitapplications,
|
||||||
submitapplicationsvalue,
|
submitapplicationsvalue,
|
||||||
user,
|
user,
|
||||||
isRender,
|
isRender,
|
||||||
showSearchOpentype,
|
|
||||||
headtypesonClickbool,
|
headtypesonClickbool,
|
||||||
headtypess,
|
headtypess,
|
||||||
settings,
|
settings,
|
||||||
|
@ -577,8 +546,8 @@ class NewHeader extends Component {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let search_url = settings && settings.common && settings.common.search;
|
let search_url = settings && settings.common && settings.common.length> 0 && settings.common.filter(item=>item.name==="搜索");
|
||||||
let notice_url = settings && settings.common && settings.common.notice;
|
let notice_url = settings && settings.common && settings.common.length> 0 && settings.common.filter(item=>item.name==="通知");
|
||||||
return (
|
return (
|
||||||
<div className="newHeaders" id="nHeader">
|
<div className="newHeaders" id="nHeader">
|
||||||
<div className="headerContent">
|
<div className="headerContent">
|
||||||
|
@ -646,7 +615,7 @@ class NewHeader extends Component {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="head-right">
|
<div className="head-right">
|
||||||
{search_url ? this.SearchInput(openSearch,search_url):""}
|
{search_url && search_url.length>0 ? this.SearchInput(openSearch,search_url[0]):""}
|
||||||
{
|
{
|
||||||
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
||||||
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
||||||
|
@ -654,10 +623,10 @@ class NewHeader extends Component {
|
||||||
</Dropdown>:""
|
</Dropdown>:""
|
||||||
}
|
}
|
||||||
|
|
||||||
{this.props.user && this.props.user.login && notice_url ?
|
{this.props.user && this.props.user.login && (notice_url && notice_url.length>0) ?
|
||||||
<div className="ml30 edu-menu-panel">
|
<div className="ml30 edu-menu-panel">
|
||||||
{user && user.login &&
|
{user && user.login &&
|
||||||
<a href={`${notice_url}`} style={{ position: 'relative' }}>
|
<a href={`${notice_url[0].url}`} style={{ position: 'relative' }}>
|
||||||
<i className="iconfont icon-xiaoxilingdang color-grey-6"></i>
|
<i className="iconfont icon-xiaoxilingdang color-grey-6"></i>
|
||||||
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
|
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React , { useEffect , useState } from 'react';
|
import React , { useEffect , useState } from 'react';
|
||||||
import { WhiteBack , Box , LongWidth , ShortWidth , Gap , AlignCenter , FlexAJ } from '../Component/layout';
|
import { WhiteBack , Box , LongWidth , ShortWidth , Gap , AlignCenter , FlexAJ } from '../Component/layout';
|
||||||
import { Dropdown , Menu , Divider , Spin, Button } from 'antd';
|
import { Dropdown , Menu , Divider , Spin } from 'antd';
|
||||||
import { getImageUrl } from "educoder";
|
import { getImageUrl } from "educoder";
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import CloneAddress from '../Branch/CloneAddress';
|
import CloneAddress from '../Branch/CloneAddress';
|
||||||
|
@ -20,9 +20,7 @@ import DrawerPanel from '../Component/DrawerPanel';
|
||||||
import UpdateDescModal from './sub/UpdateDescModal';
|
import UpdateDescModal from './sub/UpdateDescModal';
|
||||||
import Nodata from '../Nodata';
|
import Nodata from '../Nodata';
|
||||||
|
|
||||||
/**
|
|
||||||
* projectDetail.type:0是托管项目,1是镜像项目,2是同步镜像项目(为2时不支持在线创建、在线上传、在线修改、在线删除、创建合并请求等功能)
|
|
||||||
*/
|
|
||||||
function CoderDepot(props){
|
function CoderDepot(props){
|
||||||
const [ projectDetail , setProjectDetail ]= useState(undefined);
|
const [ projectDetail , setProjectDetail ]= useState(undefined);
|
||||||
const [ treeValue , setTreeValue ] = useState(undefined);
|
const [ treeValue , setTreeValue ] = useState(undefined);
|
||||||
|
@ -44,18 +42,17 @@ function CoderDepot(props){
|
||||||
const [ openModal , setOpenModal ] = useState(false);
|
const [ openModal , setOpenModal ] = useState(false);
|
||||||
const [ desc , setDesc ] = useState(undefined);
|
const [ desc , setDesc ] = useState(undefined);
|
||||||
const [ website , setWebsite ] = useState(undefined);
|
const [ website , setWebsite ] = useState(undefined);
|
||||||
const [ lesson_url , setLessonUrl ] = useState(undefined);
|
|
||||||
|
|
||||||
const owner = props.match.params.owner;
|
const owner = props.match.params.owner;
|
||||||
const projectsId = props.match.params.projectsId;
|
const projectsId = props.match.params.projectsId;
|
||||||
const branchName = props.match.params.branchName;
|
const branchName = props.match.params.branchName;
|
||||||
let pathname = props.history.location.pathname;
|
let pathname = props.history.location.pathname;
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(props.projectDetail){
|
if(props.projectDetail){
|
||||||
setProjectDetail(props.projectDetail);
|
setProjectDetail(props.projectDetail);
|
||||||
setDesc(props.projectDetail.description);
|
setDesc(props.projectDetail.description);
|
||||||
setWebsite(props.projectDetail.website);
|
setWebsite(props.projectDetail.website);
|
||||||
setLessonUrl(props.projectDetail.lesson_url);
|
|
||||||
}
|
}
|
||||||
},[props])
|
},[props])
|
||||||
|
|
||||||
|
@ -68,17 +65,17 @@ function CoderDepot(props){
|
||||||
},[treeValue])
|
},[treeValue])
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if (pathname && projectDetail){
|
if (pathname){
|
||||||
if(pathname.indexOf(`/projects/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${branchName}/`) > -1) {
|
if(pathname.indexOf(`/projects/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${branchName}/`) > -1) {
|
||||||
let url = pathname.split(`/tree/${branchName}/`)[1];
|
let url = pathname.split(`/tree/${branchName}/`)[1];
|
||||||
setTreeValue(url);
|
setTreeValue(url);
|
||||||
getFileInfo(url,branchName);
|
getFileInfo(url,branchName);
|
||||||
}else{
|
}else{
|
||||||
setTreeValue(undefined);
|
setTreeValue(undefined);
|
||||||
getDirInfo(branchName ||projectDetail.default_branch);
|
getDirInfo(branchName ||(projectDetail && projectDetail.default_branch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},[pathname,projectDetail])
|
},[pathname])
|
||||||
|
|
||||||
// 获取主目录列表
|
// 获取主目录列表
|
||||||
function getDirInfo(branch){
|
function getDirInfo(branch){
|
||||||
|
@ -95,7 +92,7 @@ function CoderDepot(props){
|
||||||
setZip_url(result.data.zip_url);
|
setZip_url(result.data.zip_url);
|
||||||
let c = result.data.last_commit
|
let c = result.data.last_commit
|
||||||
setLastCommit(c && c.commit);
|
setLastCommit(c && c.commit);
|
||||||
setLastCommitAuthor(c && c.committer);
|
setLastCommitAuthor(c && (c.author || (c.commit && c.commit.author)));
|
||||||
setMainFlag(true);
|
setMainFlag(true);
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +134,7 @@ function CoderDepot(props){
|
||||||
}
|
}
|
||||||
let c = result.data.last_commit
|
let c = result.data.last_commit
|
||||||
setLastCommit(c && c.commit);
|
setLastCommit(c && c.commit);
|
||||||
setLastCommitAuthor(c && c.committer);
|
setLastCommitAuthor(c && (c.author || (c.commit && c.commit.author)));
|
||||||
setMainFlag(false);
|
setMainFlag(false);
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
}
|
}
|
||||||
|
@ -219,16 +216,14 @@ function CoderDepot(props){
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
// 确认修改简介、website、实践课程链接
|
function okUpdate(d,w){
|
||||||
function okUpdate(d,w,l){
|
|
||||||
const url = `/${owner}/${projectsId}.json`;
|
const url = `/${owner}/${projectsId}.json`;
|
||||||
axios.put(url,{
|
axios.put(url,{
|
||||||
description:d,website:w,lesson_url:l
|
description:d,website:w
|
||||||
}).then(result=>{
|
}).then(result=>{
|
||||||
if(result && result.data && result.data.id){
|
if(result && result.data && result.data.id){
|
||||||
setDesc(result.data.description);
|
setDesc(result.data.description);
|
||||||
setWebsite(result.data.website);
|
setWebsite(result.data.website);
|
||||||
setLessonUrl(result.data.lesson_url);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -238,7 +233,7 @@ function CoderDepot(props){
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<WhiteBack>
|
<WhiteBack>
|
||||||
<UpdateDescModal desc={desc} website={website} lesson_url={lesson_url} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
|
<UpdateDescModal desc={desc} website={website} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
|
||||||
<Spin spinning={isSpin}>
|
<Spin spinning={isSpin}>
|
||||||
{
|
{
|
||||||
(dirInfo || fileInfo) &&
|
(dirInfo || fileInfo) &&
|
||||||
|
@ -253,10 +248,7 @@ function CoderDepot(props){
|
||||||
onClose={()=>setVisible(false)}
|
onClose={()=>setVisible(false)}
|
||||||
list = {mainFlag ? dirInfo : undefined}
|
list = {mainFlag ? dirInfo : undefined}
|
||||||
/>
|
/>
|
||||||
<div className="drawerBtn" onClick={()=>setVisible(true)}>
|
<div className="drawerBtn" onClick={()=>setVisible(true)}><i className="iconfont icon-youjiantou"></i></div>
|
||||||
<i className="iconfont icon-youjiantou font-16"></i>
|
|
||||||
<span>目录</span>
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
<div style={{minHeight:"500px"}}>
|
<div style={{minHeight:"500px"}}>
|
||||||
|
@ -298,21 +290,11 @@ function CoderDepot(props){
|
||||||
</AlignCenter>
|
</AlignCenter>
|
||||||
<AlignCenter>
|
<AlignCenter>
|
||||||
<div className="mr20 addOptionBtn">
|
<div className="mr20 addOptionBtn">
|
||||||
{
|
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/pulls/new`)} >+ 合并请求</a>
|
||||||
projectDetail.type !== 2 &&
|
|
||||||
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/pulls/new`)} >+ 合并请求</a>
|
|
||||||
}
|
|
||||||
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/issues/new`)} >+ 任务</a>
|
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/issues/new`)} >+ 任务</a>
|
||||||
</div>
|
</div>
|
||||||
{ type === "dir" && projectDetail.type !== 2 &&
|
{ type === "dir" && <Dropdown.Button overlay={fileMenu} className="mr20">文件</Dropdown.Button>}
|
||||||
<Dropdown overlay={fileMenu} className="mr20">
|
<Dropdown.Button overlay={downloadMenu} type={'primary'}>下载</Dropdown.Button>
|
||||||
<Button type="default">文件 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-grey-9"></i></Button>
|
|
||||||
</Dropdown>
|
|
||||||
}
|
|
||||||
|
|
||||||
<Dropdown overlay={downloadMenu} placement="bottomRight">
|
|
||||||
<Button type={'primary'}>下载 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-white"></i></Button>
|
|
||||||
</Dropdown>
|
|
||||||
</AlignCenter>
|
</AlignCenter>
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
{
|
{
|
||||||
|
@ -321,7 +303,7 @@ function CoderDepot(props){
|
||||||
{
|
{
|
||||||
lastCommit &&
|
lastCommit &&
|
||||||
<div className="listtablehead">
|
<div className="listtablehead">
|
||||||
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} id={lastCommitAuthor && lastCommitAuthor.id} login={lastCommitAuthor && lastCommitAuthor.login}/>
|
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} />
|
||||||
<div className={hideBtn && hide ? "ellipsistxt hide" :"ellipsistxt"}><p id="ptxt">{lastCommit && lastCommit.message}</p></div>
|
<div className={hideBtn && hide ? "ellipsistxt hide" :"ellipsistxt"}><p id="ptxt">{lastCommit && lastCommit.message}</p></div>
|
||||||
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
|
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
|
||||||
|
|
||||||
|
@ -362,7 +344,6 @@ function CoderDepot(props){
|
||||||
md={mdFlag}
|
md={mdFlag}
|
||||||
onEdit={onEdit}
|
onEdit={onEdit}
|
||||||
currentBranch={branchName || (projectDetail && projectDetail.default_branch)}
|
currentBranch={branchName || (projectDetail && projectDetail.default_branch)}
|
||||||
type={projectDetail.type}
|
|
||||||
></CoderRootFileDetail>
|
></CoderRootFileDetail>
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -373,7 +354,7 @@ function CoderDepot(props){
|
||||||
(dirInfo && dirInfo.length === 0) && (fileInfo && fileInfo.length === 0) ? <Nodata _html="暂未发现文件"/> :""
|
(dirInfo && dirInfo.length === 0) && (fileInfo && fileInfo.length === 0) ? <Nodata _html="暂未发现文件"/> :""
|
||||||
}
|
}
|
||||||
{/* readme文件显示(显示文件详情时不显示readme文件) */}
|
{/* readme文件显示(显示文件详情时不显示readme文件) */}
|
||||||
{ dirInfo && (projectDetail && projectDetail.readme) ? <ReadMe ChangeFile={ChangeFile} readme={projectDetail && projectDetail.readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
|
{ dirInfo && (projectDetail && projectDetail.readme) ? <ReadMe ChangeFile={ChangeFile} readme={projectDetail && projectDetail.readme} operate={props && (props.isManager || props.isDeveloper)} history={props.history} /> :"" }
|
||||||
</div>
|
</div>
|
||||||
</LongWidth>
|
</LongWidth>
|
||||||
{
|
{
|
||||||
|
@ -384,12 +365,12 @@ function CoderDepot(props){
|
||||||
<FlexAJ className="font-18 color-grey-6 mb20" style={{lineHeight:"28px"}}>简介
|
<FlexAJ className="font-18 color-grey-6 mb20" style={{lineHeight:"28px"}}>简介
|
||||||
{projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner") && <i onClick={()=>setOpenModal(true)} className="iconfont icon-anquanshezhi color-grey-9 font-15"></i>}
|
{projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner") && <i onClick={()=>setOpenModal(true)} className="iconfont icon-anquanshezhi color-grey-9 font-15"></i>}
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
{desc && <p className="font-14 color-grey-9 mb15 task-hide-2" style={{lineHeight:"22px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}}>{desc}</p>}
|
{desc && <p className="font-14 color-grey-9 mb15 task-hide-2" style={{lineHeight:"22px",WebkitLineClamp:"4",textAlign:"justify"}}>{desc}</p>}
|
||||||
{
|
{
|
||||||
website &&
|
website &&
|
||||||
<p className="color-grey-6 df">
|
<p className="color-grey-6 df">
|
||||||
<i className="iconfont icon-lianjie2 font-15 mr10 color-grey-9"></i>
|
<i className="iconfont icon-lianjie2 font-15 mr10 color-grey-9"></i>
|
||||||
<a href={website} target="_blank" style={{wordBreak:"break-all",lineHeight:"20px",marginTop:"5px",textDecoration:"underline"}}>{website}</a>
|
<span style={{wordBreak:"break-all",lineHeight:"20px",marginTop:"5px"}}>{website}</span>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
<p>
|
<p>
|
||||||
|
@ -408,14 +389,6 @@ function CoderDepot(props){
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
{
|
|
||||||
lesson_url &&
|
|
||||||
<div>
|
|
||||||
<Divider />
|
|
||||||
<p className="font-16 color-grey-6">实践课程</p>
|
|
||||||
<a href={lesson_url} target="_blank" className="color-grey-6" style={{textDecoration:"underline"}}>{lesson_url}</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{/* 发布 */}
|
{/* 发布 */}
|
||||||
{
|
{
|
||||||
projectDetail && projectDetail.release_versions &&
|
projectDetail && projectDetail.release_versions &&
|
||||||
|
|
|
@ -496,11 +496,9 @@ class Detail extends Component {
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<span className="detail_tag_btn">
|
<span className="detail_tag_btn">
|
||||||
<Tooltip title="复刻是fork的中文名,即复制代码仓库" placement="bottom">
|
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={this.forkFunc}>
|
||||||
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={this.forkFunc}>
|
<i className="iconfont icon-fork color-grey-9 mr3"></i>复刻 (Fork)
|
||||||
<i className="iconfont icon-fork color-grey-9 mr3"></i>复刻
|
</a>
|
||||||
</a>
|
|
||||||
</Tooltip>
|
|
||||||
{
|
{
|
||||||
forked_count > 0 ?
|
forked_count > 0 ?
|
||||||
platform ?
|
platform ?
|
||||||
|
@ -518,7 +516,6 @@ class Detail extends Component {
|
||||||
{
|
{
|
||||||
firstSync ? "" :
|
firstSync ? "" :
|
||||||
<DetailBanner
|
<DetailBanner
|
||||||
history={this.props.history}
|
|
||||||
list={bannerList}
|
list={bannerList}
|
||||||
owner={owner}
|
owner={owner}
|
||||||
projectsId={projectsId}
|
projectsId={projectsId}
|
||||||
|
|
|
@ -83,10 +83,10 @@
|
||||||
}
|
}
|
||||||
.addOptionBtn{
|
.addOptionBtn{
|
||||||
height: 32px;
|
height: 32px;
|
||||||
line-height: 30px;
|
line-height: 32px;
|
||||||
display: flex;
|
display: flex;
|
||||||
border:1px solid #d9d9d9;
|
border:1px solid #d9d9d9;
|
||||||
border-radius: 2px;
|
border-radius: 4px;
|
||||||
a{
|
a{
|
||||||
padding:0px 13px;
|
padding:0px 13px;
|
||||||
color: rgba(0, 0, 0, 0.65);
|
color: rgba(0, 0, 0, 0.65);
|
||||||
|
@ -95,9 +95,6 @@
|
||||||
& > a:first-child{
|
& > a:first-child{
|
||||||
border-right: 1px solid #d9d9d9;
|
border-right: 1px solid #d9d9d9;
|
||||||
}
|
}
|
||||||
& > a:last-child{
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.infoCount{
|
.infoCount{
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -260,30 +257,20 @@
|
||||||
.drawerBtn{
|
.drawerBtn{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: -13px;
|
left: -13px;
|
||||||
border:1px solid rgb(207,205,223);
|
border:1px solid #d9d9d9;
|
||||||
width: 34px;
|
width: 34px;
|
||||||
border-radius: 0px 12px 12px 0px;
|
border-radius: 0px 12px 12px 0px;
|
||||||
|
text-align: right;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
|
line-height: 70px;
|
||||||
top:50%;
|
top:50%;
|
||||||
margin-top: -35px;
|
margin-top: -35px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: center;
|
|
||||||
&:hover{
|
&:hover{
|
||||||
box-shadow: 1px 0px 7px rgba(0,0,0,0.1);
|
box-shadow: 1px 0px 7px rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
span{
|
|
||||||
writing-mode: vertical-lr;
|
|
||||||
color: #202429;
|
|
||||||
width: 25px;
|
|
||||||
}
|
|
||||||
i{
|
i{
|
||||||
color: #24292e;
|
color: #d9d9d9;
|
||||||
height: 18px;
|
|
||||||
line-height: 18px;
|
|
||||||
width: 18px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.downMenu{
|
.downMenu{
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Skeleton , Tooltip} from 'antd';
|
import { Skeleton } from 'antd';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
function DetailBanner({ history,list , owner , projectsId , isManager , url , pathname , state , urlFlag , projectDetail , platform ,open_devops }){
|
function DetailBanner({ list , owner , projectsId , isManager , url , pathname , state , urlFlag , projectDetail , platform ,open_devops }){
|
||||||
const [ menuName , setMenuName ] = useState(undefined);
|
const [ menuName , setMenuName ] = useState(undefined);
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(list){
|
if(list){
|
||||||
// 没有资源库banner但是通过连接进资源库页面时
|
|
||||||
if(pathname && pathname==="source"){
|
|
||||||
let a = list.filter(item=>item.menu_name === "resources");
|
|
||||||
if(a && a.length === 0){
|
|
||||||
history.push(`/projects/${owner}/${projectsId}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setMenuName(list);
|
setMenuName(list);
|
||||||
}
|
}
|
||||||
},[list]);
|
},[list]);
|
||||||
|
@ -46,13 +39,11 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
||||||
{
|
{
|
||||||
item.menu_name === "issues" &&
|
item.menu_name === "issues" &&
|
||||||
<li className={pathname==="issues" ? "active" : ""}>
|
<li className={pathname==="issues" ? "active" : ""}>
|
||||||
<Tooltip title="易修是Issue的中文名,即问题列表" placement="bottom">
|
<Link to={{ pathname: `/projects/${owner}/${projectsId}/issues`, state }}>
|
||||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/issues`, state }}>
|
<i className={pathname==="issues" ? "iconfont icon-renwu color-grey-3 mr5 font-14":"iconfont icon-renwu color-grey-6 font-14 mr5"}></i>
|
||||||
<i className={pathname==="issues" ? "iconfont icon-renwu color-grey-3 mr5 font-14":"iconfont icon-renwu color-grey-6 font-14 mr5"}></i>
|
<span>易修 (Issue)</span>
|
||||||
<span>易修</span>
|
{projectDetail && projectDetail.issues_count ? <span className="num">{projectDetail.issues_count}</span> : ""}
|
||||||
{projectDetail && projectDetail.issues_count ? <span className="num">{projectDetail.issues_count}</span> : ""}
|
</Link>
|
||||||
</Link>
|
|
||||||
</Tooltip>
|
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -75,8 +66,8 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
||||||
</li>
|
</li>
|
||||||
:""
|
:""
|
||||||
}
|
}
|
||||||
{/* {
|
{
|
||||||
item.menu_name === "resources" &&
|
item.menu_name === "source" &&
|
||||||
<li className={pathname==="source" ? "active" : ""}>
|
<li className={pathname==="source" ? "active" : ""}>
|
||||||
<Link to={{ pathname: `/projects/${owner}/${projectsId}/source`, state }}>
|
<Link to={{ pathname: `/projects/${owner}/${projectsId}/source`, state }}>
|
||||||
<i className={pathname==="source" ? "iconfont icon-ziyuanpaihanghetuijian color-grey-3 mr5 font-14":"iconfont icon-ziyuanpaihanghetuijian color-grey-6 font-14 mr5"}></i>
|
<i className={pathname==="source" ? "iconfont icon-ziyuanpaihanghetuijian color-grey-3 mr5 font-14":"iconfont icon-ziyuanpaihanghetuijian color-grey-6 font-14 mr5"}></i>
|
||||||
|
@ -84,7 +75,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
||||||
{projectDetail && projectDetail.source_count ? <span className="num">{projectDetail.source_count}</span> :""}
|
{projectDetail && projectDetail.source_count ? <span className="num">{projectDetail.source_count}</span> :""}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
} */}
|
}
|
||||||
{
|
{
|
||||||
item.menu_name === "versions" &&
|
item.menu_name === "versions" &&
|
||||||
<li className={pathname==="milestones" ? "active" : ""}>
|
<li className={pathname==="milestones" ? "active" : ""}>
|
||||||
|
@ -104,19 +95,19 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
{
|
|
||||||
item.menu_name === "setting" &&
|
|
||||||
<li className={pathname === "setting" ? "active" : ""}>
|
|
||||||
<Link to={`/projects/${owner}/${projectsId}/setting`}>
|
|
||||||
<i className={url && url.indexOf("/setting") > 0 ? "iconfont icon-cangku color-grey-3 mr5 font-14":"iconfont icon-cangku color-grey-6 font-14 mr5"}></i>
|
|
||||||
<span>仓库设置</span>
|
|
||||||
</Link>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
isManager && platform ?
|
||||||
|
<li className={pathname === "setting" ? "active" : ""}>
|
||||||
|
<Link to={`/projects/${owner}/${projectsId}/setting`}>
|
||||||
|
<i className={url && url.indexOf("/setting") > 0 ? "iconfont icon-cangku color-grey-3 mr5 font-14":"iconfont icon-cangku color-grey-6 font-14 mr5"}></i>
|
||||||
|
<span>仓库设置</span>
|
||||||
|
</Link>
|
||||||
|
</li>:""
|
||||||
|
}
|
||||||
</ul>
|
</ul>
|
||||||
:
|
:
|
||||||
<Skeleton paragraph={false} active={true}/>
|
<Skeleton paragraph={false} active={true}/>
|
||||||
|
|
|
@ -2,13 +2,13 @@ import React , { forwardRef, useEffect } from 'react';
|
||||||
import {Form , Modal , Input } from 'antd';
|
import {Form , Modal , Input } from 'antd';
|
||||||
import "./sub.scss";
|
import "./sub.scss";
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
function UpdateDescModal({form , visible , onCancel , onOk,desc,website,lesson_url}){
|
function UpdateDescModal({form , visible , onCancel , onOk,desc,website}){
|
||||||
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
const { getFieldDecorator, validateFields , setFieldsValue } = form;
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(desc || website){
|
if(desc || website){
|
||||||
setFieldsValue({
|
setFieldsValue({
|
||||||
website,desc,lesson_url
|
website,desc
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},[desc,website])
|
},[desc,website])
|
||||||
|
@ -17,7 +17,7 @@ function UpdateDescModal({form , visible , onCancel , onOk,desc,website,lesson_u
|
||||||
validateFields((err,values)=>{
|
validateFields((err,values)=>{
|
||||||
if(!err){
|
if(!err){
|
||||||
onCancel();
|
onCancel();
|
||||||
onOk(values.desc,values.website,values.lesson_url)
|
onOk(values.desc,values.website)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -49,13 +49,6 @@ function UpdateDescModal({form , visible , onCancel , onOk,desc,website,lesson_u
|
||||||
<Input placeholder="website链接"/>
|
<Input placeholder="website链接"/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="实践课程">
|
|
||||||
{getFieldDecorator("lesson_url",{
|
|
||||||
rules:[]
|
|
||||||
})(
|
|
||||||
<Input placeholder="实践课程链接"/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
|
|
|
@ -178,7 +178,7 @@ class NewMerge extends Component {
|
||||||
let arr = projects_names && projects_names.filter(item=>item.id===value);
|
let arr = projects_names && projects_names.filter(item=>item.id===value);
|
||||||
let identifier = arr && arr[0].project_id;
|
let identifier = arr && arr[0].project_id;
|
||||||
let login = arr && arr[0].project_user_login;
|
let login = arr && arr[0].project_user_login;
|
||||||
let is_fork_id = parseInt(value) !== parseInt(id)
|
let is_fork_id = parseInt(value) !== parseInt(id);
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpin: true,
|
isSpin: true,
|
||||||
merge_head: is_fork_id,
|
merge_head: is_fork_id,
|
||||||
|
|
|
@ -253,6 +253,24 @@ class merge extends Component {
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const Paginations = (
|
||||||
|
<React.Fragment>
|
||||||
|
{search_count > limit ? (
|
||||||
|
<div className="mt30 mb50 edu-txt-center">
|
||||||
|
<Pagination
|
||||||
|
simple
|
||||||
|
defaultCurrent={page}
|
||||||
|
total={search_count}
|
||||||
|
pageSize={limit}
|
||||||
|
onChange={this.ChangePage}
|
||||||
|
></Pagination>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<div className="main" style={{padding:"0px"}}>
|
<div className="main" style={{padding:"0px"}}>
|
||||||
<div className="topWrapper" style={{borderBottom:"none",padding:"20px"}}>
|
<div className="topWrapper" style={{borderBottom:"none",padding:"20px"}}>
|
||||||
|
@ -401,21 +419,9 @@ class merge extends Component {
|
||||||
{...this.props}
|
{...this.props}
|
||||||
{...this.state}
|
{...this.state}
|
||||||
></OrderItem>
|
></OrderItem>
|
||||||
|
{Paginations}
|
||||||
</div>
|
</div>
|
||||||
):""}
|
):""}
|
||||||
{search_count > select_params.limit ? (
|
|
||||||
<div className="mt30 mb50 edu-txt-center">
|
|
||||||
<Pagination
|
|
||||||
simple
|
|
||||||
current={select_params.page}
|
|
||||||
total={search_count}
|
|
||||||
pageSize={select_params.limit}
|
|
||||||
onChange={this.ChangePage}
|
|
||||||
></Pagination>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
""
|
|
||||||
)}
|
|
||||||
{ data && data.issues && data.issues.length === 0 ? <NoneData _html="暂时还没有相关数据!" projectsId={projectsId} owner={owner} /> :""}
|
{ data && data.issues && data.issues.length === 0 ? <NoneData _html="暂时还没有相关数据!" projectsId={projectsId} owner={owner} /> :""}
|
||||||
</Spin>
|
</Spin>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,17 +34,19 @@ class MergeForm extends Component {
|
||||||
this.set_defatul();
|
this.set_defatul();
|
||||||
};
|
};
|
||||||
componentDidUpdate=(prevPros)=>{
|
componentDidUpdate=(prevPros)=>{
|
||||||
|
const { projectsId ,owner } = this.props.match.params;
|
||||||
|
const pId = prevPros.match.params.projectsId;
|
||||||
|
const oId = prevPros.match.params.owner;
|
||||||
|
if(pId !== projectsId || oId !== owner ){
|
||||||
|
// console.log("切换了项目分支···········");
|
||||||
|
this.get_default_selects();
|
||||||
|
}
|
||||||
if(prevPros && this.props && !this.props.checkIfLogin()){
|
if(prevPros && this.props && !this.props.checkIfLogin()){
|
||||||
this.props.history.push("/403")
|
this.props.history.push("/403")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check_is_login =() =>{
|
|
||||||
// if(!this.props.checkIfLogin()){
|
|
||||||
// this.props.history.push("/403")
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
get_default_selects = () => {
|
get_default_selects = () => {
|
||||||
const { projectsId ,owner } = this.props.match.params;
|
const { projectsId ,owner } = this.props.match.params;
|
||||||
this.setState({ isSpin: true });
|
this.setState({ isSpin: true });
|
||||||
|
|
|
@ -218,7 +218,7 @@ class MilepostDetail extends Component {
|
||||||
</span>
|
</span>
|
||||||
<div className="milepostdiv">
|
<div className="milepostdiv">
|
||||||
<Link to={`/projects/${owner}/${projectsId}/milestones/${meilid}/edit`} className="topWrapper_btn" style={{ marginRight: 15 }} >编辑里程碑</Link>
|
<Link to={`/projects/${owner}/${projectsId}/milestones/${meilid}/edit`} className="topWrapper_btn" style={{ marginRight: 15 }} >编辑里程碑</Link>
|
||||||
<Link to={`/projects/${owner}/${projectsId}/issues/${meilid}/new`} className="topWrapper_btn">创建任务</Link>
|
<Link to={`/projects/${owner}/${projectsId}/issues/${meilid}/new`} className="topWrapper_btn">创建易修</Link>
|
||||||
</div>
|
</div>
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -352,12 +352,12 @@ class order extends Component {
|
||||||
if (this.props.checkIfLogin()) {
|
if (this.props.checkIfLogin()) {
|
||||||
return(
|
return(
|
||||||
<Link className="topWrapper_btn ml10" target="_blank" to={`/projects/${owner}/${projectsId}/issues/new`}>
|
<Link className="topWrapper_btn ml10" target="_blank" to={`/projects/${owner}/${projectsId}/issues/new`}>
|
||||||
+ 创建任务
|
+ 创建易修
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}else{
|
}else{
|
||||||
return(
|
return(
|
||||||
<a className="topWrapper_btn ml10" onClick={this.islogin}>+ 创建任务</a>
|
<a className="topWrapper_btn ml10" onClick={this.islogin}>+ 创建易修</a>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,14 +310,14 @@ class order_form extends Component {
|
||||||
<div className="list-right">
|
<div className="list-right">
|
||||||
<div className="pd20">
|
<div className="pd20">
|
||||||
<h3 className="mb15">
|
<h3 className="mb15">
|
||||||
{form_type === "new" ? "新建" :( form_type === "copy" ? "复制" : "编辑")}任务
|
{form_type === "new" ? "新建" :( form_type === "copy" ? "复制" : "编辑")}易修
|
||||||
</h3>
|
</h3>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
{getFieldDecorator("subject", {
|
{getFieldDecorator("subject", {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: "请填写任务标题",
|
message: "请填写易修标题",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
})(<Input placeholder="标题" size="large" />)}
|
})(<Input placeholder="标题" size="large" />)}
|
||||||
|
|
|
@ -11,7 +11,7 @@ function Collaborator(props){
|
||||||
const [ newGroupId , setNewGroupId] = useState(undefined);
|
const [ newGroupId , setNewGroupId] = useState(undefined);
|
||||||
const {projectsId ,owner} = props.match.params;
|
const {projectsId ,owner} = props.match.params;
|
||||||
|
|
||||||
const author = props && props.projectDetail && props.projectDetail.author;
|
const author = props.projectDetail && props.projectDetail.author;
|
||||||
|
|
||||||
function getID(id){
|
function getID(id){
|
||||||
setNewId(id);
|
setNewId(id);
|
||||||
|
@ -42,7 +42,7 @@ function Collaborator(props){
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
nav === "1" ?
|
nav === "1" ?
|
||||||
<Member newId={newId} projectsId={projectsId} owner={owner} project_id={props.project_id} author={props.projectDetail && props.projectDetail.author} showNotification={props.showNotification}/>
|
<Member newId={newId} projectsId={projectsId} owner={owner} project_id={props.project_id} author={props.author} showNotification={props.showNotification}/>
|
||||||
:
|
:
|
||||||
<Group owner={owner} projectsId={projectsId} newGroupId={newGroupId}/>
|
<Group owner={owner} projectsId={projectsId} newGroupId={newGroupId}/>
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ function CollaboratorMember({projectsId,owner,project_id,author,showNotification
|
||||||
const [ role , setRole ] = useState(undefined);
|
const [ role , setRole ] = useState(undefined);
|
||||||
const [ listData , setListData ] = useState(undefined);
|
const [ listData , setListData ] = useState(undefined);
|
||||||
const [ total , setTotal ] = useState(0);
|
const [ total , setTotal ] = useState(0);
|
||||||
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(newId){
|
if(newId){
|
||||||
addCollaborator(newId);
|
addCollaborator(newId);
|
||||||
|
|
|
@ -13,7 +13,6 @@ const menu = [
|
||||||
{name:"易修 (Issue)",index:"issues"},
|
{name:"易修 (Issue)",index:"issues"},
|
||||||
{name:"合并请求",index:"pulls"},
|
{name:"合并请求",index:"pulls"},
|
||||||
{name:"工作流(beta版)",index:"devops"},
|
{name:"工作流(beta版)",index:"devops"},
|
||||||
// {name:"资源库",index:"resources"},
|
|
||||||
{name:"里程碑",index:"versions"},
|
{name:"里程碑",index:"versions"},
|
||||||
{name:"动态",index:"activity"},
|
{name:"动态",index:"activity"},
|
||||||
]
|
]
|
||||||
|
|
|
@ -84,11 +84,12 @@ export default ((props) => {
|
||||||
|
|
||||||
// 移除成员
|
// 移除成员
|
||||||
function removeUser(username) {
|
function removeUser(username) {
|
||||||
const url = `/organizations/${OIdentifier}/teams/${groupId}/team_users/${username}.json`;
|
|
||||||
if (username) {
|
if (username) {
|
||||||
|
const url = `/organizations/${OIdentifier}/teams/${groupId}/team_users/quit.json`;
|
||||||
axios.delete(url).then((result) => {
|
axios.delete(url).then((result) => {
|
||||||
if (result && result.data) {
|
if (result && result.data) {
|
||||||
|
props.showNotification(`已成功退出团队!`);
|
||||||
|
props.history.push(`/organize/${OIdentifier}`);
|
||||||
}
|
}
|
||||||
}).catch((error) => { });
|
}).catch((error) => { });
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,35 +95,15 @@ export default Form.create()(
|
||||||
})
|
})
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}
|
}
|
||||||
function checkname(rule, value, callback){
|
|
||||||
if(!value){
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
if(value && !value.match(/^[a-zA-Z][a-zA-Z0-9_-]{3,19}$/)){
|
|
||||||
callback("只能使用以字母开头,包含字母、数字、下划线、横杠等,长度4到20个字符");
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
return(
|
return(
|
||||||
<div>
|
<div>
|
||||||
<WhiteBack>
|
<WhiteBack>
|
||||||
<Title>基本设置</Title>
|
<Title>基本设置</Title>
|
||||||
<Div>
|
<Div>
|
||||||
<Form>
|
<Form>
|
||||||
{helper(
|
|
||||||
"组织账号:",
|
|
||||||
"name",
|
|
||||||
[
|
|
||||||
{ required: true, message: "请输入组织账号" },
|
|
||||||
{
|
|
||||||
validator:checkname
|
|
||||||
}
|
|
||||||
],
|
|
||||||
<Input placeholder="请输入组织账号" disabled/>,true
|
|
||||||
)}
|
|
||||||
{helper(
|
{helper(
|
||||||
"组织名称:",
|
"组织名称:",
|
||||||
"nickname",
|
"name",
|
||||||
[{ required: true, message: "请输入组织名称" }],
|
[{ required: true, message: "请输入组织名称" }],
|
||||||
<Input placeholder="请输入组织名称" />,true
|
<Input placeholder="请输入组织名称" />,true
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -56,7 +56,7 @@ export default ((props)=>{
|
||||||
detail &&
|
detail &&
|
||||||
<Cards
|
<Cards
|
||||||
src={`/organize/${OIdentifier}/group/${groupId}`}
|
src={`/organize/${OIdentifier}/group/${groupId}`}
|
||||||
title={detail.nickname||detail.name}
|
title={detail.name}
|
||||||
rightBtn={
|
rightBtn={
|
||||||
flag && <span className="subNavs">
|
flag && <span className="subNavs">
|
||||||
<Link to={`/organize/${OIdentifier}/member`} className={pathname ===`/organize/${OIdentifier}/member` ? "active":""}><span>组织成员</span>{detail.num_users && <lable>{detail.num_users}</lable>}</Link>
|
<Link to={`/organize/${OIdentifier}/member`} className={pathname ===`/organize/${OIdentifier}/member` ? "active":""}><span>组织成员</span>{detail.num_users && <lable>{detail.num_users}</lable>}</Link>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { Upload, Icon , Button } from 'antd';
|
import { Upload, Button, Icon } from 'antd';
|
||||||
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
||||||
import { AlignCenter } from '../Component/layout';
|
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
const { Dragger } = Upload;
|
const { Dragger } = Upload;
|
||||||
|
@ -29,12 +28,22 @@ class Index extends Component {
|
||||||
|
|
||||||
onAttachmentRemove = (file) => {
|
onAttachmentRemove = (file) => {
|
||||||
if (!file.percent || file.percent === 100) {
|
if (!file.percent || file.percent === 100) {
|
||||||
|
// this.props.confirm({
|
||||||
|
// content: '是否确认删除?',
|
||||||
|
// onOk: () => {
|
||||||
|
// this.deleteAttachment(file)
|
||||||
|
// },
|
||||||
|
// onCancel() {
|
||||||
|
// console.log('Cancel');
|
||||||
|
// },
|
||||||
|
// });
|
||||||
this.deleteAttachment(file)
|
this.deleteAttachment(file)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAttachment = (file) => {
|
deleteAttachment = (file) => {
|
||||||
|
|
||||||
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
|
||||||
axios.delete(url, {
|
axios.delete(url, {
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
|
@ -73,7 +82,7 @@ class Index extends Component {
|
||||||
fileIdList = (fileList) => {
|
fileIdList = (fileList) => {
|
||||||
let array = [];
|
let array = [];
|
||||||
fileList && fileList.length > 0 && fileList.map((item) => {
|
fileList && fileList.length > 0 && fileList.map((item) => {
|
||||||
return array.push(item.response && (item.response.id || (item.response.data && item.response.data.id)));
|
return array.push(item.response && item.response.id);
|
||||||
})
|
})
|
||||||
array && this.props.load && this.props.load(array);
|
array && this.props.load && this.props.load(array);
|
||||||
}
|
}
|
||||||
|
@ -89,27 +98,21 @@ class Index extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
//判断是否已经提交,如已提交评论则上一条评论数据清除
|
//判断是否已经提交,如已提交评论则上一条评论数据清除
|
||||||
const { isComplete, icon , btn , className , size , actionUrl } = this.props;
|
const { isComplete, icon } = this.props;
|
||||||
const { fileList } = this.state;
|
const { fileList } = this.state;
|
||||||
|
|
||||||
let list = isComplete === true ? fileList : undefined;
|
let list = isComplete === true ? fileList : undefined;
|
||||||
const upload = {
|
const upload = {
|
||||||
name: 'file',
|
name: 'file',
|
||||||
fileList: list,
|
fileList: list,
|
||||||
action: actionUrl || `${getUploadActionUrl()}`,
|
action: `${getUploadActionUrl()}`,
|
||||||
onChange: this.handleChange,
|
onChange: this.handleChange,
|
||||||
onRemove: this.onAttachmentRemove,
|
onRemove: this.onAttachmentRemove,
|
||||||
beforeUpload: this.beforeUpload
|
beforeUpload: this.beforeUpload
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
btn ?
|
<Dragger {...upload} className={this.props.className}>
|
||||||
<Upload {...upload} className={className}>
|
|
||||||
<Button type={"default"}>上传文件</Button>
|
|
||||||
<span className="ml10 color-grey-9">(你可以上传小于<span className="color-red">{size}MB</span>的文件)</span>
|
|
||||||
</Upload>
|
|
||||||
:
|
|
||||||
<Dragger {...upload} className={className}>
|
|
||||||
{icon || <Icon type="inbox" />}
|
{icon || <Icon type="inbox" />}
|
||||||
<p className="ant-upload-text font-14">拖动文件或<span className="color-blue">点击此处上传</span></p>
|
<p className="ant-upload-text font-14">拖动文件或<span className="color-blue">点击此处上传</span></p>
|
||||||
</Dragger>
|
</Dragger>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -17,6 +17,21 @@ const paramRequestOldUrlArray = [
|
||||||
|
|
||||||
]
|
]
|
||||||
const paramRequestNewUrlArray = [
|
const paramRequestNewUrlArray = [
|
||||||
|
// 获取代码内容
|
||||||
|
// (matchResult) => {
|
||||||
|
// const stageId = matchResult[1]
|
||||||
|
// return `/tasks/${stageId}/rep_content.json`
|
||||||
|
// },
|
||||||
|
|
||||||
|
// 获取版本库目录、文件
|
||||||
|
// http://testeduplus2.educoder.net/tasks/se79x25pzfwo/git_entries.json?path=&dev=master&gpid=3441
|
||||||
|
// (matchResult) => {
|
||||||
|
// const stageId = matchResult[1]
|
||||||
|
// // return `/tasks/${stageId}/git_entries.json`
|
||||||
|
// return `/myshixuns/${stageId}/repository.json`
|
||||||
|
// },
|
||||||
|
|
||||||
|
// `/tasks/tonblikwzj78/choose_build.json`
|
||||||
(matchResult) => {
|
(matchResult) => {
|
||||||
const stageId = matchResult[1]
|
const stageId = matchResult[1]
|
||||||
return `/tasks/${stageId}/choose_build.json`
|
return `/tasks/${stageId}/choose_build.json`
|
||||||
|
@ -50,4 +65,20 @@ export function requestProxy(config) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
('/api/v1/careers/qweqw/edit/').match(/\/api\/v1\/careers\/(\w*)\/edit/i)
|
||||||
|
0: "/api/v1/careers/qweqw/edit"
|
||||||
|
1: "qweqw"
|
||||||
|
|
||||||
|
example:
|
||||||
|
`/api/v1/games/${this.props.game.identifier}/answer_grade` ->
|
||||||
|
`/tasks/${this.props.game.identifier}/answer_grade.json`
|
||||||
|
|
||||||
|
|
||||||
|
https://testeduplus2.educoder.net/api/v1/games/feguz4tiqpvx/rep_content
|
||||||
|
?path=src/step2/CLnkQueue.cpp&shixun_gpid=2791&status=0&retry=0 ->
|
||||||
|
http://testeduplus2.educoder.net/tasks/tonblikwzj78/rep_content.json
|
||||||
|
?path=1-4.py&shixun_gpid=2448&status=0
|
||||||
|
*/
|
|
@ -1366,6 +1366,10 @@ samp {
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.courseForm .ant-input-group>.ant-input:first-child,
|
||||||
|
.ant-input-group-addon:first-child {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.courseForm .ant-select-selection,
|
.courseForm .ant-select-selection,
|
||||||
.courseForm .ant-select-selection-selected-value {
|
.courseForm .ant-select-selection-selected-value {
|
||||||
|
@ -1718,6 +1722,12 @@ samp {
|
||||||
background-color: #fff !important;
|
background-color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-input-group-addon {
|
||||||
|
color: #666 !important;
|
||||||
|
font-size: 12px;
|
||||||
|
border: 1px solid #d9d9d9 !important;
|
||||||
|
border-left: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.check_on {
|
.check_on {
|
||||||
background: #4CACFF;
|
background: #4CACFF;
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import React, {Component} from "react";
|
import React, { Component } from "react";
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { getImageUrl } from 'educoder';
|
import { getImageUrl } from 'educoder';
|
||||||
import '../courses/css/members.css';
|
import '../courses/css/members.css';
|
||||||
import "../courses/common/formCommon.css";
|
import "../courses/common/formCommon.css"
|
||||||
import '../courses/css/Courses.css';
|
import '../courses/css/Courses.css';
|
||||||
import beijintulogontwo from '../../../src/images/login/beijintulogontwo.png';
|
import beijintulogontwo from '../../../src/images/login/beijintulogontwo.png';
|
||||||
import educodernet from '../../../src/images/login/educodernet.png';
|
import educodernet from '../../../src/images/login/logo.png';
|
||||||
import LoginRegisterComponent from '../user/LoginRegisterComponent';
|
import LoginRegisterComponent from '../user/LoginRegisterComponent';
|
||||||
import FindPasswordComponent from '../user/FindPasswordComponent';
|
import FindPasswordComponent from '../user/FindPasswordComponent';
|
||||||
//educoder登入页面
|
|
||||||
|
|
||||||
var newContainer={
|
var newContainer={
|
||||||
background: `url(${beijintulogontwo})`,
|
background: `url(${beijintulogontwo})`,
|
||||||
|
@ -47,7 +46,6 @@ class EducoderLogin extends Component {
|
||||||
|
|
||||||
}
|
}
|
||||||
}else if(props.match.url === "/register"){
|
}else if(props.match.url === "/register"){
|
||||||
// showbool: 1,
|
|
||||||
this.state = {
|
this.state = {
|
||||||
showbool: 1,
|
showbool: 1,
|
||||||
loginstatus:false,
|
loginstatus:false,
|
||||||
|
@ -64,18 +62,12 @@ class EducoderLogin extends Component {
|
||||||
loginstatus:true,
|
loginstatus:true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Setlogins=(i)=>{
|
Setlogins=(i)=>{
|
||||||
console.log("96ye");
|
|
||||||
console.log(i)
|
|
||||||
this.setState({
|
this.setState({
|
||||||
logini:i
|
logini:i
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
gohome=()=>{
|
gohome=()=>{
|
||||||
window.location.href="/"
|
window.location.href="/"
|
||||||
|
@ -94,84 +86,39 @@ class EducoderLogin extends Component {
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {showbool,loginstatus,logini} = this.state;
|
let { showbool } = this.state;
|
||||||
|
const { settings } = this.props;
|
||||||
return (
|
return (
|
||||||
<div style={newContainer} className=" clearfix" >
|
<div style={newContainer} className=" clearfix" >
|
||||||
|
<div style={{"justify-content": "center","align-items": "center","width": "100%",textAlign:"center"}}>
|
||||||
<div >
|
<div style={{cursor:"pointer"}}>
|
||||||
<div style={{
|
{
|
||||||
"display": "flex",
|
settings && settings.login_logo_url ?
|
||||||
"justify-content": "center",
|
<img style={{cursor:"pointer"}} alt="" onClick={()=>this.gohome()} width="80px" src={getImageUrl(settings.login_logo_url)}/>
|
||||||
"align-items": "center",
|
:
|
||||||
"width": "100%"
|
<img style={{cursor:"pointer"}} alt="" onClick={()=>this.gohome()} src={educodernet} width="80px"/>
|
||||||
}}>
|
}
|
||||||
<div style={{cursor:"pointer"}}>
|
|
||||||
{this.props.mygetHelmetapi === null ? ""
|
|
||||||
:
|
|
||||||
this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.login_logo_url===null|| this.props.mygetHelmetapi.login_logo_url===undefined?
|
|
||||||
<img style={{cursor:"pointer"}} onClick={()=>this.gohome()} src={educodernet}/>
|
|
||||||
:
|
|
||||||
<img style={{cursor:"pointer"}} onClick={()=>this.gohome()} src={getImageUrl(this.props.mygetHelmetapi.login_logo_url)}/>
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
showbool === 1 ?
|
showbool === 1 ?
|
||||||
<div style={{
|
<div style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
marginTop: "25px",
|
marginTop: "25px",
|
||||||
}}>
|
}}>
|
||||||
<div>
|
<div>
|
||||||
|
<LoginRegisterComponent {...this.props} {...this.state} Setshowbool={(e)=>this.Setshowbool(e)} ></LoginRegisterComponent>
|
||||||
<LoginRegisterComponent {...this.props} {...this.state}
|
|
||||||
Setshowbool={(e)=>this.Setshowbool(e)} ></LoginRegisterComponent>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
:
|
:
|
||||||
<div style={{
|
<div style={{display: "flex",justifyContent: "center",width: "100%",marginTop: "25px",}}>
|
||||||
display: "flex",
|
<div>
|
||||||
justifyContent: "center",
|
<FindPasswordComponent {...this.props} {...this.state} Setshowbool={(e)=>this.Setshowbool(e)}></FindPasswordComponent>
|
||||||
width: "100%",
|
</div>
|
||||||
marginTop: "25px",
|
</div>
|
||||||
}}>
|
|
||||||
<div >
|
|
||||||
<FindPasswordComponent {...this.props} {...this.state}
|
|
||||||
Setshowbool={(e)=>this.Setshowbool(e)}></FindPasswordComponent>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
{this.props.mygetHelmetapi === null ? <div style={{
|
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} Trustie<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "100%",
|
|
||||||
}}>
|
|
||||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
|
||||||
</div>:
|
|
||||||
this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.main_site===null|| this.props.mygetHelmetapi.main_site===undefined? <div style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "100%",
|
|
||||||
}}>
|
|
||||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
|
||||||
</div>:this.props.mygetHelmetapi.main_site===true?
|
|
||||||
<div style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
width: "100%",
|
|
||||||
}}>
|
|
||||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
|
||||||
</div>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import Dialog from 'material-ui/Dialog';
|
||||||
import { notification } from 'antd';
|
import { notification } from 'antd';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import educoderLogo from './educoder.png';
|
|
||||||
|
|
||||||
import './LoginDialog.css';
|
import './LoginDialog.css';
|
||||||
import { broadcastChannelPostMessage } from 'educoder'
|
import { broadcastChannelPostMessage } from 'educoder'
|
||||||
|
@ -302,9 +301,12 @@ class LoginDialog extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isRender: nextProps.isRender
|
isRender: nextProps.isRender
|
||||||
})
|
})
|
||||||
|
// console.log(nextProps.isRender);
|
||||||
|
|
||||||
}
|
}
|
||||||
IsPC = () => {
|
IsPC = () => {
|
||||||
var userAgentInfo = navigator.userAgent;
|
var userAgentInfo = navigator.userAgent;
|
||||||
|
@ -321,8 +323,8 @@ class LoginDialog extends Component {
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
//true为PC端,false为手机端
|
|
||||||
let flag = this.IsPC();
|
let flag = this.IsPC(); //true为PC端,false为手机端
|
||||||
this.setState({
|
this.setState({
|
||||||
isphone: flag
|
isphone: flag
|
||||||
})
|
})
|
||||||
|
@ -354,6 +356,7 @@ class LoginDialog extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
loginEDU = () => {
|
loginEDU = () => {
|
||||||
|
|
||||||
let { loginValue, passValue, regular, isGoingValue } = this.state;
|
let { loginValue, passValue, regular, isGoingValue } = this.state;
|
||||||
if (regular === 1) {
|
if (regular === 1) {
|
||||||
return
|
return
|
||||||
|
@ -375,8 +378,15 @@ class LoginDialog extends Component {
|
||||||
if (response.data.message === "登录密码出错已达上限,账号已被锁定, 请10分钟后重新登录或找回密码") {
|
if (response.data.message === "登录密码出错已达上限,账号已被锁定, 请10分钟后重新登录或找回密码") {
|
||||||
const messge = (
|
const messge = (
|
||||||
<div>
|
<div>
|
||||||
<p>登录密码出错已达上限,账号已被锁定;</p>
|
<p>
|
||||||
<p className="mt10">请10分钟后重新登录或<a href={'https://www.trustie.net/account/lost_password'} style={{textDecoration: "underline",color: "#4CACFF"}}>找回密码</a></p>
|
登录密码出错已达上限,账号已被锁定;
|
||||||
|
</p>
|
||||||
|
<p className="mt10">
|
||||||
|
请10分钟后重新登录或<a href={'https://www.trustie.net/account/lost_password'} style={{
|
||||||
|
textDecoration: "underline",
|
||||||
|
color: "#4CACFF",
|
||||||
|
}}>找回密码</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
this.openNotifications(messge);
|
this.openNotifications(messge);
|
||||||
|
@ -420,6 +430,11 @@ class LoginDialog extends Component {
|
||||||
getloginurl = (url) => {
|
getloginurl = (url) => {
|
||||||
window.location.href = url;
|
window.location.href = url;
|
||||||
};
|
};
|
||||||
|
openweixinlogin = () => {
|
||||||
|
this.setState({
|
||||||
|
weixinlogin: true
|
||||||
|
})
|
||||||
|
}
|
||||||
openNotifications = (btn) => {
|
openNotifications = (btn) => {
|
||||||
// type 1 成功提示绿色 2提醒颜色黄色 3错误提示红色
|
// type 1 成功提示绿色 2提醒颜色黄色 3错误提示红色
|
||||||
notification.open({
|
notification.open({
|
||||||
|
@ -455,16 +470,18 @@ class LoginDialog extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { login, isGoing, isGoingValue, disabled , Phonenumberisnotco , dialogBox, isRender, weixinlogin } = this.state;
|
let { qqlogin, login, isGoing, isGoingValue, disabled, bottonclass, Phonenumberisnotco,
|
||||||
let { settings } = this.props;
|
dialogBox, isRender, weixinlogin } = this.state;
|
||||||
|
|
||||||
|
let { settings } = this.props;
|
||||||
if (isRender === undefined) {
|
if (isRender === undefined) {
|
||||||
isRender = false
|
isRender = false
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={true} id="DialogID"
|
<Dialog open={true} id="DialogID"
|
||||||
className="zindextest"
|
className="zindextest"
|
||||||
style={{ display: isRender === false ? 'none' : '' }}
|
style={{ display: isRender == false ? 'none' : '' }}
|
||||||
disableEscapeKeyDown={true}
|
disableEscapeKeyDown={true}
|
||||||
disableBackdropClick={true}
|
disableBackdropClick={true}
|
||||||
onClose={() => this.handleDialogClose()}
|
onClose={() => this.handleDialogClose()}
|
||||||
|
@ -495,7 +512,7 @@ class LoginDialog extends Component {
|
||||||
<li onClick={() => { this.enter(0) }}>登录</li>
|
<li onClick={() => { this.enter(0) }}>登录</li>
|
||||||
</ul>}
|
</ul>}
|
||||||
<div className="login-panel" id="login-panel-1" style={{ display: login == 0 ? 'block' : 'none' }}>
|
<div className="login-panel" id="login-panel-1" style={{ display: login == 0 ? 'block' : 'none' }}>
|
||||||
<form acceptCharset="UTF-8" action="/login" id="main_login_form" method="post">
|
{weixinlogin === true ? "" : <form acceptCharset="UTF-8" action="/login" id="main_login_form" method="post">
|
||||||
|
|
||||||
<div style={{ "display": "inline", "padding": "0", "margin": "0" }}>
|
<div style={{ "display": "inline", "padding": "0", "margin": "0" }}>
|
||||||
<input name="utf8" type="hidden" value="✓"></input>
|
<input name="utf8" type="hidden" value="✓"></input>
|
||||||
|
@ -520,10 +537,9 @@ class LoginDialog extends Component {
|
||||||
|
|
||||||
<div style={{ height: '25px' }}><p className="color-orange edu-txt-left none" id="username_error_notice"
|
<div style={{ height: '25px' }}><p className="color-orange edu-txt-left none" id="username_error_notice"
|
||||||
style={{ display: Phonenumberisnotco === undefined ? 'none' : 'block' }}>{Phonenumberisnotco}</p></div>
|
style={{ display: Phonenumberisnotco === undefined ? 'none' : 'block' }}>{Phonenumberisnotco}</p></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input type="password" id="password_loggin_input"
|
||||||
type="password"
|
|
||||||
id="password_loggin_input"
|
|
||||||
name="password"
|
name="password"
|
||||||
ref="passwordText"
|
ref="passwordText"
|
||||||
onInput={this.passwordChange}
|
onInput={this.passwordChange}
|
||||||
|
@ -533,8 +549,8 @@ class LoginDialog extends Component {
|
||||||
this.loginEDU : () => {
|
this.loginEDU : () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
placeholder="密码"
|
placeholder="密码" >
|
||||||
/>
|
</input>
|
||||||
<div style={{ height: '25px' }}>
|
<div style={{ height: '25px' }}>
|
||||||
<p className="color-orange edu-txt-left none" id="password_error_notice">
|
<p className="color-orange edu-txt-left none" id="password_error_notice">
|
||||||
请输入密码
|
请输入密码
|
||||||
|
@ -565,25 +581,38 @@ class LoginDialog extends Component {
|
||||||
<a onClick={(url) => this.getloginurl(`${settings && settings.common && settings.common.register}`)} className="color-grey-9">注册</a>
|
<a onClick={(url) => this.getloginurl(`${settings && settings.common && settings.common.register}`)} className="color-grey-9">注册</a>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
{
|
|
||||||
settings && settings.third_party && settings.third_party.length > 0 ?
|
{this.props.user && this.props.user.main_site === true ? this.state.isphone === true ? <p className="clearfix mt20">
|
||||||
<p className="clearfix mt20">
|
<span className={"startlogin"}>———————— 快速登录 ————————</span>
|
||||||
|
<div className={"mt10"}>
|
||||||
|
<a onClick={() => this.openweixinlogin()}>
|
||||||
|
<img src={require('./WeChat.png')} alt="微信登录" />
|
||||||
|
</a>
|
||||||
|
<a onClick={() => this.openqqlogin()} className={"ml10"}>
|
||||||
|
<img src={require('./qq.png')} alt="qq登录" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</p> : <p className="clearfix mt20">
|
||||||
|
|
||||||
<span className={"startlogin"}>———————— 快速登录 ————————</span>
|
<span className={"startlogin"}>———————— 快速登录 ————————</span>
|
||||||
<div className={"mt10"}>
|
<div className={"mt10"}>
|
||||||
{settings.third_party.map((item,key)=>{
|
<a onClick={() => this.openphoneqqlogin()} className={"ml10"}>
|
||||||
return(
|
<img src={require('./qq.png')} alt="qq登录" />
|
||||||
<a href={`${item.url}`}>
|
</a>
|
||||||
<img src={item.name === "educoder" ? educoderLogo : ""} width="46px" alt={`${item.name}登录`} />
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p> : ""}
|
||||||
:""
|
</form>}
|
||||||
}
|
{weixinlogin === true ? <iframe
|
||||||
</form>
|
className={"weixinheight390"}
|
||||||
|
frameBorder="0"
|
||||||
|
sandbox="allow-scripts allow-same-origin allow-top-navigation"
|
||||||
|
scrolling="no"
|
||||||
|
src={`https://open.weixin.qq.com/connect/qrconnect?appid=wx6b119e2d829c13fa&redirect_uri=https%3a%2f%2fwww.educoder.net%2fotherloginstart&response_type=code&scope=snsapi_login&state=null,${window.location.host}#wechat_redirect`}></iframe> : ""}
|
||||||
|
{weixinlogin === true ? <p className="clearfix ">
|
||||||
|
<a className={"startlogin color-blue"} onClick={() => this.hideweixinlogin()}>返回账号登录</a>
|
||||||
|
</p> : ""}
|
||||||
</div>
|
</div>
|
||||||
|
{/*快捷登录*/}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
: ""}
|
: ""}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
|
@ -1062,7 +1062,7 @@ class TPMBanner extends Component {
|
||||||
</div> :
|
</div> :
|
||||||
<div className="task-popup-content">
|
<div className="task-popup-content">
|
||||||
<p className="task-popup-text-center font-16 mt10 mb10">
|
<p className="task-popup-text-center font-16 mt10 mb10">
|
||||||
尚未创建任务的实训,不能申请发布
|
尚未创建易修的实训,不能申请发布
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import axios from 'axios';
|
||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
import './TPMIndex.css';
|
import './TPMIndex.css';
|
||||||
import LoginDialog from '../login/LoginDialog';
|
import LoginDialog from '../login/LoginDialog';
|
||||||
import EducoderAccount from '../../forge/Component/EducoderAccount';
|
|
||||||
|
|
||||||
export function TPMIndexHOC(WrappedComponent) {
|
export function TPMIndexHOC(WrappedComponent) {
|
||||||
return class II extends React.Component {
|
return class II extends React.Component {
|
||||||
|
@ -206,14 +205,13 @@ export function TPMIndexHOC(WrappedComponent) {
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { isRender , current_user , giteaVisible , email } = this.state;
|
let { isRender , current_user } = this.state;
|
||||||
const common = {
|
const common = {
|
||||||
showLoginDialog: this.showLoginDialog,
|
showLoginDialog: this.showLoginDialog,
|
||||||
checkIfLogin: this.checkIfLogin,
|
checkIfLogin: this.checkIfLogin,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div className="indexHOC">
|
<div className="indexHOC">
|
||||||
<EducoderAccount visible={giteaVisible} email={email} onOk={this.onOk}/>
|
|
||||||
{isRender === true ? <LoginDialog
|
{isRender === true ? <LoginDialog
|
||||||
Modifyloginvalue={() => this.hideLoginDialog()}
|
Modifyloginvalue={() => this.hideLoginDialog()}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue