diff --git a/public/css/edu-purge.css b/public/css/edu-purge.css index 11e90f7d2..1dc17448b 100644 --- a/public/css/edu-purge.css +++ b/public/css/edu-purge.css @@ -1753,7 +1753,7 @@ a.decoration { } .mb15 { - margin-bottom: 15px; + margin-bottom: 15px!important; } .mb16 { @@ -6685,4 +6685,10 @@ p{ right: 0px; top:4px; color: #999; +} +.ant-input, .ant-input .ant-input-suffix{ + background-color: #fff!important; +} +.has-error .ant-input{ + background-color: #FEF1F0!important; } \ No newline at end of file diff --git a/public/css/iconfont.css b/public/css/iconfont.css index 32cb789aa..fbd30d52c 100644 --- a/public/css/iconfont.css +++ b/public/css/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 2340181 */ - src: url('iconfont.woff2?t=1625800786751') format('woff2'), - url('iconfont.woff?t=1625800786751') format('woff'), - url('iconfont.ttf?t=1625800786751') format('truetype'); + src: url('iconfont.woff2?t=1626838578464') format('woff2'), + url('iconfont.woff?t=1626838578464') format('woff'), + url('iconfont.ttf?t=1626838578464') format('truetype'); } .iconfont { @@ -13,6 +13,34 @@ -moz-osx-font-smoothing: grayscale; } +.icon-erciqueren_icon:before { + content: "\e867"; +} + +.icon-xuanzhongssh_icon:before { + content: "\e868"; +} + +.icon-weixuanzhonganquanshezhi_icon:before { + content: "\e869"; +} + +.icon-weixuanzhongssh_icon:before { + content: "\e86a"; +} + +.icon-xuanzhonganquanshezhi_icon:before { + content: "\e86b"; +} + +.icon-shanchu_icon:before { + content: "\e86c"; +} + +.icon-liebiaossh_icon:before { + content: "\e86e"; +} + .icon-file-submodule:before { content: "\e866"; } diff --git a/public/css/iconfont.js b/public/css/iconfont.js index c4fb710fb..77ba176ff 100644 --- a/public/css/iconfont.js +++ b/public/css/iconfont.js @@ -1 +1 @@ -!function(c){var l,a,h,i,o,z,t='',p=(p=document.getElementsByTagName("script"))[p.length-1].getAttribute("data-injectcss");if(p&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}function v(){o||(o=!0,h())}l=function(){var c,l,a;(a=document.createElement("div")).innerHTML=t,t=null,(l=a.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",c=l,(a=document.body).firstChild?(l=a.firstChild).parentNode.insertBefore(c,l):a.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(a=function(){document.removeEventListener("DOMContentLoaded",a,!1),l()},document.addEventListener("DOMContentLoaded",a,!1)):document.attachEvent&&(h=l,i=c.document,o=!1,(z=function(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(z,50)}v()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,v())})}(window); \ No newline at end of file +!function(c){var l,a,h,i,o,z,t='',p=(p=document.getElementsByTagName("script"))[p.length-1].getAttribute("data-injectcss");if(p&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}function v(){o||(o=!0,h())}l=function(){var c,l,a;(a=document.createElement("div")).innerHTML=t,t=null,(l=a.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",c=l,(a=document.body).firstChild?(l=a.firstChild).parentNode.insertBefore(c,l):a.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(a=function(){document.removeEventListener("DOMContentLoaded",a,!1),l()},document.addEventListener("DOMContentLoaded",a,!1)):document.attachEvent&&(h=l,i=c.document,o=!1,(z=function(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(z,50)}v()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,v())})}(window); \ No newline at end of file diff --git a/public/css/iconfont.json b/public/css/iconfont.json index 43c5fbfbb..44d85cac9 100644 --- a/public/css/iconfont.json +++ b/public/css/iconfont.json @@ -5,6 +5,55 @@ "css_prefix_text": "icon-", "description": "", "glyphs": [ + { + "icon_id": "22906287", + "name": "二次确认_icon", + "font_class": "erciqueren_icon", + "unicode": "e867", + "unicode_decimal": 59495 + }, + { + "icon_id": "22906288", + "name": "选中ssh_icon", + "font_class": "xuanzhongssh_icon", + "unicode": "e868", + "unicode_decimal": 59496 + }, + { + "icon_id": "22906289", + "name": "未选中安全设置_icon", + "font_class": "weixuanzhonganquanshezhi_icon", + "unicode": "e869", + "unicode_decimal": 59497 + }, + { + "icon_id": "22906290", + "name": "未选中ssh_icon", + "font_class": "weixuanzhongssh_icon", + "unicode": "e86a", + "unicode_decimal": 59498 + }, + { + "icon_id": "22906291", + "name": "选中安全设置_icon", + "font_class": "xuanzhonganquanshezhi_icon", + "unicode": "e86b", + "unicode_decimal": 59499 + }, + { + "icon_id": "22906292", + "name": "删除_icon", + "font_class": "shanchu_icon", + "unicode": "e86c", + "unicode_decimal": 59500 + }, + { + "icon_id": "22906293", + "name": "列表ssh_icon", + "font_class": "liebiaossh_icon", + "unicode": "e86e", + "unicode_decimal": 59502 + }, { "icon_id": "17575494", "name": "file-submodule", diff --git a/public/css/iconfont.ttf b/public/css/iconfont.ttf index 96f61dcb8..662bd6630 100644 Binary files a/public/css/iconfont.ttf and b/public/css/iconfont.ttf differ diff --git a/public/css/iconfont.woff b/public/css/iconfont.woff index 67761f2ca..6b554c8a3 100644 Binary files a/public/css/iconfont.woff and b/public/css/iconfont.woff differ diff --git a/public/css/iconfont.woff2 b/public/css/iconfont.woff2 index ca08e83e2..171927971 100644 Binary files a/public/css/iconfont.woff2 and b/public/css/iconfont.woff2 differ diff --git a/src/App.js b/src/App.js index fd228f397..f59412c8c 100644 --- a/src/App.js +++ b/src/App.js @@ -39,6 +39,11 @@ const Projects = Loadable({ loader: () => import('./forge/Index'), loading: Loading, }) +//forge安全设置 +const Security = Loadable({ + loader: () => import('./forge/SecuritySetting/Index'), + loading: Loading, +}) //forge项目-devOps详情 const OpsDetail = Loadable({ loader: () => import('./forge/DevOps/opsDetail'), @@ -206,6 +211,14 @@ class App extends Component { } }> + { + return () + } + }> + {/*项目*/} { + function jsCopy(){ var e = document.getElementById("copy_rep_content"); e.select(); document.execCommand("Copy"); } - render() { - const { http_url, downloadUrl } = this.props; - return ( -
- {/*

版本库地址已变更,请基于新地址提交代码

*/} - { - http_url && HTTP - } - - - this.jsCopy()}> - - { - downloadUrl && - - - - - - - - } + return ( +
+
+ + {setKey(e.key)}}>HTTP + {setKey(e.key)}}>SSH + +
+ + + + +
- ) - } + + 下载 ZIP + 下载 TAR.GZ + +
+ ) } export default CloneAddress; \ No newline at end of file diff --git a/src/forge/Branch/Select.jsx b/src/forge/Branch/Select.jsx index f33a716fb..fedd288c1 100644 --- a/src/forge/Branch/Select.jsx +++ b/src/forge/Branch/Select.jsx @@ -1,6 +1,6 @@ import React , { useState , useEffect } from 'react'; import { Popover , Input , Spin } from 'antd'; -import './branch.css'; +import './branch.scss'; import { getBranch , getTag } from '../GetData/getData'; diff --git a/src/forge/Branch/branch.css b/src/forge/Branch/branch.scss similarity index 77% rename from src/forge/Branch/branch.css rename to src/forge/Branch/branch.scss index 962b01970..bdd4aa397 100644 --- a/src/forge/Branch/branch.css +++ b/src/forge/Branch/branch.scss @@ -81,4 +81,25 @@ .listTips{ padding:20px 0px; text-align: center; +} + +.urlMenu{ + line-height: 30px; + margin-bottom: 10px; + border-bottom: none; + li.ant-menu-item{ + height: 30px; + line-height: 30px; + padding:0px 5px; + margin-right: 20px!important; + &.ant-menu-item-selected,&.ant-menu-item-active{ + color: #333; + } + &.ant-menu-item-selected{ + border-color:#1890ff!important; + } + &.ant-menu-item-active{ + border-color:transparent ; + } + } } \ No newline at end of file diff --git a/src/forge/Head/Footer.jsx b/src/forge/Head/Footer.jsx index 8a69c2ad1..568583ea5 100644 --- a/src/forge/Head/Footer.jsx +++ b/src/forge/Head/Footer.jsx @@ -19,7 +19,7 @@ function Footer(){ return(
-
+
{value && showhtml(value)} {/*
diff --git a/src/forge/Head/Header.js b/src/forge/Head/Header.js index d02430891..7364ebd38 100644 --- a/src/forge/Head/Header.js +++ b/src/forge/Head/Header.js @@ -3,9 +3,9 @@ import AccountProfile from "../../modules/user/AccountProfile"; import { getImageUrl } from 'educoder' import axios from 'axios'; import { Input , notification , Dropdown , Menu } from 'antd'; +import { Link } from 'react-router-dom'; import LoginDialog from '../../modules/login/LoginDialog'; -import GotoQQgroup from '../../modal/GotoQQgroup'; import HeadSearch from '../Component/HeadSearch'; import AddProjectModal from './AddProjectModal'; @@ -79,36 +79,6 @@ class NewHeader extends Component { } catch (e) {} } - // SearchInput = (open,item)=>{ - // if(open){ - // return( - //
{ - // setTimeout(() => { - // this.setState({ - // openSearch:false - // }) - // }, 300) - // }} - // > - // this.onGlobalSearch(value,item)} - // autoFocus={true} - // /> - //
- // ) - // }else{ - // return { - // this.setState({openSearch:true}) - // }} /> - // } - // } - - // onGlobalSearch=(value,item)=>{ - // window.location.href=`${item}?value=` + value; - // } - openNotification = (messge) => { notification.open({ message: "提示", @@ -117,8 +87,6 @@ class NewHeader extends Component { }); }; - - componentWillReceiveProps(newProps, oldProps) { this.setState({ user: newProps.user @@ -128,7 +96,6 @@ class NewHeader extends Component { } } - educoderlogin = () => { //登录账号 this.setState({ @@ -166,13 +133,11 @@ class NewHeader extends Component { }) }; - // 关闭 cancelModulationModels = () => { this.setState({ isRenders: false }) } - setevaluatinghides = () => { this.setState({ setevaluatinghides: true @@ -289,6 +254,7 @@ class NewHeader extends Component { ) }) } +
  • 设置
  • this.educoderloginysl()}>退出 ) @@ -297,17 +263,13 @@ class NewHeader extends Component { render() { const { match} = this.props; let current_user = this.props.user; - let { Addcoursestypes, - tojoinitemtype, - tojoinclasstitle, - code_notice, + let { AccountProfiletype, user, isRender, headtypesonClickbool, headtypess, settings, - openSearch, } = this.state; /*用户名称 用户头像url*/ let activeIndex = false; diff --git a/src/forge/Main/CoderDepot.jsx b/src/forge/Main/CoderDepot.jsx index eab51dc55..32121077b 100644 --- a/src/forge/Main/CoderDepot.jsx +++ b/src/forge/Main/CoderDepot.jsx @@ -253,17 +253,12 @@ function CoderDepot(props){ } const downloadMenu = ( -
    -
    - -
    - - 下载 ZIP - 下载 TAR.GZ - -
    + ) // 确认修改简介、website、实践课程链接 function okUpdate(d,w,l){ diff --git a/src/forge/Main/Index.scss b/src/forge/Main/Index.scss index 592002e9d..cb05f1cf2 100644 --- a/src/forge/Main/Index.scss +++ b/src/forge/Main/Index.scss @@ -319,6 +319,7 @@ } } .downMenu{ + width: 330px; box-shadow: 0px 0px 9px rgba(134, 134, 134,0.4); background-color: #fff; .ant-menu-vertical .ant-menu-item:hover{ diff --git a/src/forge/Main/NullData.js b/src/forge/Main/NullData.js index a550b5bcc..1621d657c 100644 --- a/src/forge/Main/NullData.js +++ b/src/forge/Main/NullData.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import "../Branch/branch.css" +import "../Branch/branch.scss" diff --git a/src/forge/SecuritySetting/Index.jsx b/src/forge/SecuritySetting/Index.jsx new file mode 100644 index 000000000..e314c66a2 --- /dev/null +++ b/src/forge/SecuritySetting/Index.jsx @@ -0,0 +1,68 @@ +import React from "react"; + +import { Route, Switch } from "react-router-dom"; +import { withRouter } from "react-router"; + +import { SnackbarHOC } from "educoder"; +import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC"; +import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC"; +import Loadable from "react-loadable"; +import Loading from "../../Loading"; +import { Box , Gap , LongWidth } from '../Component/layout'; +import { getImageUrl } from 'educoder'; +import { Link } from 'react-router-dom'; + +import './Index.scss'; + +const SSHNew = Loadable({ + loader: () => import("./sub/New"), + loading: Loading, +}); +const SSHIndex = Loadable({ + loader: () => import("./sub/SSH"), + loading: Loading, +}); +function Index(props){ + const { current_user } = props; + const { pathname } = props.location; + + return( +
    +
    + +
    +
    + + {current_user && current_user.username} +
    +
      +
    • 安全设置
    • +
    • -1 ?"active":""}>SSH密钥
    • +
    +
    + + + + ( + + )} + > + ( + + )} + > + + + +
    +
    + +
    + ) +} +export default withRouter((CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index)))) +); \ No newline at end of file diff --git a/src/forge/SecuritySetting/Index.scss b/src/forge/SecuritySetting/Index.scss new file mode 100644 index 000000000..664ed7ab4 --- /dev/null +++ b/src/forge/SecuritySetting/Index.scss @@ -0,0 +1,192 @@ +.whiteBack{ + background-color: #fff; + .boies{ + width: 1200px; + margin:0px auto; + padding:30px 0px 10px; + .shortW{ + width: 198px; + border: 1px solid rgba(153, 153, 153, 0.22); + border-radius: 4px; + min-height: 400px; + margin-bottom: 30px; + .userDetail{ + background: rgba(153, 153, 153, 0.05); + border-radius: 4px 4px 0px 0px; + padding:20px 25px; + display: flex; + align-items: center; + justify-content: flex-start; + img{ + height: 48px; + width: 48px; + border-radius: 50%; + margin-right: 12px; + } + span{ + font-size: 16px; + color: #333; + max-width: 90px; + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } + .securityUl{ + padding:20px 16px; + color: #333; + li{ + margin-bottom: 10px; + height: 27px; + line-height: 27px; + position: relative; + cursor: pointer; + a{ + color: #666; + &:hover{ + color: #333; + } + } + &.active a{ + color: #333; + } + &:first-child{ + font-size: 16px; + } + &.active::before{ + position: absolute; + left: -16px; + top:0px; + height: 100%; + width: 2px; + content: ""; + background-color: #2A61FF; + } + } + } + } + .sshHead{ + display: flex; + align-items: center; + padding:15px 20px; + justify-content: space-between; + border-bottom: 1px solid #EEEEEE; + &>span{ + font-size: 18px; + } + } + .ant-list-item{ + padding:20px; + border-bottom: 1px solid #eee!important; + &>img{ + margin-right: 24px; + } + &>div{ + flex:1; + width: 0; + margin-right: 20px; + p{ + margin-bottom: 8px!important; + } + span{ + font-size: 12px; + } + } + .ant-btn.ant-btn-danger{ + background-color: #fff; + border-color: #D0D0D0; + color: #DF0002; + &:hover{ + background-color: #DF0002; + color: #fff; + border-color: #DF0002; + } + } + } + .questionLink{ + padding:15px 20px; + a{ + color: #4B7AFF; + &:hover{ + text-decoration: underline; + } + } + } + .sshForm{ + padding:15px 20px; + .ant-col.ant-form-item-label{ + font-size: 16px; + color:#333; + } + } + } +} +.deleteBox{ + .ant-modal-header{ + background-color: rgba(223, 0, 2, 0.06); + border-bottom: none; + .ant-modal-title{ + text-align: left; + font-size: 20px; + } + } + .ant-modal-body{ + padding:30px 50px; + p{ + font-size: 16px; + line-height: 26px; + color:#666 + } + .desc{ + .descMain{ + align-items: center; + justify-content: center; + font-size: 20px; + margin-bottom: 10px; + i{ + font-size: 38px!important; + color:#DF0002 + } + } + } + } + .ant-modal-footer{ + border-top: none; + text-align: center; + padding-bottom: 40px; + button{ + width: 120px; + margin:0px 20px; + &.ant-btn-danger{ + background-color: #fff; + color: #DF0002; + border-color: #D0D0D0; + } + } + } +} +.descModal{ + .ant-modal-title{ + text-align: left; + font-size: 20px; + } + .keyContent{ + border:1px solid #eee; + border-radius: 4px; + padding:10px 15px; + margin-top: 10px; + max-height: 200px; + overflow-y: auto; + } + .keysTitle{ + display: flex; + align-items: flex-start; + justify-content: flex-start; + flex-wrap: wrap; + span:last-child{ + word-break: break-all; + flex:1; + } + } +} \ No newline at end of file diff --git a/src/forge/SecuritySetting/img/miyao_middle_icon.png b/src/forge/SecuritySetting/img/miyao_middle_icon.png new file mode 100644 index 000000000..03584cfe3 Binary files /dev/null and b/src/forge/SecuritySetting/img/miyao_middle_icon.png differ diff --git a/src/forge/SecuritySetting/sub/DeleteBox.jsx b/src/forge/SecuritySetting/sub/DeleteBox.jsx new file mode 100644 index 000000000..af8b64189 --- /dev/null +++ b/src/forge/SecuritySetting/sub/DeleteBox.jsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { AlignCenter } from '../../Component/layout'; +import { Modal , Button } from 'antd'; + +function DeleteBox({ visible , onCancel ,onSuccess }) { + + return( + + + +
    + } + > +
    + 您确定要删除此 SSH 密钥吗? +

    此操作将永久删除该SSH密钥,且不可恢复。如果您想再次使用该密钥,则需要您重新上传。

    +
    + + ) +} +export default DeleteBox; \ No newline at end of file diff --git a/src/forge/SecuritySetting/sub/New.jsx b/src/forge/SecuritySetting/sub/New.jsx new file mode 100644 index 000000000..68a65db37 --- /dev/null +++ b/src/forge/SecuritySetting/sub/New.jsx @@ -0,0 +1,59 @@ +import React , { forwardRef, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { Button, Form , Input } from 'antd'; +import Axios from 'axios'; + +const { TextArea } = Input; +function New({ form , showNotification , history }) { + const { getFieldDecorator, validateFields , setFieldsValue } = form; + const [ msg , setMsg ] = useState(undefined); + + function submit() { + validateFields((error,values)=>{ + if(!error){ + const url = `/public_keys.json`; + Axios.post(url,{ + ...values + }).then(result=>{ + if(result){ + if(result.data.status === 0){ + history.push(`/settings/SSH`); + showNotification("密钥创建成功!"); + } + let s = { + status:result.data.status, + message:result.data.message + } + setMsg(s); + } + }).catch(error=>{}) + } + }) + } + + return( +
    +
    + SSH密钥添加SSH密钥 +
    +
    + + {getFieldDecorator("title",{ + rules:[{required:true,message:"请输入密钥标题"}] + })( + + )} + + + {getFieldDecorator("key",{ + rules:[{required:true,message:"请输入密钥"}] + })( +