diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4771ae99a..9ea84263c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3425,9 +3425,9 @@ "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" }, "clipboard": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", - "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", + "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", "requires": { "good-listener": "^1.2.2", "select": "^1.1.2", @@ -7286,7 +7286,8 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true }, "aproba": { "version": "1.2.0", @@ -7703,7 +7704,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -7759,6 +7761,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7802,12 +7805,14 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "optional": true }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true } } }, diff --git a/package.json b/package.json index ff7a86851..04142cb4d 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "case-sensitive-paths-webpack-plugin": "2.1.1", "chalk": "1.1.3", "classnames": "^2.2.5", - "clipboard": "^2.0.6", + "clipboard": "^2.0.8", "code-prettify": "^0.1.0", "codemirror": "^5.53.0", "connected-react-router": "4.4.1", @@ -125,7 +125,7 @@ "scripts": { "start": "node --max_old_space_size=15360 scripts/start.js", "build": "cross-env NODE_ENV=production node --max_old_space_size=15360 scripts/build.js", - "test-build": "NODE_ENV=testBuild node --max_old_space_size=15360 scripts/build.js", + "test-build": "cross-env NODE_ENV=testBuild node --max_old_space_size=15360 scripts/build.js", "pre-build": "NODE_ENV=preBuild node --max_old_space_size=15360 scripts/build.js", "gen_stats": "NODE_ENV=production webpack --profile --config=./config/webpack.config.prod.js --json > stats.json", "ana": "webpack-bundle-analyzer ./stats.json", diff --git a/public/css/edu-purge.css b/public/css/edu-purge.css index ecce221de..603513339 100644 --- a/public/css/edu-purge.css +++ b/public/css/edu-purge.css @@ -1520,7 +1520,15 @@ a.edu-txt-w80, .font-16 { font-size: 16px !important; } - +.weight400{ + font-weight: 400; +} +.weight500{ + font-weight: 500; +} +.weight{ + font-weight: bold; +} .font-17 { font-size: 17px !important; } @@ -1540,6 +1548,9 @@ a.edu-txt-w80, .font-25 { font-size: 25px !important; } +.font-26 { + font-size: 26px !important; +} .font-24 { font-size: 24px !important; @@ -1561,6 +1572,9 @@ a.edu-txt-w80, font-size: 36px !important; } +.font-40 { + font-size: 40px !important; +} .font-50 { font-size: 50px !important; } @@ -1746,6 +1760,14 @@ a.decoration { margin-bottom: 10px; } +.mb12 { + margin-bottom: 12px; +} + +.mb13 { + margin-bottom: 13px; +} + .mb14 { margin-bottom: 14px; } @@ -1927,7 +1949,9 @@ a.decoration { } .mr20 { - margin-right: 20px; + margin-right: 10px; + margin-left: 10px; + float: left; } .mr25 { @@ -1935,7 +1959,7 @@ a.decoration { } .mr30 { - margin-right: 30px; + margin-right: 10px; } .mr35 { @@ -2460,7 +2484,7 @@ a:hover{ .color-grey-B3 { color: #B3B3B3 !important; } -` + .color-grey-B4 { color: #B4B4B4 !important; } diff --git a/public/css/iconfont.css b/public/css/iconfont.css index 7e0e2c7e6..3866189c2 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=1631773579834') format('woff2'), - url('iconfont.woff?t=1631773579834') format('woff'), - url('iconfont.ttf?t=1631773579834') format('truetype'); + src: url('iconfont.woff2?t=1632964996877') format('woff2'), + url('iconfont.woff?t=1632964996877') format('woff'), + url('iconfont.ttf?t=1632964996877') format('truetype'); } .iconfont { @@ -13,6 +13,30 @@ -moz-osx-font-smoothing: grayscale; } +.icon-wenjian7:before { + content: "\e8e0"; +} + +.icon-xiangyoujiantou:before { + content: "\e8de"; +} + +.icon-xiangzuojiantou:before { + content: "\e8df"; +} + +.icon-a-liulanicon2x:before { + content: "\e8dd"; +} + +.icon-wenjianicon:before { + content: "\e8dc"; +} + +.icon-a-yuanquan2x:before { + content: "\e8db"; +} + .icon-xiangmubiaoqian:before { content: "\e8da"; } diff --git a/public/css/iconfont.js b/public/css/iconfont.js index f38ef2a3a..0e23ffb85 100644 --- a/public/css/iconfont.js +++ b/public/css/iconfont.js @@ -1 +1 @@ -!function(c){var a,l,h,i,o,z='',t=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss"),p=function(c,a){a.parentNode.insertBefore(c,a)};if(t&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}function v(){o||(o=!0,h())}function m(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(m,50)}v()}a=function(){var c,a;(a=document.createElement("div")).innerHTML=z,z=null,(c=a.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",a=c,(c=document.body).firstChild?p(a,c.firstChild):c.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(l=function(){document.removeEventListener("DOMContentLoaded",l,!1),a()},document.addEventListener("DOMContentLoaded",l,!1)):document.attachEvent&&(h=a,i=c.document,o=!1,m(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,v())})}(window); \ No newline at end of file +!function(c){var a,l,h,i,o,z='',t=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss"),p=function(c,a){a.parentNode.insertBefore(c,a)};if(t&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}function v(){o||(o=!0,h())}function m(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(m,50)}v()}a=function(){var c,a;(a=document.createElement("div")).innerHTML=z,z=null,(c=a.getElementsByTagName("svg")[0])&&(c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.width=0,c.style.height=0,c.style.overflow="hidden",a=c,(c=document.body).firstChild?p(a,c.firstChild):c.appendChild(a))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(l=function(){document.removeEventListener("DOMContentLoaded",l,!1),a()},document.addEventListener("DOMContentLoaded",l,!1)):document.attachEvent&&(h=a,i=c.document,o=!1,m(),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 42dec3471..5acfb6e98 100644 --- a/public/css/iconfont.json +++ b/public/css/iconfont.json @@ -5,6 +5,48 @@ "css_prefix_text": "icon-", "description": "", "glyphs": [ + { + "icon_id": "24656750", + "name": "文件", + "font_class": "wenjian7", + "unicode": "e8e0", + "unicode_decimal": 59616 + }, + { + "icon_id": "630094", + "name": "向右箭头", + "font_class": "xiangyoujiantou", + "unicode": "e8de", + "unicode_decimal": 59614 + }, + { + "icon_id": "630095", + "name": "向左箭头", + "font_class": "xiangzuojiantou", + "unicode": "e8df", + "unicode_decimal": 59615 + }, + { + "icon_id": "24600282", + "name": "浏览icon@2x", + "font_class": "a-liulanicon2x", + "unicode": "e8dd", + "unicode_decimal": 59613 + }, + { + "icon_id": "24567893", + "name": "文件icon", + "font_class": "wenjianicon", + "unicode": "e8dc", + "unicode_decimal": 59612 + }, + { + "icon_id": "24527422", + "name": "圆圈@2x", + "font_class": "a-yuanquan2x", + "unicode": "e8db", + "unicode_decimal": 59611 + }, { "icon_id": "24378423", "name": "项目标签", diff --git a/public/css/iconfont.ttf b/public/css/iconfont.ttf index a559db11e..cffaad689 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 2076f553a..af2a764e6 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 3031b14a1..7d4cb19bb 100644 Binary files a/public/css/iconfont.woff2 and b/public/css/iconfont.woff2 differ diff --git a/src/common/TextUtil.js b/src/common/TextUtil.js index 94e736314..d1aa0e9cd 100644 --- a/src/common/TextUtil.js +++ b/src/common/TextUtil.js @@ -69,7 +69,7 @@ export function appendFileSizeToUploadFile(item) { } export function appendFileSizeToUploadFileAll(fileList) { return fileList.map(item => { - if (item.name.indexOf(uploadNameSizeSeperator) == -1) { + if (item.name.indexOf(uploadNameSizeSeperator) === -1) { return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` }) } return item diff --git a/src/forge/Branch/Select.jsx b/src/forge/Branch/Select.jsx index 073658d93..ff3dd829e 100644 --- a/src/forge/Branch/Select.jsx +++ b/src/forge/Branch/Select.jsx @@ -1,32 +1,61 @@ -import React , { useState , useEffect } from 'react'; -import { Popover , Dropdown , Input , Spin } from 'antd'; +import React , { useState , useEffect , useRef } from 'react'; +import { Dropdown} from 'antd'; import './branch.scss'; -import { getBranch , getTag } from '../GetData/getData'; import SelectOverlay from './SelectOverlay'; - +import { findDOMNode } from 'react-dom'; export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true })=>{ const [ showValue , setShowValue ] = useState(branch); + const [ visible , setVisible ] = useState(false); + + const refFa = useRef(null); + const refBox = useRef(null); + + useEffect(() => { + document.addEventListener('click', clickMe , false); + }, []) + + const clickMe = ({ target }) => { + // 查找父组件 + const faComponent = findDOMNode(refFa.current); + const boxComponent = findDOMNode(refBox.current); + + if (faComponent && boxComponent) { + const isChild = faComponent.contains(target); + const isBox = boxComponent.contains(target); + if(!isChild && !isBox){ + setVisible(false); + } + } + } useEffect(()=>{ setShowValue(branch); },[branch]) + function ChangeB(params) { + setVisible(false); + changeBranch(params); + } + const menu = ( - + + ); return( - -
+ +
setVisible(visible ? false : true)}> {/* {nav === 0 ?"分支":"标签"} */} - + {showValue} diff --git a/src/forge/Branch/SelectOverlay.jsx b/src/forge/Branch/SelectOverlay.jsx index d536d1c99..f043a8f52 100644 --- a/src/forge/Branch/SelectOverlay.jsx +++ b/src/forge/Branch/SelectOverlay.jsx @@ -2,7 +2,7 @@ import React , { useState , useEffect } from 'react'; import { Input , Spin , Menu } from 'antd'; import { getBranch , getTag } from '../GetData/getData'; -function SelectOverlay({ changeBranch , tagflag , branchList , projectsId , owner }) { +function SelectOverlay({ changeBranch , tagflag , branchList , projectsId , owner , visible }) { const [ inputValue , setInputValue] = useState(undefined); const [ nav , setNav ] = useState(0); const [ isSpin , setIsSpin ] = useState(true); @@ -11,6 +11,14 @@ function SelectOverlay({ changeBranch , tagflag , branchList , projectsId , owne const [ datas , setDatas ] = useState(undefined); const [ keys ,setKeys] = useState("branch"); + // useEffect(()=>{ + // if(visible){ + // setKeys("branch"); + // getBranchs(projectsId,owner); + // setIsSpin(true); + // } + // },[visible]) + useEffect(()=>{ if(branchList){ setData(branchList); @@ -55,7 +63,7 @@ function SelectOverlay({ changeBranch , tagflag , branchList , projectsId , owne
} - placeholder="请输入分支或标签名称搜索" + placeholder={`请输入分支${tagflag ? "或标签" :""}名称搜索`} autocomplete="off" className="OptionsInput" value={inputValue} onChange={changeInputValue} @@ -68,12 +76,16 @@ function SelectOverlay({ changeBranch , tagflag , branchList , projectsId , owne
    { - datas && datas.length>0 ? + datas && datas.length>0 && datas.map((item,key)=>{ return(
  • chooseitem(item.name)}>{item.name}
  • ) - }): + }) + + } + { + datas && datas.length === 0 &&

    暂无{inputValue}{nav === 0 ?"分支":"标签"}~

    }
diff --git a/src/forge/Branch/branch.scss b/src/forge/Branch/branch.scss index b0f8ca2c9..030b05cd1 100644 --- a/src/forge/Branch/branch.scss +++ b/src/forge/Branch/branch.scss @@ -23,6 +23,7 @@ max-height: 300px; } .OptionsUl{ + min-height: 50px; max-height: 220px; overflow-y: auto; } @@ -87,6 +88,13 @@ line-height: 30px; padding:0px 5px; margin-left: 20px!important; + &.ant-menu-item-selected{ + border-color:#466aff!important; + color:#466aff!important; + } + &.ant-menu-item-active{ + border-color:transparent ; + } } } } @@ -109,7 +117,7 @@ color: #333; } &.ant-menu-item-selected{ - border-color:#1890ff!important; + border-color:#466aff!important; } &.ant-menu-item-active{ border-color:transparent ; diff --git a/src/forge/Component/Releases.jsx b/src/forge/Component/Releases.jsx index 3983f600f..260e6bd2d 100644 --- a/src/forge/Component/Releases.jsx +++ b/src/forge/Component/Releases.jsx @@ -2,8 +2,7 @@ import React from 'react'; import { AlignTop } from '../Component/layout'; import { Link } from 'react-router-dom'; -function Releases({owner,projectsId,releaseVersions , baseOperate , projectType}){ - +function Releases({ owner, projectsId, releaseVersions, distribution }) { return(
@@ -16,8 +15,9 @@ function Releases({owner,projectsId,releaseVersions , baseOperate , projectType} return( key === 0 &&
-

- {item.name} +

+ {/* 如果是点击最新则发行版列表页只展示最新的一个 */} + {item.name} 最新

{item.created_at}

@@ -27,7 +27,8 @@ function Releases({owner,projectsId,releaseVersions , baseOperate , projectType} }) :
- 您暂未发布任何版本{baseOperate && projectType !==2 && 创建新版本} + 您暂未发布任何版本 + {distribution && 创建新版本}
} diff --git a/src/forge/Component/User.jsx b/src/forge/Component/User.jsx index bc652dcfb..0d970173f 100644 --- a/src/forge/Component/User.jsx +++ b/src/forge/Component/User.jsx @@ -5,6 +5,7 @@ import { Link } from 'react-router-dom'; export default ({ url , name , column , id , login })=>{ const Img = styled.span` display:flex; + font-weight: bold; ${column && "flex-direction: column;text-align:center;"} align-items: center; & img{ diff --git a/src/forge/DevOps/Dispose/PipelineName.jsx b/src/forge/DevOps/Dispose/PipelineName.jsx index 4acaa2068..63ee54378 100644 --- a/src/forge/DevOps/Dispose/PipelineName.jsx +++ b/src/forge/DevOps/Dispose/PipelineName.jsx @@ -51,7 +51,7 @@ function PipelineName({visible,onCancel,onOk,value ,branchList}){ }) } - {setEventValue(e)}}> { EVENT.map((item,key)=>{ return( diff --git a/src/forge/DevOps/ssh/XmlPanel.jsx b/src/forge/DevOps/ssh/XmlPanel.jsx index ae642caa3..295d96ce0 100644 --- a/src/forge/DevOps/ssh/XmlPanel.jsx +++ b/src/forge/DevOps/ssh/XmlPanel.jsx @@ -24,7 +24,6 @@ function onLayout(term, el) { entry.target.offsetHeight, term, ); - console.log('cols, rows', cols, rows); term.resize(cols, rows); mediator.publish('ssh-xterm-resize', { columns: cols, @@ -139,12 +138,10 @@ export default ({ sshConfigData, sid }) => { }, 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); }; diff --git a/src/forge/Head/Footer.jsx b/src/forge/Head/Footer.jsx index 568583ea5..52c068586 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 41d7fcfd3..59513153b 100644 --- a/src/forge/Head/Header.js +++ b/src/forge/Head/Header.js @@ -120,7 +120,6 @@ class NewHeader extends Component { }) }; HideAddcoursestypess = (i) => { - console.log("调用了"); this.setState({ Addcoursestypes: false, mydisplay: true, @@ -269,7 +268,7 @@ class NewHeader extends Component { ) }) } -
  • 设置
  • + {/*
  • 设置
  • */} this.educoderloginysl()}>退出 ) diff --git a/src/forge/Main/CoderDepot.jsx b/src/forge/Main/CoderDepot.jsx index be568ca9f..70d1901eb 100644 --- a/src/forge/Main/CoderDepot.jsx +++ b/src/forge/Main/CoderDepot.jsx @@ -67,6 +67,7 @@ function CoderDepot(props){ const [ editReadme , setEditReadme ] = useState(false); const [ pullsFlag , setPullsFlag ] = useState(true); const [ issuesFlag , setIssuesFlag ] = useState(true); + const [ releaseVersions , setReleaseVersions] = useState(undefined); const owner = props.match.params.owner; const projectsId = props.match.params.projectsId; @@ -74,7 +75,8 @@ function CoderDepot(props){ branchName = returnbar(branchName); const details = props.projectDetail; let pathname = props.history.location.pathname; - + //distribution:判断此用户是否可以创建发行版 + const distribution = details && details.type != 2 && (details.permission === "Admin" || details.permission === "Owner" || details.permission === "Manager"); const { bannerList } = props; useEffect(()=>{ @@ -119,14 +121,47 @@ function CoderDepot(props){ setTreeValue(url); getFileInfo(url,branchName); setType("file"); + // getReadmeInfo(url,branchName); + // setReadme(undefined); }else{ setTreeValue(undefined); getDirInfo(branchName || defaultBranch); setType("dir"); + // getReadmeInfo('', branchName || defaultBranch); } } },[projectsId,owner,pathname,defaultBranch]) + useEffect(()=>{ + axios.get(`/${owner}/${projectsId}/releases.json`).then((result)=>{ + if(result && result.data){ + const release = { + "list":result.data.releases, + "total_count":result.data.releases.length + } + setReleaseVersions(release); + } + }) + },[]) + + // 获取readme信息 + function getReadmeInfo(path, ref) { + axios.get(`/${owner}/${projectsId}/readme.json`, { + params:{ + owner: owner, + repo: projectsId, + filepath:path, + ref:ref || branchName + } + }).then((result) => { + if (result) { + setReadme(result.data); + } else { + setReadme(undefined); + } + }) + } + // 获取主目录列表 function getDirInfo(branch){ setIsSpin(true); @@ -146,9 +181,10 @@ function CoderDepot(props){ setLastCommitAuthor(c && c.committer); setMainFlag(true); setReadOnly(true); - setReadme(result.data.readme); + // setReadme(result.data.readme); setEditReadme(false); setHide(true); + getReadmeInfo('', branchName || defaultBranch); } setTimeout(function(){setIsSpin(false);},500); }).catch(error=>{setIsSpin(false);}) @@ -181,15 +217,18 @@ function CoderDepot(props){ setDirInfo(undefined); setFileInfo(en); setType(en.type); + setReadme(undefined); }else{ setFileInfo(undefined); setDirInfo(en); setType("dir"); + getReadmeInfo(path, branchName || defaultBranch); } let c = result.data.last_commit setLastCommit(c && c.commit); setLastCommitAuthor(c && c.committer); setMainFlag(false); + setReadOnly(true); setReadOnly(!editReadme); setHide(true); } @@ -301,7 +340,8 @@ function CoderDepot(props){ const mdFlag = n && n.substring(n.length-3,n.length) === ".md"; const { current_user } = props; - const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter"; + const baseOper = current_user && current_user.login && issuesFlag; + const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter" && projectDetail.type !== 2 && pullsFlag; const fileOperate = type === "dir" && projectDetail && projectDetail.type !== 2 && ((projectDetail.permission && projectDetail.permission !=="Reporter") || (current_user && current_user.admin)); return( @@ -348,34 +388,47 @@ function CoderDepot(props){ branchList={projectDetail && projectDetail.branches && projectDetail.branches.list} > : - 分支:{branchName || defaultBranch} + 分支:{branchName || defaultBranch} }
    - - - - 分支 - {projectDetail && projectDetail.branches && projectDetail.branches.total_count} - - - - - - 标签 - {projectDetail && projectDetail.tags && projectDetail.tags.total_count} - - + { + treeValuePath && treeValuePath.length > 0 ? + + : +
    + + + + 分支 + {projectDetail && projectDetail.branches && projectDetail.branches.total_count} + + + + + + 标签 + {projectDetail && projectDetail.tags && projectDetail.tags.total_count} + + +
    + } { - baseOperate && ((projectDetail.type !== 2 && pullsFlag) || issuesFlag )&& + (baseOperate || baseOper) &&
    { - projectDetail.type !== 2 && pullsFlag && - urlLink(`/${owner}/${projectsId}/pulls/new`)} >+ 合并请求 + baseOperate && + urlLink(`/${owner}/${projectsId}/pulls/new/${branchName || defaultBranch}`)} >+ 合并请求 } { - issuesFlag && + baseOper && urlLink(`/${owner}/${projectsId}/issues/new`)} >+ 易修 }
    @@ -403,8 +456,8 @@ function CoderDepot(props){ lastCommit &&
    -
    props.history.push(`/${owner}/${projectsId}/commits/${truncateCommitId(lastCommit.sha)}`)} className={hideBtn && hide ? "ellipsistxt hidetxt" :"ellipsistxt"}> -
    {lastCommit.message}
    +
    +
    {lastCommit.message}
    { hideBtn && changeHide(hide)}> } @@ -418,16 +471,6 @@ function CoderDepot(props){
    }
      - { - treeValuePath && treeValuePath.length > 0 && - - } { dirInfo && dirInfo.length > 0 && dirInfo.map((item,key)=>{ @@ -461,11 +504,11 @@ function CoderDepot(props){ (dirInfo && dirInfo.length === 0) && !fileInfo ? :"" } {/* readme文件显示(显示文件详情时不显示readme文件) */} - { dirInfo && (readme && readme.content) ? :"" } + { (readme && readme.content) ? :"" }
    { - !fileInfo && + (!(treeValuePath && treeValuePath.length > 0) && !fileInfo) &&
    @@ -516,16 +559,15 @@ function CoderDepot(props){ } {/* 发布 */} { - projectDetail && projectDetail.release_versions && + releaseVersions && } @@ -535,7 +577,7 @@ function CoderDepot(props){ } {/* 语言 */} - { projectDetail && projectDetail.languages && + { projectDetail && projectDetail.languages && diff --git a/src/forge/Main/CoderDepotPath.jsx b/src/forge/Main/CoderDepotPath.jsx index ad4bb1096..89d6a5ca3 100644 --- a/src/forge/Main/CoderDepotPath.jsx +++ b/src/forge/Main/CoderDepotPath.jsx @@ -1,3 +1,4 @@ +import { result } from 'lodash'; import React from 'react'; diff --git a/src/forge/Main/CoderRootBranch.js b/src/forge/Main/CoderRootBranch.js deleted file mode 100644 index 4982414a2..000000000 --- a/src/forge/Main/CoderRootBranch.js +++ /dev/null @@ -1,92 +0,0 @@ -import React , { useState, useEffect } from 'react'; -import { Link } from "react-router-dom"; -import { Dropdown , Menu , Icon , Tooltip , Spin } from 'antd'; -import { truncateCommitId } from '../common/util'; -import { getBranch } from '../GetData/getData'; -import Nodata from '../Nodata'; -import './list.scss'; - -function turnbar(str){ - if(str && str.length>0 && str.indexOf("/")>-1){ - return str.replaceAll('/','%2F'); - } - return str; -} -export default ((props)=>{ - const [ data , setData ] =useState(undefined); - const [ isSpin , setIsSpin ] =useState(true); - - const { projectsId , owner } = props.match.params; - const { isManager , isDeveloper , projectDetail } = props; - useEffect(()=>{ - getBranchs(projectsId, owner); - },[projectsId]) - - async function getBranchs(id,owner){ - let result = await getBranch(id,owner); - setData(result); - setIsSpin(false); - } - - const list =()=>{ - if(data && data.length>0){ - return( - -
      - { - data.map((item,key)=>{ - return( -
    • -
      - {item.name} -

      - {item.last_commit && truncateCommitId(item.last_commit.sha)} - {item.last_commit && item.last_commit.message} - 最后更新于{item.last_commit && item.last_commit.time_from_now} -

      -
      - - { - (isManager || isDeveloper) && (projectDetail && projectDetail.type!==2) && - 创建合并请求 - } - - - - - - -
    • - ) - }) - } -
    -
    - ) - }else if(data && data.length === 0){ - return ( ) - } - } - const menu =(zip_url,tar_url)=> ( - - ZIP - TAR.GZ - - ) - - return( - -
    - -
    -

    分支列表

    -
    {list()}
    -
    -
    -
    -
    - ) -}) - - - diff --git a/src/forge/Main/CoderRootCommit.js b/src/forge/Main/CoderRootCommit.js index a715fe74e..604917ba0 100644 --- a/src/forge/Main/CoderRootCommit.js +++ b/src/forge/Main/CoderRootCommit.js @@ -1,13 +1,18 @@ import React , { Component } from 'react'; -import { Spin , Pagination } from 'antd'; +import { Spin , Pagination, Timeline } from 'antd'; import { getImageUrl } from 'educoder'; -import { truncateCommitId } from '../common/util'; +import { truncateCommitId ,timeFormat } from '../common/util'; import { AlignTop } from '../Component/layout'; import SelectBranch from '../Branch/Select'; import Nodata from '../Nodata'; +import User from '../Component/User' +import Tree from './img/tree.png'; import axios from 'axios'; import {Link} from "react-router-dom"; +import CopyTool from '../Component/CopyTool'; + +import './tree/Index.scss' function returnbar(str){ if(str && str.length>0 && str.indexOf("%2F")>-1){ @@ -15,14 +20,16 @@ function returnbar(str){ } return str; } + +//代码库--提交页面 class CoderRootCommit extends Component{ constructor(props){ - super(props) + super(props); this.state={ commitDatas:undefined, dataCount:undefined, - limit:20, - page:1, + limit:10, + page: 1, isSpining:false, branchList:undefined } @@ -50,20 +57,34 @@ class CoderRootCommit extends Component{ this.Init(); } } + + UrlParamHash(url){ + const params = {}; + let h; + let hash = url.slice(url.indexOf('?')+1).split('&'); + for(let i = 0; i{ const { branchName } = this.props.match.params; - const { page , limit } = this.state; + const { limit } = this.state; + const {search} = this.props.location; + const realPage = (search && this.UrlParamHash(search).page) ? parseInt(this.UrlParamHash(search).page) : 1; this.setState({ - isSpining:true + isSpining:true, + page:realPage }) - this.getCommitList( branchName , page , limit ); + this.getCommitList( branchName , realPage , limit ); } getCommitList=(branch , page , limit)=>{ this.setState({ isSpining:true }) - console.log(returnbar(branch)); const { projectsId , owner } = this.props.match.params; const url = `/${owner}/${projectsId}/commits.json`; axios.get(url,{ @@ -86,7 +107,8 @@ class CoderRootCommit extends Component{ image_url:item.author && item.author.image_url, sha:item.sha, time_from_now:item.time_from_now, - message:item.message + message:item.message, + timestamp:item.timestamp }) }) this.setState({ @@ -105,10 +127,9 @@ class CoderRootCommit extends Component{ } ChangePage=(page)=>{ - const { branchName } = this.props.match.params; - const { limit } = this.state; - this.getCommitList(branchName , page , limit); + this.props.history.push({pathname: this.props.history.location.pathname,search: `page=${page}`}) } + render(){ const { commitDatas , dataCount , limit , page , isSpining , branchList } = this.state; const { projectDetail, commit_class , defaultBranch } = this.props; @@ -129,46 +150,50 @@ class CoderRootCommit extends Component{ >
    -
    -
    -
    - {dataCount}次提交代码({branch}) -
    -
    -
    - { - commitDatas && commitDatas.length > 0 && commitDatas.map((item,k)=>{ - return( -
    - - {truncateCommitId(`${item.sha}`)} - {item.message} - -

    - { - item.id ? - - {item.image_url?:""} - - : - - {item.image_url?:""} - - - } - -

    + + { + commitDatas && commitDatas.length > 0 && commitDatas.map((item,k)=>{ + return( + 最新:}> +
    +
    + +
    {item.message}
    +
    +

    + + {item.timestamp && } +

    +
    +
    +
    +
    + + sha + {truncateCommitId(`${item.sha}`)} + + + +
    + +
    +
    - ) - }) - } - {commitDatas && commitDatas.length === 0 && } -
    -
    + + ) + }) + } + {commitDatas && commitDatas.length === 0 && } + { dataCount > limit ?
    - +
    :"" } diff --git a/src/forge/Main/CoderRootFileDetail.js b/src/forge/Main/CoderRootFileDetail.js index d5a9670c6..c6c976f47 100644 --- a/src/forge/Main/CoderRootFileDetail.js +++ b/src/forge/Main/CoderRootFileDetail.js @@ -1,10 +1,12 @@ import React, { Component } from "react"; -import { Popconfirm , Select } from "antd"; +import { Popconfirm , Select , Dropdown , Spin , Anchor } from "antd"; import "./list.scss"; import axios from "axios"; import Meditor from "../Newfile/m_editor"; import RenderHtml from "../../components/render-html"; +import ReadmeCatelogue from "./sub/ReadmeCatelogue"; +const $ = window.$; function bytesToSize(bytes) { if (bytes === 0) return "0 B"; let k = 1024, @@ -19,7 +21,8 @@ class CoderRootFileDetail extends Component { value: undefined, language: undefined, languages: undefined, - description: props.detail.content + description: props.detail.content, + menuList:undefined }; } @@ -169,6 +172,31 @@ class CoderRootFileDetail extends Component { }); }; + renderMenulist=()=>{ + const { description } = this.state; + if(description){ + const items = $.map($("#files-md").find("h1,h2,h3,h4,h5,h6"), function (el, _) { + const anchor = el.id; + const level = el.tagName.replace("H", ""); + const href = `#${anchor}`; + return { href:`${href}`,text:el.textContent , level:level } + }); + return items; + } + return []; + } + + menu=()=>{ + const menuList = this.renderMenulist(); + if(menuList && menuList.length > 0){ + return( + + ) + }else{ + return + } + } + render() { const { readOnly, @@ -186,79 +214,88 @@ class CoderRootFileDetail extends Component { const Option = Select.Option; return ( -
    -
    - + +
    + { + md && readOnly && + + + + 目录 + + + } + {bytesToSize(detail && detail.size)}

    - {flag && platform && ( -

    - {readOnly ? ( - - { - !detail.direct_download? - - this.DownLoadFile(detail.download_url)} className="ml20"> - - - { - type !==2 && - this.EditFile(false)} className="ml20"> - + {flag && platform && ( +
    + {readOnly ? ( + + { + !detail.direct_download? + + this.DownLoadFile(detail.download_url)} className="ml20"> + - } - :"" - } - - ) : ( - - - - - )} - { - type !==2 && - - - - - - } - -
    - )} -

    -
    + { + type !==2 && + this.EditFile(false)} className="ml20"> + + + } +
    :"" + } + + ) : ( + + + + + )} + { + type !==2 && + + + + + + } + +
    + )} +

    +
    {detail.image_type ? (
    @@ -272,7 +309,7 @@ class CoderRootFileDetail extends Component {
    ) : ( md && readOnly ? -
    +
    : diff --git a/src/forge/Main/CoderRootIndex.js b/src/forge/Main/CoderRootIndex.js index 0fb30c4e1..b5d241968 100644 --- a/src/forge/Main/CoderRootIndex.js +++ b/src/forge/Main/CoderRootIndex.js @@ -1,9 +1,10 @@ import React , { Component } from 'react'; import { Route , Switch } from 'react-router-dom'; -import Top from './DetailTop'; +// import Top from './DetailTop'; import Loadable from 'react-loadable'; import Loading from '../../Loading'; import axios from 'axios'; +import './Index.scss'; const FileNew = Loadable({ loader: () => import('../Newfile/Index'), @@ -18,25 +19,25 @@ const CoderRootCommit = Loadable({ loading: Loading, }) const CoderRootBranch = Loadable({ - loader: () => import('./CoderRootBranch'), + loader: () => import('./tree/Index'), loading: Loading, }) const CoderRootTag = Loadable({ - loader: () => import('./CoderRootTag'), + loader: () => import('./tag/Index'), loading: Loading, }) const CoderRootVersion = Loadable({ - loader: () => import('../Version/version'), - loading: Loading, -}) -const CoderRootVersionNew = Loadable({ - loader: () => import('../Version/New'), - loading: Loading, -}) -const CoderRootVersionUpdate = Loadable({ - loader: () => import('../Version/New'), + loader: () => import('./version/Index'), loading: Loading, }) +// const CoderRootVersionNew = Loadable({ +// loader: () => import('./version/New'), +// loading: Loading, +// }) +// const CoderRootVersionUpdate = Loadable({ +// loader: () => import('./version/New'), +// loading: Loading, +// }) const Diff = Loadable({ loader: () => import('./Diff'), loading: Loading, @@ -83,8 +84,8 @@ class CoderRootIndex extends Component{ } render(){ return( -
    - +
    + {/* */} {/* 新建文件 */} () } > - () } @@ -126,7 +127,7 @@ class CoderRootIndex extends Component{ render={ () => () } - > + > */} () diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js index a1a741496..4e1c241b5 100644 --- a/src/forge/Main/Detail.js +++ b/src/forge/Main/Detail.js @@ -681,18 +681,19 @@ class Detail extends Component { (props) => () } > - {/* 修改详情 */} - () } > - {/* 复制详情 */} + {/* 复制详情 copyetail*/} () + (props) => () } > + {/* 任务详情 */} .f-wrap-between { - padding: 10px 20px; + padding: 14px 20px 14px 16px; + border-radius: 3px 3px 0px 0px; + border: 1px solid #D0D0D0; + .df{ + align-items: center; + & .underline:hover{ + text-decoration: underline; + } + } } `; - -export default ({ match , history }) => { +//提交详情页 +export default (props) => { + const {match , history } = props; const [data, setData] = useState({undefined}); const [commit, setCommit] = useState(undefined); const [parents, setParents] = useState(undefined); const [committer, setCommitter] = useState(undefined); const [isSpin, setIsSpin] = useState(true); - const { sha , projectsId, owner } = match.params; useEffect(() => { if (projectsId && owner && sha) { @@ -43,6 +63,7 @@ export default ({ match , history }) => { setParents(result.data.parents); setCommitter(result.data.committer || (result.data.commit && result.data.commit.committer)); setIsSpin(false); + } }) .catch(error => { @@ -56,29 +77,42 @@ export default ({ match , history }) => {
    - {commit && commit.message && -
    {commit.message}
    - } - +
    + {commit && commit.message && +
    {commit.message}
    + } + {data.branch} +
    +
      - {committer && committer.time_from_now &&
    • {committer.time_from_now}
    • } + {commit && commit.timestamp &&
    • 提交于{timeFormat(commit.timestamp)}
    • }
  • { parents && parents.length > 0 && parents.map((item,key)=>{ return( - +
    + + sha + {truncateCommitId(item.sha)} +
    ) }) } - +
    + + sha + {truncateCommitId(sha)} +
  • @@ -87,6 +121,7 @@ export default ({ match , history }) => { data={data} owner={owner} projectsId={projectsId} + parentsSha={parents && parents.length > 0 && parents[0].sha} />
    diff --git a/src/forge/Main/Index.scss b/src/forge/Main/Index.scss index 1158c38e6..a19bd80da 100644 --- a/src/forge/Main/Index.scss +++ b/src/forge/Main/Index.scss @@ -189,13 +189,13 @@ flex-wrap: wrap; padding-bottom: 2px; a{ - margin: 0px 17px 0px 0px; + margin: 0px 17px 10px 0px; img{ border-radius: 50%; width: 40px; height: 40px; } - &:nth-child(6){ + &:nth-child(5){ margin-right: 0px; } } @@ -253,7 +253,7 @@ background-color: #FAFCFF; .ellipsistxt{ margin-top: 6px; - cursor: pointer; + // cursor: pointer; #ptxt{ margin-bottom: 0px; word-break: break-all; @@ -402,6 +402,16 @@ cursor: pointer; background: #FAFBFC; border-radius: 4px; + .ant-dropdown-menu-item{ + border-radius: 8px; + text-align: left!important; + a{ + width: 350px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + } border: 1px solid #D0D0D0; font-size: 15px; font-weight: normal; @@ -447,4 +457,28 @@ .ant-anchor-ink::before{ background-color: #fff; } +} +.coderSubPage{ + width: 1200px; + margin:0px auto; +} +.griditemAnchor{ + margin-left: 0px; + padding: 0px; + border-bottom: 1px solid #ddd; + .ant-anchor{ + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 20px; + } + .griditemCate{ + color: #333; + font-size: 16px; + display: flex; + align-items: center; + .catelogue{ + margin-left: 0px; + } + } } \ No newline at end of file diff --git a/src/forge/Main/img/tree-black.png b/src/forge/Main/img/tree-black.png new file mode 100644 index 000000000..02aa71c3a Binary files /dev/null and b/src/forge/Main/img/tree-black.png differ diff --git a/src/forge/Main/img/tree.png b/src/forge/Main/img/tree.png new file mode 100644 index 000000000..56247256c Binary files /dev/null and b/src/forge/Main/img/tree.png differ diff --git a/src/forge/Main/list.scss b/src/forge/Main/list.scss index 72c3437e9..73b534de9 100644 --- a/src/forge/Main/list.scss +++ b/src/forge/Main/list.scss @@ -426,14 +426,15 @@ border-right: none; } .gitAddressClone > input{ - border:none; outline: none; - padding:0px 8px; - height: 40px; - line-height: 40px; - border-radius: 0px; - border: 1px solid #eee; - flex:1; + padding: 0px 8px; + height: 38px; + line-height: 38px; + border: none!important; + border-right: 1px solid #eee!important; + border-radius: 4px 0px 0px 4px; + flex: 1; + max-width: 249px; } .wrap-commit-table .ant-table-small > .ant-table-content > .ant-table-body{ margin:0px; @@ -574,6 +575,9 @@ border:1px solid #ddd; margin-top: 18px; border-radius: 4px; + .ant-anchor-wrapper{ + overflow: unset!important; + } } .commonBox .commonBox-title{ padding:0px 20px; @@ -718,12 +722,76 @@ a.color-grey-ccc:hover{ padding:0px 30px; min-height: 400px; } -.commitList > div{ - border-bottom: 1px solid #EEEEEE; - padding:16px 0px; -} -.commitList > div:last-child{ - border-bottom: none; + +.main{ + margin: 30px auto; + .ant-timeline{ + margin-top: 28px; + .commitList-item{ + position: relative; + padding: 20px 20px; + background: #FAFCFF; + border: 1px solid rgba(42, 97, 255, 0.23); + border-radius: 4px; + margin-left: 16px; + align-items: center; + &:after,&:before{ + content: ""; + position: absolute; + left: -10px; + top: 10px; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + border-right: 10px solid rgba(42, 97, 255, 0.23); + } + &:after{ + left: -8px; + border-right: 10px solid #FAFCFF; + &:hover{ + border-right: 10px solid #EEF6FF; + } + } + &:hover{ + background: #EEF6FF; + border: 1px solid rgba(42, 97, 255, 0.58); + &:after{ + border-right: 10px solid #EEF6FF; + } + &:before{ + border-right: 10px solid rgba(42, 97, 255, 0.58); + } + } + .treecopy-cont{ + padding: 4px 15px; + } + .btn-83{ + margin-left: 20px; + } + } + .ant-timeline-item{ + padding: 8px 0 20px; + } + .ant-timeline-item-tail{ + height: calc(100% - 20px); + border-left: 2px solid #EEEEEE; + top: 12px; + &:after{ + content: ' '; + height: 0; + position: absolute; + width: 0; + border: 7px solid transparent; + border-top-color: #EEEEEE; + top: 100%; + left: 50%; + margin-left: -8px; + } + } + .ant-timeline-item-head-custom{ + top:20px; + padding: 0 1px; + } + } } diff --git a/src/forge/Main/sub/DetailBanner.jsx b/src/forge/Main/sub/DetailBanner.jsx index 83268b9e9..5e3ab9440 100644 --- a/src/forge/Main/sub/DetailBanner.jsx +++ b/src/forge/Main/sub/DetailBanner.jsx @@ -86,7 +86,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa :"" } - { + {/* { item.menu_name === "resources" &&
  • @@ -95,7 +95,7 @@ function DetailBanner({ history,list , owner , projectsId , isManager , url , pa {projectDetail && projectDetail.source_count ? {projectDetail.source_count} :""}
  • - } + } */} { item.menu_name === "versions" &&
  • diff --git a/src/forge/Main/sub/ReadmeCatelogue.jsx b/src/forge/Main/sub/ReadmeCatelogue.jsx index d1e018bb6..6dab7d792 100644 --- a/src/forge/Main/sub/ReadmeCatelogue.jsx +++ b/src/forge/Main/sub/ReadmeCatelogue.jsx @@ -1,7 +1,7 @@ -import React , { useState , useEffect } from 'react'; +import React , { useState } from 'react'; import { Anchor , Input } from 'antd'; import './sub.scss'; -import { Base64 } from 'js-base64'; +import { useEffect } from 'react'; const { Link } = Anchor; @@ -18,7 +18,7 @@ function ReadmeCatelogue({ menuList , hash }) { function changeValue(e) { setValue(e.target.value); if(e.target.value){ - let m = menuList.filter(i=>i.text.indexOf(e.target.value)>-1); + let m = menuList.filter(i=>i.text.toLowerCase().indexOf(e.target.value.toLowerCase())>-1); setMenu(m); }else{ setMenu(menuList); diff --git a/src/forge/Main/sub/SubMenu.jsx b/src/forge/Main/sub/SubMenu.jsx new file mode 100644 index 000000000..78f37b4de --- /dev/null +++ b/src/forge/Main/sub/SubMenu.jsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import'./sub.scss' + +function SubMenu({tab,owner,projectsId}) { + return( +
      + 标签 + 发行版 +
    + ) +} +export default SubMenu; \ No newline at end of file diff --git a/src/forge/Main/sub/sub.scss b/src/forge/Main/sub/sub.scss index 4e6a3d8ac..7716f0c50 100644 --- a/src/forge/Main/sub/sub.scss +++ b/src/forge/Main/sub/sub.scss @@ -64,4 +64,28 @@ background-color: #fff; } } +} +.subMenu{ + display: flex; + padding-top: 30px; + a{ + width: 83px; + font-weight: 500; + line-height: 30px; + height: 32px; + color: #333333!important; + text-align: center; + border: 1px solid #D0D0D0; + border-radius: 0px 4px 4px 0px; + background: rgba(250, 251, 252, 0); + &:first-child{ + border-right: none; + border-radius: 4px 0px 0px 4px; + } + &.active{ + background-color: #466AFF; + color: #fff!important; + border-color: #466AFF; + } + } } \ No newline at end of file diff --git a/src/forge/Main/tag/Index.jsx b/src/forge/Main/tag/Index.jsx new file mode 100644 index 000000000..88cca13b5 --- /dev/null +++ b/src/forge/Main/tag/Index.jsx @@ -0,0 +1,105 @@ +import React,{ useEffect , useState } from 'react'; +import SubMenu from '../sub/SubMenu'; +import { Table , Tooltip } from 'antd'; +import axios from 'axios'; +import { Link } from 'react-router-dom'; +import { truncateCommitId } from '../../common/util'; +import './Index.scss'; +import Tree from '../img/tree.png' +import moment from 'moment'; + + +function Tags(props) { + + const [ source , setSource ] = useState([]); + + const { projectsId , owner } = props.match.params; + + useEffect(() => { + if (projectsId) { + const url = `/${owner}/${projectsId}/tags.json`; + axios.get(url).then((result) => { + if (result) { + setSource(result.data); + } + }).catch(error => {}) + } + }, [owner, projectsId]); + + const columns=[ + { + title:"标签名", + dataIndex:"name", + key:1, + ellipsis:true, + render:(txt,item)=>{ + return {item.name} + } + }, + { + title:"创建时间", + dataIndex:"time_ago", + key:2, + ellipsis:true, + render:(txt,item)=>{ + return ( + + {item.commit && item.commit.name} + 创建于{txt} + + ) + } + }, + { + title:"提交ID", + dataIndex:"id", + key:3, + ellipsis:true, + render:(txt,item)=>{ + return ( + + 提交ID + {truncateCommitId(item.commit && item.commit.sha)} + + ) + } + }, + { + title:"描述信息", + dataIndex:"message", + key:4, + ellipsis:true, + render:(txt,item)=>{ + return item.message || "--" + } + }, + { + title:"下载", + dataIndex:"stage_type", + key:5, + ellipsis:true, + align:"center", + width:"181px", + render:(txt,item)=>{ + return ( + + ) + } + } + ] + return( +
    + +
    +
    + ) +} +export default Tags; \ No newline at end of file diff --git a/src/forge/Main/tag/Index.scss b/src/forge/Main/tag/Index.scss new file mode 100644 index 000000000..3bd487db6 --- /dev/null +++ b/src/forge/Main/tag/Index.scss @@ -0,0 +1,31 @@ +.tagTable{ + margin-top: 30px; + thead{ + tr th{ + background-color: #fff; + padding:5px 0px; + .ant-table-column-title{ + font-size: 16px; + font-weight: 500; + color: #333333; + } + } + } + tbody{ + tr{ + &:hover td{ + background-color: #fff!important; + } + td{ + padding:0px; + height: 69px; + line-height: 69px; + } + &:last-child{ + td{ + border-bottom: none!important; + } + } + } + } +} \ No newline at end of file diff --git a/src/forge/Main/tree/Index.jsx b/src/forge/Main/tree/Index.jsx new file mode 100644 index 000000000..84220a0bb --- /dev/null +++ b/src/forge/Main/tree/Index.jsx @@ -0,0 +1,114 @@ +import React , { useEffect , useState } from 'react'; +import CopyTool from '../../Component/CopyTool'; +import { truncateCommitId } from '../../common/util'; +import { Link } from 'react-router-dom'; +import { getImageUrl } from 'educoder'; +import { Dropdown , Menu , Spin } from 'antd'; +import './Index.scss'; + +import Tree from '../img/tree.png'; +import Axios from 'axios'; + +function turnbar(str){ + if(str && str.length>0 && str.indexOf("/")>-1){ + return str.replaceAll('/','%2F'); + } + return str; +} +function Index(props) { + const [ list , setList ] = useState([]); + const [ isSpin , setIsSpin ] = useState(true); + + const { projectsId , owner } = props.match.params; + const { isManager , isDeveloper , projectDetail } = props; + + useEffect(()=>{ + getList(); + },[]) + + + const menu =(zip_url,tar_url)=> ( + + ZIP + TAR.GZ + + ) + + function getList() { + const url = `/${owner}/${projectsId}/branches_slice.json`; + Axios.get(url).then(result=>{ + if(result){ + setList(result.data); + } + setIsSpin(false); + }).catch(error=>{setIsSpin(false);}) + } + + return( + +
    + { + list && list.length>0 && list.map((item,key)=>{ + return( + +

    {item.branch_type === "default" ? "默认分支" : item.branch_type==="protected"?"保护分支":"其它分支"}

    + { + item.list && item.list.length>0 && +
      + { + item.list.map((i,k)=>{ + let last_commit = i.last_commit; + return( +
    • +
      + {i.name} +
      + { + last_commit && last_commit.committer && last_commit.committer.id? + + + {last_commit && last_commit.committer && last_commit.committer.name} + + : + + + {last_commit && last_commit.committer && last_commit.committer.name} + + } + 更新于{last_commit && last_commit.time_from_now} +
      +
      +
      +
      + + sha + {truncateCommitId(last_commit && last_commit.sha)} + + + +
      +
      +
      + { + (isManager || isDeveloper) && (projectDetail && projectDetail.type!==2) && + + 合并请求 + } + + 下载 + +
      +
    • + ) + }) + } +
    + } +
    + ) + }) + } +
    +
    + ) +} +export default Index; \ No newline at end of file diff --git a/src/forge/Main/tree/Index.scss b/src/forge/Main/tree/Index.scss new file mode 100644 index 000000000..b077d9de9 --- /dev/null +++ b/src/forge/Main/tree/Index.scss @@ -0,0 +1,96 @@ +.branchSort{ + font-weight: 500; + color: #333333; + font-size: 15px; + height: 20px; + line-height: 20px; + padding-left: 10px; + margin-top: 20px; + margin-bottom: 6px!important; +} +.treeUl{ + background: #FAFCFF; + border-radius: 4px; + border: 1px solid rgba(42, 97, 255, 0.23); + li{ + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 20px; + border-bottom: 1px solid rgba(42, 97, 255, 0.23); + &:last-child{ + border-bottom: none; + } + .treeinfo{ + max-width: 399px; + flex:1; + flex-direction: column; + a:hover{ + span{ + color: #466AFF!important; + } + } + img{ + height: 20px; + width: 20px; + margin-right: 5px; + } + } + .treeabout{ + flex:1; + text-align: right; + } + } +} +.treecopy{ + flex:1; + display: flex; + justify-content: center; + &>div{ + height: 32px; + background: #FAFBFC; + border-radius: 4px; + border: 1px solid #D0D0D0; + position: relative; + z-index: 1; + display: flex; + align-items: center; + &>span{ + padding:0px 15px; + border-right: 1px solid rgba(153, 153, 153, 0.4); + height: 100%; + img{ + margin-right: 4px; + } + a{ + color: #466AFF; + &:hover{ + text-decoration: underline; + } + } + } + &>i{ + margin:0px 12px; + color: #333!important; + } + input{ + position: absolute; + z-index: 0; + opacity: 0; + top: 32px; + } + } +} +.new-conmmit{ + width: 30px; + height: 18px; + line-height: 18px; + display: block; + background: #FF6832; + color: white; + font-size: 12px; + border-radius: 4px; +} +.icon-a-yuanquan2x{ + color: #466AFF; +} \ No newline at end of file diff --git a/src/forge/Main/version/Empty.jsx b/src/forge/Main/version/Empty.jsx new file mode 100644 index 000000000..3200d3e8f --- /dev/null +++ b/src/forge/Main/version/Empty.jsx @@ -0,0 +1,22 @@ +import { Button } from 'antd'; +import React from 'react'; +import './version.scss'; + +function Empty({operation,addFunc}) { + return( +
    + + 这里暂未发布过任何版本 + 发行版功能基于仓库中的历史标记
    建议使用类似 V1.0 的版本标记作为发布点
    +
    + { + operation ? + + : + 该项目暂时没有发布版本 + } +
    +
    + ) +} +export default Empty; \ No newline at end of file diff --git a/src/forge/Main/version/Index.jsx b/src/forge/Main/version/Index.jsx new file mode 100644 index 000000000..37cc8c128 --- /dev/null +++ b/src/forge/Main/version/Index.jsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { Switch , Route } from 'react-router'; +import Loadable from 'react-loadable'; +import Loading from '../../../Loading'; +import SubMenu from '../sub/SubMenu'; +import "./version.scss"; + +const CoderRootVersion = Loadable({ + loader: () => import('./version'), + loading: Loading, +}) +const CoderRootVersionNew = Loadable({ + loader: () => import('./New'), + loading: Loading, +}) +function Index(props) { + const { projectsId , owner } = props.match.params; + return( +
    + + + () + } + > + () + } + > + () + } + > + +
    + ) +} +export default Index; \ No newline at end of file diff --git a/src/forge/Main/version/New.jsx b/src/forge/Main/version/New.jsx new file mode 100644 index 000000000..8adde9b01 --- /dev/null +++ b/src/forge/Main/version/New.jsx @@ -0,0 +1,266 @@ +import React, { useState, useEffect, forwardRef } from "react"; +import styled from "styled-components"; +import { AutoComplete , Input, Checkbox, Button, Form } from "antd"; +import SelectBranch from '../../Branch/Select'; + +import Editor from "../../../modules/tpm/challengesnew/tpm-md-editor"; +import Upload from "../../Upload/Index"; +import Attachments from "../../Upload/attachment"; +import axios from "axios"; +import "./version.scss"; +import { trim } from "lodash"; + +const { Option } = AutoComplete; + +const Span = styled.span` + margin: 0px 15px; + color: #bbb; + line-height: 35px; + font-size:16px; + font-weight:400; + color:#666; +`; +export default Form.create()( + forwardRef( + ( + { form, projectDetail , match, showNotification, history }, + ref + ) => { + const { getFieldDecorator, validateFields, setFieldsValue } = form; + const [tagList, setTagList] = useState(undefined); + const [desc, setDesc] = useState(null); + const [branch, setBranch ] = useState(null); + const [fileList, setFileList] = useState(undefined); + const [attachment, setAttachment] = useState(undefined); + const [options , setOptions] = useState(undefined); + const stable = history && history.location && history.location.state.stable; + const { projectsId, versionId , owner } = match.params; + + useEffect(()=>{ + if(projectDetail && projectDetail.default_branch){ + setBranch(projectDetail.default_branch); + } + },[projectDetail]) + + + useEffect(() => { + if (versionId) { + const url = `/${owner}/${projectsId}/releases/${versionId}/edit.json`; + axios.get(url).then(result => { + if (result) { + setFieldsValue(result.data); + setDesc(result.data.body); + setAttachment(result.data.attachments); + } + }); + } + }, [versionId]); + + useEffect(() => { + if (projectsId) { + const url = `/${owner}/${projectsId}/tags.json`; + axios + .get(url,{params:{ + limit:1000 + }}) + .then(result => { + if (result) { + setTagList(result.data); + setOptions(renderTagList(result.data)); + } + }) + .catch(error => { + console.log(error); + }); + } + }, [projectsId]); + + function renderTagList(list) { + if (list) { + let array = list.map((item, key) => { + return ( + + ); + }); + return array || undefined; + } + } + function submit() { + validateFields((err, value) => { + if(err)return; + if (versionId) { + let url = `/${owner}/${projectsId}/releases/${versionId}.json`; + axios + .put(url, { + ...value, + body: desc, + attachment_ids: fileList, + target_commitish:branch + }) + .then(result => { + if (result) { + showNotification("版本修改成功!"); + history.push(`/${owner}/${projectsId}/releases`); + } + }); + } else { + let url = `/${owner}/${projectsId}/releases.json`; + axios.post(url, { + ...value, + body: desc, + attachment_ids: fileList + }) + .then(result => { + if (result) { + showNotification("版本发布成功!"); + history.push(`/${owner}/${projectsId}/releases`); + } + }); + } + }); + } + // 输入标签名 + function changeAuto(value){ + let l = tagList.filter(item=>item.name.indexOf(value) > -1); + setOptions(renderTagList(l)); + } + + function changeBranch(params) { + setBranch(params); + } + + return ( +
    +
    +
    + + {getFieldDecorator("tag_name", + { rules:[ + { required: true, message: "请输入获取或选择一个标签" }, + { validator: (rule,val,callback) =>{ + if(val.length>30 || val.indexOf(' ')>0 || val.match(/^\s+$/) || trim(val).length!=val.length){ + callback('无效的标签名称,请参考右侧建议命名标签并确认长度在1~30个字符之间'); + }else{ + callback(); + } + }}], + validateFirst: true + })( + + {options} + + )} + + @ + +

    选择一个已经存在的标签,或者在发布时新建一个标签

    +
    + + {getFieldDecorator("name", + { rules:[ + { required: true, message: "请输入发行版的标题" }, + { validator: (rule,val,callback) =>{ + if(val.length>50){ + callback('标题长度在1~50个字符之间'); + }else{ + callback(); + } + }}], + validateFirst: true + })( + + )} + + + +
    + + } + size={100} + showNotification={showNotification} + /> + {versionId && attachment && attachment.length > 0 ? ( + + ) : ( + "" + )} +
    + + {getFieldDecorator("prerelease", + { rules:[], + validateFirst: true + })( + 这是一个预览版本 + )} + +

    + + +

    + +
    +
    +

    标签命名建议

    +

    + 通常的做法是在版本名称前加上字母 v 前缀, v1.0 或者 v2.3.4。 +

    +

    + 如果标签不适合在生产环境下使用,请在版本名称后添加预发行版本。例如:v0.2-alpha + 或者 v5.9-beta.3。 +

    +
    +
    +

    语义化版本

    +

    + 如果你是第一次发布版本,我们强烈建议你阅读语义化版本。 +

    +
    +
    +

    附件大小说明

    +

    + 单个附件不能超过 100M(GVP 项目200M),每个仓库总附件不可超过 + 1G(推荐项目不可超过 5G;GVP 项目不可超过 + 20G)。附件总容量统计包括仓库附件和发行版附件。 +

    +
    +
    +
    + ); + } + ) +); diff --git a/src/forge/Main/version/version.js b/src/forge/Main/version/version.js new file mode 100644 index 000000000..68cfd7746 --- /dev/null +++ b/src/forge/Main/version/version.js @@ -0,0 +1,150 @@ +import React, { useEffect , useState } from "react"; +import { Link } from 'react-router-dom'; +import { Spin , Button } from 'antd'; +import { getImageUrl } from 'educoder'; +import {truncateCommitId} from '../../common/util'; +import Empty from './Empty'; +import './version.scss'; +import axios from 'axios'; +import Tree from '../img/tree-black.png'; +import RenderHtml from '../../../components/render-html'; +import User from "../../Component/User"; + +function version(props) { + const [ data , setData ] = useState(undefined); + const [ releases , setReleases ] = useState(undefined); + const [ isSpin , setIsSpin ] = useState(true); + const { projectsId ,owner } = props.match.params; + const { isManager, isDeveloper, location , user } = props; + const type = props.projectDetail && props.projectDetail.type; + const turnFromNew = location && location.query && location.query.turnFromNew; + const current_user_login = user && user.login; + useEffect(()=>{ + getIssueList(); + },[]) + // 获取列表数据 + function getIssueList(){ + const url = `/${owner}/${projectsId}/releases.json`; + axios.get(url).then((result) => { + if (result) { + setData(result.data); + const { releases = [] } = result.data; + //默认第一个展开(body参数) + releases.length && (releases[0].bodyshow = true); + setReleases(result.data.releases); + setIsSpin(false); + } + + }).catch((error) => { + console.log(error); + }) + } + // 显示版本描述 + function showBody(key,flag){ + var lists = releases.concat(); + lists[key].bodyshow = !flag ? true : false; + lists.splice(); + setReleases(lists); + } + //删除 + function deleteRelease(releaseId) { + if(releaseId){ + axios.delete(`/${owner}/${projectsId}/releases/${releaseId}.json`).then((result)=>{ + if(result){ + getIssueList(); + } + }) + } + } + function release(item,key){ + return ( +
    + + {item.draft} + + + {item.tag_name} + + + + {truncateCommitId(item.sha)} + + +
    +
    + {item.name} + + {data && data.user_admin_permission && type !== 2 && } + {data && data.user_admin_permission && type !== 2 && {deleteRelease(item.version_id)}}>} + +
    + + showBody(key,item.bodyshow)}> + + 发布于{item.created_at} + + { + item.bodyshow && +
    + +
    + } + +

    + {/* 发行版附件下载 */} + {item.attachments && item.attachments.map((item)=>{ + return(下载 {item.title}) + })} + {/* 发行版下载包 */} + 下载 {item.tag_name}.TAR.gz + 下载 {item.tag_name}.ZIP +

    +
    +
    + ) + } + function renderList(releases){ + if (releases && releases.length > 0) { + return ( + + { + data && data.user_admin_permission && type !== 2 && +
    + +
    + } +
    + {!turnFromNew ? releases.map((item, key) => release(item,key)) : release(releases[0],0)} +
    +
    + ) + } else if (releases && releases.length === 0) { + return ( + + ) + } + } + + function addFunc(){ + props.history.push({pathname:`/${owner}/${projectsId}/releases/new`,state:{stable:true}}); + } + + return ( +
    +
    + + {renderList(releases)} + +
    +
    + ) +} +export default version; \ No newline at end of file diff --git a/src/forge/Main/version/version.scss b/src/forge/Main/version/version.scss new file mode 100644 index 000000000..7cd5ddb46 --- /dev/null +++ b/src/forge/Main/version/version.scss @@ -0,0 +1,357 @@ +.topWrapper { + padding: 20px 0; + box-sizing: border-box; + display: flex; + justify-content: space-between; + border-bottom: 1px solid #EEEEEE; + align-items: center; +} +.topWrapper_btn_new { + background: #fff; + color: #5091FF!important; + padding:0px 12px; + text-align: center; + height: 32px; + line-height: 32px; + border-radius: 4px; + border:1px solid #5091FF; +} +.versionInfo{ + display: flex; + width: 100%; +} +.versionInfo_left{ + display: flex; + width: 182px; + flex-direction: column; + align-items: flex-end; + padding-right: 15px; + &>.color-grey-3{ + max-width: 10rem; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } +} +.versionInfo_right{ + flex: 1; + display: flex; + flex-direction: column; + align-items: flex-start; + border-left: 1px solid #eee; + position: relative; + padding: 0px 30px 60px 24px; + &::before{ + position: absolute; + left: -4px; + top:0px; + content: ''; + width: 8px; + height: 8px; + background-color: #466AFF; + border-radius: 50%; + } + .sendAuthorImg{ + width: 20px; + height: 20px; + border-radius: 50%; + margin-right: 5px; + } + .body-show{ + padding: 5px 10px 10px 10px; + } + & .version-user>a>span{ + display: inline-block; + & img{ + width: 20px; + height: 20px; + } + } +} +.versionTag{ + display: inline; + padding:0px 9px; + color: #fff; + position: relative; + margin-top: -8px; + height: 22px; + line-height: 20px; + border-radius: 4px; + &::before{ + position: absolute; + content: ""; + width: 0; + height: 0px; + border-left: 4px solid #cccccc; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-right: 4px solid transparent; + z-index: 9; + top: 6px; + right: -9px; + } + &:after{ + width: 0px; + height: 0px; + top:6px; + right: -7px; + position: absolute; + border-left:4px solid #fff; + border-top:4px solid transparent; + border-bottom:4px solid transparent; + border-right:4px solid transparent; + content:''; + z-index:10; + } +} +.versionFile{ + margin-top: 5px; + padding-top: 20px; + border-top: 1px solid #eee; + // width: 100%; + a{ + display: block; + color: #333; + font-weight: 400; + height: 20px; + margin-bottom: 10px; + } +} +.versionTag.yellow{ + border: 1px solid #FBBC06; + color: #FBBC06; + &::before{ + border-left-color: #FBBC06; + } +} +.versionTag.green{ + border: 1px solid #2DB44D; + color: #2DB44D; + &::before{ + border-left-color: #2DB44D; + } +} +.versionTag.orange{ + border: 1px solid #FF6E23; + color: #FF6E23; + &::before{ + border-left-color: #FF6E23; + } +} +.addReleaseBtn{ + text-align: right; + margin-bottom: 30px; +} +.versionName{ + font-size: 16px; + color: #333; + margin-bottom: 15px; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + height: 18px; + line-height: 18px; + margin-top: -5px; +} + + +.versionmilepostleft{ + padding: 15px; + margin-right: 50px; + width: 80%; + } +.topWrapper_btn_close { + background: #504b4b; + color: #FFFFFF!important; + padding:0px 12px; + text-align: center; + height: 32px; + line-height: 32px; + border-radius: 4px; + } + + .topWrapper_btn_delete { + background: #da1010; + color: #FFFFFF!important; + padding:0px 12px; + text-align: center; + height: 32px; + line-height: 32px; + border-radius: 4px; + } + + .versionrighe{ + flex: 2; + } + .versionleft{ + flex: 1; + text-align: right; + display: flex; + justify-content: right; + } + + /* .version_line{ + display: flex; + height: 30px; + margin: auto; + border-left:1px solid #eee; + } */ + .version_line_one{ + display: flex; + height: 45px; + margin: auto; + border-left:1px solid #eee; + } + + .version_line_tpw{ + display: flex; + height: 80px; + margin: auto; + border-left:1px solid #eee; + } + + .versiondiv{ + display: flex; + } + .verwinth{ + width: 80%; + } + + /*开启中 关闭中*/ +.opendversionetail{ + display: inline-block; + background: #21ba45; + color: #ffffff!important; + padding:0px 5px; + text-align: center; + height: 25px; + /*width: 110px;*/ + border-radius: 4px; + line-height: 25px; +} +.closedversionetail{ + display: inline-block; + background: #e60b0b; + color: #ffffff!important; + padding:0px 5px; + text-align: center; + height: 25px; + /*width: 110px;*/ + border-radius: 4px; + line-height: 25px; +} +.versionrectangle { + width: 8px; + height: 8px; + border-radius: 100%; + margin-top: 15px; + margin-left: -4px; + margin-bottom: 10px; + background: rgb(83, 81, 81); + } +.ver-middle{ + vertical-align: middle; +} +/* new */ +.versionForm{ + flex:1; + padding-right: 40px; + box-sizing: border-box; + .ant-select-auto-complete.ant-select .ant-input:hover,.ant-input:hover { + border-color: rgba(153, 153, 153, 0.8); + } +} +.versionTips{ + width:268px; + box-sizing: border-box; +} +.infosTip{ + border-bottom: 1px solid #EEEEEE; + color: #333; + padding-bottom: 26px; + margin-bottom: 26px; + font-weight: 400; + text-align: justify; + &:last-child{ + border-bottom: none; + } +} +.dragBox{ + background: rgba(153, 153, 153, 0.04); + border-radius: 4px; + border: 1px dashed #d9d9d9; + padding:20px; + .versionStyle{ + border: none!important; + padding-bottom:20px; + .dragIcon{ + font-size: 40px!important; + color: #666!important; + line-height: 40px; + height: 40px; + margin-bottom: 14px; + display: block; + } + } + .ant-upload-list-item:hover .ant-upload-list-item-info { + background-color: rgba(239, 244, 255, 1); + } + .ant-upload-list-item-info{ + padding:0px 20px 0px 8px; + &>span{ + display: flex; + align-items: center; + } + } +} + +.set-ant-row .ant-row{ + display: flex; + height: 20px; + align-items: center; +} +.itemInline{ + display: flex; + align-items: flex-start; + position: relative; + &>p{ + position: absolute; + bottom: -5px; + } +} +.itemInline .ant-row{ + margin-bottom: 0px; +} +.prerelease{ + padding-top: 20px; + .ant-form-item-control{ + height: 20px; + line-height: 20px; + } +} +.releaseIndex{ + margin: 30px auto; + width: 1200px; +} +.emptyPanel{ + width: 100%; + background: #FAFCFF; + border-radius: 4px; + border: 1px solid rgba(42, 97, 255, 0.23); + min-height: 418px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + .operation{ + width: 400px; + border-top: 1px solid #eee; + padding-top: 34px; + text-align: center; + margin-top: 30px; + } +} +.ant-form-item-control{ + line-height: initial; +} \ No newline at end of file diff --git a/src/forge/Merge/Files.jsx b/src/forge/Merge/Files.jsx index 82a8638c6..a3015fcec 100644 --- a/src/forge/Merge/Files.jsx +++ b/src/forge/Merge/Files.jsx @@ -1,17 +1,20 @@ -import React ,{useEffect,useState } from 'react'; +import React ,{useEffect,useRef,useState } from 'react'; import { truncateCommitId } from '../common/util'; import { AlignCenter , FlexAJ } from '../Component/layout'; -import { Button } from 'antd'; +import { Button, Tooltip,Progress, Popover, Anchor } from 'antd'; import './merge.css'; +import './Index.scss'; -function Files({data,history,owner,projectsId}){ +function Files({ data,history,owner,projectsId , parentsSha }){ const [ files , setFiles ] = useState(data && data.files); - + const [ copyfileTipTitle, setCopyfileTipTitle] = useState("复制文件路径"); + const [ isOpen, setIsOpen] = useState(false); + useEffect(()=>{ if(data){ setFiles(data.files); } - },[data]) + },[data]); function showDown(flag,index,isBin){ if(!isBin){ @@ -22,35 +25,83 @@ function Files({data,history,owner,projectsId}){ } } + function copyFileName(fileName){ + var copyCont = document.createElement('input'); + copyCont.defaultValue = fileName; + document.body.appendChild(copyCont); + copyCont.select(); // 选择对象 + document.execCommand("Copy"); // 执行浏览器复制命令 + copyCont.className = 'copyCont'; + copyCont.style.display='none'; + setCopyfileTipTitle("复制成功"); + } + + const folderOpen = ( + + ) + return(
    - - - - 共有 {data && data.files_count} 个文件被更改,包括 + +
    {setIsOpen(!isOpen)}}> + + + 共有 {data && data.files_count} 个文件 被更改,包括 { data && data.total_addition ? {data && data.total_addition} 次插入:"" } { data && data.total_addition && data.total_deletion ? " 和 ":""} { data && data.total_deletion ? {data && data.total_deletion} 次删除:""} - + +
    + {isOpen && folderOpen}
    { files && files.length>0 && -
    +
    { files.map((item,key)=>{ return(
    - showDown(item.flag,key,item.isBin)}> + + - {!item.isBin ? :""} - - {item.name} + {!item.isBin ? showDown(item.flag,key,item.isBin)}>:""} + showDown(item.flag,key,item.isBin)}>{item.name} + setCopyfileTipTitle("复制文件路径")} + > + copyFileName(item.name)}> + - - - +{item.addition} - -{item.deletion} - +
    + 0 && ":"} ${item.addition > 0 ? item.addition + "处添加" : ""}${item.addition > 0 && item.deletion > 0 ? "和" : ""}${item.deletion > 0 ? item.deletion + "处删除" : ""}`}> + + {item.addition+item.deletion}处 + + {history.push(`/${owner}/${projectsId}${item.isDeleted ? `/commits/${truncateCommitId(parentsSha)}`:`/tree/${truncateCommitId(item.sha)}/${item.name}`}`)}}>查看文件 +
    { item.sections && item.sections.length >= 1 && !item.flag && diff --git a/src/forge/Merge/Index.scss b/src/forge/Merge/Index.scss index 936b868f8..16cc95632 100644 --- a/src/forge/Merge/Index.scss +++ b/src/forge/Merge/Index.scss @@ -18,4 +18,86 @@ .pr_tags_closed{ border:1px solid #FA6400; color: #FA6400; +} +.update-file-count{ + cursor: pointer; + & .color-grey-3{ + font-weight: bold; + } +} +.fileList{ + .sc-bxivhb{ + width: 55rem; + overflow: hidden; + white-space: normal; + word-break: break-all; + } + .see-file{ + width: 14rem; + .ml10{ + display: inline-block; + width: 4.5rem; + cursor: default; + } + span{ + width: 7%; + } + } + .anchorPoint{ + position: relative; + top: -5rem; + display: block; + height: 0; + } +} +.filesInfo{ + background: #FAFCFF; + border-color:rgba(42, 97, 255, 0.23); + .ant-progress-line { + width: 5rem; + } + .ant-progress-inner{ + background-color: #D14A4A; + } +} +.folders,.ant-anchor{ + margin-left: 0; + padding-left: 0; +} +.folders{ + position: absolute; + z-index: 2; + left: 0px; + top: 37px; + color: #333333; + width: 75rem; + box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5); + border-radius: 4px; + border: 1px solid rgba(153, 153, 153, 0.32); + .ant-anchor-link-active > .ant-anchor-link-title { + color: #466AFF; + } + .ant-anchor-link { + padding: 0px; + } + .folderList{ + max-height: 275px; + overflow:auto; + .files{ + border: 0px; + } + .filesInfo { + padding: 10px 18px 10px 15px; + height: 55px; + background: #FFF; + border-bottom: 1px solid #EEEEEE; + &:hover{ + background: #F3F4F6; + } + .color-green,.color-red{ + width: 3%; + text-align: right; + } + } + } } \ No newline at end of file diff --git a/src/forge/Merge/NewMerge.js b/src/forge/Merge/NewMerge.js index 7d33028d3..8913b0d1c 100644 --- a/src/forge/Merge/NewMerge.js +++ b/src/forge/Merge/NewMerge.js @@ -110,6 +110,7 @@ class NewMerge extends Component { const { author , identifier } =oldProject; url += `/${mergeBranch}...${author && author.login}/${identifier}:${localBranch}.json`; } + this.setState({isSpin: true}); axios.get(url).then(result=>{ if(result){ if (result.data.status === 0) { @@ -128,7 +129,9 @@ class NewMerge extends Component { comparesData:result.data }) } - }).catch(error=>{}) + }).catch(error=>{ + this.setState({isSpin: false}); + }) } } diff --git a/src/forge/Merge/merge.css b/src/forge/Merge/merge.css index 6b50eeb10..088874c19 100644 --- a/src/forge/Merge/merge.css +++ b/src/forge/Merge/merge.css @@ -152,13 +152,23 @@ form .ant-cascader-picker, form .ant-select { margin-top: 15px; border-radius: 2px; } +.see-file-btn{ + color: #466AFF; + cursor: pointer; +} .filesInfo{ padding:10px 15px; background-color: #fafafa; } +.filesInfo .cursor-pointer{ + cursor: pointer; +} .filesContent{ border-top: 1px solid #ddd; } +.icon-fuzhiicon:hover{ + color: #466AFF; +} .linesContent{ display: flex; min-height: 30px; diff --git a/src/forge/Newfile/Index.js b/src/forge/Newfile/Index.js index 9b7769552..953f50720 100644 --- a/src/forge/Newfile/Index.js +++ b/src/forge/Newfile/Index.js @@ -65,16 +65,18 @@ class Index extends Component {
    - +
    + +
    diff --git a/src/forge/Newfile/UserSubmitComponent.js b/src/forge/Newfile/UserSubmitComponent.js index 65fa7ec24..84ae9b33e 100644 --- a/src/forge/Newfile/UserSubmitComponent.js +++ b/src/forge/Newfile/UserSubmitComponent.js @@ -83,8 +83,9 @@ class UserSubmitComponent extends Component { if (result.data && result.data.name) { this.props.showNotification("文件新建成功!"); if(submitType === "1"){ - const { getTopCount } = this.props; + const { getTopCount , getDetail } = this.props; getTopCount && getTopCount(values.branchname); + getDetail && getDetail(); } let url = `/${owner}/${projectsId}${values.branchname ? `/tree/${turnbar(values.branchname)}`: (branch ? `/tree/${turnbar(branch)}` : "")}`; this.props.history.push(url); @@ -147,6 +148,7 @@ class UserSubmitComponent extends Component { const { current_user, filepath, projectDetail , currentBranch } = this.props; const { editor_type } = this.props; let b = currentBranch || branch; + return (
    diff --git a/src/forge/Newfile/index.css b/src/forge/Newfile/index.css index 242fd4516..746febe55 100644 --- a/src/forge/Newfile/index.css +++ b/src/forge/Newfile/index.css @@ -8,7 +8,13 @@ border: 1px solid #d9d9d9!important; border-right: none!important; } - +.editorBorder .editorBorderBox{ + border:1px solid #eee; + border-radius: 2px; +} +.editorBorder .editorBorderSubmitBox{ + padding:20px 0px!important; +} .userScrew{ margin:20px 0px; border:1px solid #f4f4f4; @@ -39,7 +45,7 @@ z-index: 1; } .ant-input-group .ant-input:focus{ - border-right: 1px solid #d9d9d9!important; + border-right: 1px solid rgba(70, 106, 255, 1)!important; } .ant-btn-primary.grey{ border:1px solid #BBBBBB; diff --git a/src/forge/Newfile/m_editor.js b/src/forge/Newfile/m_editor.js index 05a7b2ac0..242f7e0d3 100644 --- a/src/forge/Newfile/m_editor.js +++ b/src/forge/Newfile/m_editor.js @@ -10,6 +10,7 @@ class m_editor extends Component { super(props); this.state = { editorValue: this.props.content, + prevHeight:0 }; } componentDidUpdate=(prevProps)=>{ @@ -41,42 +42,81 @@ class m_editor extends Component { folding: true, foldingStrategy: "indentation", // 代码可分小段折叠 automaticLayout: true, // 自适应布局 - // overviewRulerBorder: false, // 不要滚动条的边框 - // scrollBeyondLastLine: false, // 取消代码后面一大段空白 + overviewRulerBorder: false, // 不要滚动条的边框 + scrollBeyondLastLine: false, // 取消代码后面一大段空白 minimap: { // 不要小地图 enabled: false, }, }; + + const handleEditorMount = (editor, monaco) => { + editor.onDidChangeModelDecorations(() => { + requestAnimationFrame(updateEditorHeight); // folding + }); + + const updateEditorHeight = () => { + const editorElement = editor.getDomNode(); + + if (!editorElement) { + return; + } + + const padding = 40; + + const lineHeight = editor.getOption( + monaco.editor.EditorOption.lineHeight + ); + + const lineCount = editor.getModel().getLineCount() || 1; + let height = + editor.getTopForLineNumber(lineCount + 1) + + lineHeight + + padding ; + + if(height<400){height = 400;} + + if (this.state.prevHeight !== height) { + this.setState({ + prevHeight:height + }) + // setPrevHeight(height); + editorElement.style.height = `${height}px`; + editor.layout(); + } + }; + + updateEditorHeight(); // typing + }; + + return ( -
    -
    - -
    - {!readOnly && ( -
    - -
    - )} -
    +
    + +
    + {!readOnly && ( +
    + +
    + )}
    ); } diff --git a/src/forge/Order/CopyDetail.js b/src/forge/Order/CopyDetail.js index 1f61e7369..906de4be7 100644 --- a/src/forge/Order/CopyDetail.js +++ b/src/forge/Order/CopyDetail.js @@ -1,11 +1,13 @@ -import React, { Component } from "react"; +import React from "react"; import OrderItem from './order_form' -class CopyDetail extends Component { - render() { - return ( - - ) - } + + +function CopyDetail(props){ + const operate = props.match.params.operate; + console.log(operate); + return( + + ) } -export default CopyDetail; +export default CopyDetail; \ No newline at end of file diff --git a/src/forge/Order/Detail.js b/src/forge/Order/Detail.js index b377b6a1d..19ef67c59 100644 --- a/src/forge/Order/Detail.js +++ b/src/forge/Order/Detail.js @@ -123,22 +123,25 @@ class Detail extends Component { //复制 copydetail = () => { const { projectsId, orderId, owner } = this.props.match.params; - const url = `/${owner}/${projectsId}/issues/${orderId}/copy.json`; - axios - .post(url, { - project_id: projectsId, - id: orderId, - }) - .then((result) => { - if (result) { - this.props.history.push( - `/${owner}/${projectsId}/issues/${result.data.issue_id}/copyetail` - ); - } - }) - .catch((error) => { - console.log(error); - }); + // const url = `/${owner}/${projectsId}/issues/${orderId}/copy.json`; + // axios + // .post(url, { + // project_id: projectsId, + // id: orderId, + // }) + // .then((result) => { + // if (result) { + // this.props.history.push( + // `/${owner}/${projectsId}/issues/${result.data.issue_id}/copyetail` + // ); + // } + // }) + // .catch((error) => { + // console.log(error); + // }); + this.props.history.push( + `/${owner}/${projectsId}/issues/${orderId}/copyetail` + ); }; // 翻页 diff --git a/src/forge/Order/UpdateDetail.js b/src/forge/Order/UpdateDetail.js index 9cbb3cd64..0bf4f0f13 100644 --- a/src/forge/Order/UpdateDetail.js +++ b/src/forge/Order/UpdateDetail.js @@ -1,11 +1,11 @@ -import React, { Component } from "react"; +import React from "react"; import OrderForm from './order_form' -class UpdateDetail extends Component { - render() { - return ( - - ) - } + +function CopyDetail(props){ + const operateName = props.match.params.operateName; + return( + + ) } -export default UpdateDetail; +export default CopyDetail; diff --git a/src/forge/Order/order_form.js b/src/forge/Order/order_form.js index 936dc3d11..0858ac527 100644 --- a/src/forge/Order/order_form.js +++ b/src/forge/Order/order_form.js @@ -153,7 +153,7 @@ class order_form extends Component { values.issue_tag_ids = [values.issue_tag_ids]; } const { description, start_date, due_date, issue_type } = this.state; - if (form_type === "new") { + if (form_type !== "edit") { const url = `/${owner}/${projectsId}/issues.json`; axios.post(url, { ...values, @@ -178,7 +178,6 @@ class order_form extends Component { this.setState({ isSpin: false, }); - console.log(error); }); } else { const url = `/${owner}/${projectsId}/issues/${orderId}.json`; diff --git a/src/forge/Settings/Setting.js b/src/forge/Settings/Setting.js index d6d3cdc60..b1af2f998 100644 --- a/src/forge/Settings/Setting.js +++ b/src/forge/Settings/Setting.js @@ -16,7 +16,7 @@ const menu = [ {name:"合并请求",index:"pulls"}, {name:"Wiki",index:"wiki"}, {name:"工作流(beta版)",index:"devops"}, - {name:"资源库",index:"resources"}, + // {name:"资源库",index:"resources"}, {name:"里程碑",index:"versions"}, {name:"动态",index:"activity"}, ] diff --git a/src/forge/Team/New.jsx b/src/forge/Team/New.jsx index 414a8d158..46e13c3e0 100644 --- a/src/forge/Team/New.jsx +++ b/src/forge/Team/New.jsx @@ -87,7 +87,7 @@ export default Form.create()( } ], )} diff --git a/src/forge/Team/Setting/TeamSettingCommon.jsx b/src/forge/Team/Setting/TeamSettingCommon.jsx index 499a00c20..e4f5cf7a6 100644 --- a/src/forge/Team/Setting/TeamSettingCommon.jsx +++ b/src/forge/Team/Setting/TeamSettingCommon.jsx @@ -122,7 +122,7 @@ export default Form.create()( validator:checkname } ], - ,true + ,true )} {helper( "组织名称:", diff --git a/src/forge/Team/Sub/SubDetail.jsx b/src/forge/Team/Sub/SubDetail.jsx index b4f1d0363..278fef07e 100644 --- a/src/forge/Team/Sub/SubDetail.jsx +++ b/src/forge/Team/Sub/SubDetail.jsx @@ -48,9 +48,9 @@ export default ((props)=>{
    - {OIdentifier} + {detail && detail.organization && detail.organization.nickname} - {detail ? detail.name : "新建团队"} + {detail ? detail.nickname : "新建团队"}
    { detail && diff --git a/src/forge/Upload/Index.js b/src/forge/Upload/Index.js index 5b09ca071..713803aa3 100644 --- a/src/forge/Upload/Index.js +++ b/src/forge/Upload/Index.js @@ -1,7 +1,6 @@ import React, { Component } from "react"; import { Upload, Icon , Button } from 'antd'; import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder'; -import { AlignCenter } from '../Component/layout'; import axios from 'axios'; const { Dragger } = Upload; @@ -64,7 +63,6 @@ class Index extends Component { changeIsComplete && changeIsComplete(true); if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') { let fileList = info.fileList; - this.setState({ fileList: appendFileSizeToUploadFileAll(fileList) }); this.fileIdList(fileList); } @@ -111,7 +109,7 @@ class Index extends Component { : {icon || } -

    拖动文件或点击此处上传

    +

    拖动文件或点击此处上传

    ) } diff --git a/src/forge/Upload/untitled b/src/forge/Upload/untitled deleted file mode 100644 index 2796e4d71..000000000 --- a/src/forge/Upload/untitled +++ /dev/null @@ -1,21 +0,0 @@ - -1.请求URL: https://code.ihub.org.cn/api/v1/mirrors/create.json - -2.请求方式: POST - -3.参数: - -{ - "image_url": "xxx.git", #必填,且后缀必为.git, - "language": "Ruby", #必填,如数据库不存在,则会创建新的记录 -} - - -4. 返回值: { - "status": 1, - "message": "同步成功,项目ID===1806" -} - -5. 返回值说明: 仅有当有返回值,且返回值的status 的值为1, 才是创建成功,其余均为创建失败 - - diff --git a/src/forge/Version/New.jsx b/src/forge/Version/New.jsx deleted file mode 100644 index 0678a3457..000000000 --- a/src/forge/Version/New.jsx +++ /dev/null @@ -1,278 +0,0 @@ -import React, { useState, useEffect, useCallback, forwardRef } from "react"; -import styled from "styled-components"; -import { AutoComplete, Select, Input, Checkbox, Button, Form } from "antd"; - -import Editor from "../../modules/tpm/challengesnew/tpm-md-editor"; -import Upload from "../Upload/Index"; -import Attachments from "../Upload/attachment"; -import axios from "axios"; -import "./version.css"; -import UploadImg from "../Images/upload.png"; -import { getBranch } from '../GetData/getData'; - -const { Option } = AutoComplete; - -export default Form.create()( - forwardRef( - ( - { form, projectDetail , match, showNotification, history }, - ref - ) => { - const { getFieldDecorator, validateFields, setFieldsValue } = form; - const [tagList, setTagList] = useState(undefined); - const [branchList, setBranchList] = useState(undefined); - const [desc, setDesc] = useState(null); - const [fileList, setFileList] = useState(undefined); - const [attachment, setAttachment] = useState(undefined); - const [options , setOptions] = useState(undefined); - - - const repo_id = projectDetail && projectDetail.repo_id; - const { projectsId, versionId , owner } = match.params; - useEffect(()=>{ - getBranchs(projectsId,owner); - },[projectsId]) - - async function getBranchs(id,owner){ - let result = await getBranch(id,owner); - setBranchList(result); - } - - const Span = styled.span` - margin: 0px 15px; - color: #bbb; - line-height: 35px; - `; - - - useEffect(() => { - if (versionId) { - const url = `/${owner}/${projectsId}/releases/${versionId}/edit.json`; - axios.get(url).then(result => { - if (result) { - setFieldsValue(result.data); - setDesc(result.data.body); - setAttachment(result.data.attachments); - } - }); - } - }, [versionId]); - - useEffect(() => { - if (projectsId) { - const url = `/${owner}/${projectsId}/tags.json`; - axios - .get(url,{params:{ - limit:1000 - }}) - .then(result => { - if (result) { - setTagList(result.data); - setOptions(renderTagList(result.data)); - } - }) - .catch(error => { - console.log(error); - }); - } - }, [projectsId]); - - function renderTagList(list) { - if (list) { - let array = list.map((item, key) => { - return ( - - ); - }); - return array || undefined; - } - } - function submit() { - validateFields((err, value) => { - if(err)return; - if (versionId) { - let url = `/${owner}/${projectsId}/releases/${versionId}.json`; - axios - .put(url, { - ...value, - body: desc, - attachment_ids: fileList - }) - .then(result => { - if (result) { - showNotification("版本修改成功!"); - history.push(`/${owner}/${projectsId}/releases`); - } - }); - } else { - let url = `/${owner}/${projectsId}/releases.json`; - axios.post(url, { - ...value, - body: desc, - attachment_ids: fileList - }) - .then(result => { - if (result) { - showNotification("版本发布成功!"); - history.push(`/${owner}/${projectsId}/releases`); - } - }); - } - }); - } - - const helper = useCallback( - (label, name, rules, widget, isRequired = true) => ( - - {label} - - {getFieldDecorator(name, { rules, validateFirst: true })(widget)} - - - ), - [] - ); - // 输入标签名 - function changeAuto(value){ - let l = tagList.filter(item=>item.name.indexOf(value) > -1); - setOptions(renderTagList(l)); - } - return ( -
    -
    -
    -

    {versionId?"编辑":"创建"}发行版

    -
    -
    - {helper( - "", - "tag_name", - [{ required: true, message: "请输入获取或选择一个标签" }], - - {options} - - )} - @ - {helper( - "", - "target_commitish", - [{ required: true, message: "请选择一个分支" }], - - )} -
    -

    - 选择一个已经存在的标签,或者在发布时新建一个标签 -

    -
    -
    - {helper( - "", - "name", - [{ required: true, message: "请输入发行版的标题" }], - - )} -
    -
    - -
    -
    - {helper( - "", - "prerelease", - [], - 这是一个预览版本 - )} -
    -
    - - } - size={100} - showNotification={showNotification} - /> - {versionId && attachment && attachment.length > 0 ? ( - - ) : ( - "" - )} -
    -

    - - -

    -
    -
    -
    -
    -

    标签命名建议

    -

    - 通常的做法是在版本名称前加上字母 v 前缀, v1.0 或者 v2.3.4。 -

    -

    - 如果标签不适合在生产环境下使用,请在版本名称后添加预发行版本。例如:v0.2-alpha - 或者 v5.9-beta.3。 -

    -
    -
    -

    语义化版本

    -

    - 如果你是第一次发布版本,我们强烈建议你阅读语义化版本。 -

    -
    -
    -

    附件大小说明

    -

    - 单个附件不能超过 100M(GVP 项目200M),每个仓库总附件不可超过 - 1G(推荐项目不可超过 5G;GVP 项目不可超过 - 20G)。附件总容量统计包括仓库附件和发行版附件。 -

    -
    -
    -
    - ); - } - ) -); diff --git a/src/forge/Version/version.css b/src/forge/Version/version.css deleted file mode 100644 index ddfbe7d64..000000000 --- a/src/forge/Version/version.css +++ /dev/null @@ -1,205 +0,0 @@ -.topWrapper { - padding: 20px 0; - box-sizing: border-box; - display: flex; - justify-content: space-between; - border-bottom: 1px solid #EEEEEE; - align-items: center; -} -.topWrapper_btn_new { - background: #fff; - color: #5091FF!important; - padding:0px 12px; - text-align: center; - height: 32px; - line-height: 32px; - border-radius: 4px; - border:1px solid #5091FF; -} -.versionInfo{ - display: flex; - width: 100%; -} -.versionInfo_left{ - display: flex; - width: 30%; - padding-top: 20px; - flex-direction: column; - align-items: flex-end; - padding-right: 15px; -} -.versionInfo_right{ - flex: 1; - padding: 20px 0px 20px 15px; - display: flex; - flex-direction: column; - align-items: flex-start; - border-left: 1px solid #eee; -} -.versionTag{ - display: inline; - border-radius: 2px; - padding:2px 12px; - font-size: 12px; - color: #fff; -} -.versionTag.yellow{ - background-color: #FBBC06; -} -.versionTag.green{ - background-color: #20BA45; -} -.versionTag.orange{ - background-color: #F2711D; -} -.versionName{ - font-size: 16px; - color: #333; - margin-bottom: 10px; - display: flex; - align-items: flex-end; - position: relative; -} -.versionName::before{ - position: absolute; - left: -19px; - top:8px; - content: ''; - width: 8px; - height: 8px; - background-color: #5091FF; - border-radius: 50%; -} - - -.versionmilepostleft{ - padding: 15px; - margin-right: 50px; - width: 80%; - } -.topWrapper_btn_close { - background: #504b4b; - color: #FFFFFF!important; - padding:0px 12px; - text-align: center; - height: 32px; - line-height: 32px; - border-radius: 4px; - } - - .topWrapper_btn_delete { - background: #da1010; - color: #FFFFFF!important; - padding:0px 12px; - text-align: center; - height: 32px; - line-height: 32px; - border-radius: 4px; - } - - .versionrighe{ - flex: 2; - } - .versionleft{ - flex: 1; - text-align: right; - display: flex; - justify-content: right; - } - - /* .version_line{ - display: flex; - height: 30px; - margin: auto; - border-left:1px solid #eee; - } */ - .version_line_one{ - display: flex; - height: 45px; - margin: auto; - border-left:1px solid #eee; - } - - .version_line_tpw{ - display: flex; - height: 80px; - margin: auto; - border-left:1px solid #eee; - } - - .versiondiv{ - display: flex; - } - .verwinth{ - width: 80%; - } - - /*开启中 关闭中*/ -.opendversionetail{ - display: inline-block; - background: #21ba45; - color: #ffffff!important; - padding:0px 5px; - text-align: center; - height: 25px; - /*width: 110px;*/ - border-radius: 4px; - line-height: 25px; -} -.closedversionetail{ - display: inline-block; - background: #e60b0b; - color: #ffffff!important; - padding:0px 5px; - text-align: center; - height: 25px; - /*width: 110px;*/ - border-radius: 4px; - line-height: 25px; -} -.versionrectangle { - width: 8px; - height: 8px; - border-radius: 100%; - margin-top: 15px; - margin-left: -4px; - margin-bottom: 10px; - background: rgb(83, 81, 81); - } -.ver-middle{ - vertical-align: middle; -} -/* new */ -.versionForm{ - flex:1; - padding-right: 30px; - box-sizing: border-box; -} -.versionTips{ - width:30%; - padding-left: 15px; - box-sizing: border-box; -} -.infosTip{ - padding:20px; - background-color: #F1F8FF; - margin-bottom: 22px; - color: #333; -} -.versionStyle{ - height: 200px!important; - border: 1px dashed rgba(80,145,255,1)!important; -} -.set-ant-row .ant-row{ - display: flex; - height: 20px; - align-items: center; -} -.itemInline{ - display: flex; - align-item: center; - margin-bottom: 5px; -} -.itemInline .ant-row{ - margin-bottom: 0px; -} \ No newline at end of file diff --git a/src/forge/Version/version.js b/src/forge/Version/version.js deleted file mode 100644 index 5049b31d9..000000000 --- a/src/forge/Version/version.js +++ /dev/null @@ -1,128 +0,0 @@ -import React, { Component } from "react"; -import { Link } from 'react-router-dom'; -import { Spin } from 'antd'; -import NoneData from '../Nodata'; -import './version.css'; -import axios from 'axios'; -import RenderHtml from '../../components/render-html'; - -/** - * issue_chosen:下拉的筛选列表, - * data:列表接口返回的所有数据, - * issues:列表数组, - * isSpin:加载中, - */ -class version extends Component { - constructor(props) { - super(props); - this.state = { - issue_chosen: undefined, - data: undefined, - releases:undefined, - issues: undefined, - isSpin: true, - search: undefined, - search_count: undefined, - } - } - - componentDidMount = () => { - this.getIssueList(); - } - // 获取列表数据 - getIssueList = () => { - const { projectsId, owner } = this.props.match.params; - const url = `/${owner}/${projectsId}/releases.json`; - axios.get(url).then((result) => { - if (result) { - this.setState({ - data: result.data, - releases:result.data.releases, - issues: result.data.issues, - isSpin: false - }) - } - }).catch((error) => { - console.log(error); - }) - } - - // 显示版本描述 - showBody=(key,flag)=>{ - let { releases } = this.state; - releases[key].bodyshow = !flag; - this.setState({ - releases - }) - } - - renderList = (releases) => { - const { projectsId , owner } = this.props.match.params; - const { isManager , isDeveloper } = this.props; - const type = this.props.projectDetail && this.props.projectDetail.type; - - if (releases && releases.length > 0) { - return ( - releases.map((item, key) => { - return ( -
    - - {item.draft} - {item.created_at} - - - {item.tag_name} - - -
    - - {item.name} - { - (isManager || isDeveloper) && type !==2 && - (编辑) - } - - - this.showBody(key,item.bodyshow)}> - {item.user_name}:发布了这个版本,并在发布后提交给{item.target_commitish} - - { - item.bodyshow && - } - -

    - TAR - ZIP -

    -
    -
    - ) - }) - ) - } else if (releases && releases.length === 0) { - return ( ) - } - } - - render() { - const { projectsId ,owner } = this.props.match.params; - const { data , releases , isSpin } = this.state; - const type = this.props.projectDetail && this.props.projectDetail.type; - return ( -
    -
    - 版本发布 - { - data && data.user_permission && type !== 2 ? - + 发布新版 - : '' - } -
    -
    -
    {this.renderList(releases)}
    -
    -
    - ) - } -} -export default version; \ No newline at end of file diff --git a/src/forge/common/util.js b/src/forge/common/util.js index 4f8f0bf32..1b35ea23b 100644 --- a/src/forge/common/util.js +++ b/src/forge/common/util.js @@ -6,3 +6,11 @@ export function truncateCommitId(str) { return str } } + +// 秒数转2021-9-29 01:01 +export function timeFormat(SecondsStr){ + const time = new Date(SecondsStr*1000); + const hour = time.getHours()<10?"0".concat(time.getHours()):time.getHours(); + const minutes = time.getMinutes()<10?"0".concat(time.getMinutes()):time.getMinutes(); + return time.getFullYear()+"-"+(time.getMonth()+1)+"-"+time.getDate()+" "+hour+":"+minutes; +} \ No newline at end of file diff --git a/src/forge/css/index.scss b/src/forge/css/index.scss index d9a5b071c..5926c734f 100644 --- a/src/forge/css/index.scss +++ b/src/forge/css/index.scss @@ -88,14 +88,23 @@ ul,ol,dl{ display: flex; flex-wrap: wrap; align-items: center; + &>span, & a:link, a:visited{ + color: #333; + } + &>span{ + cursor: default; + } } .commitDesc{ flex:1; - margin-left:20px; - font-size:16px; - color:#333; - line-height:26px; + line-height:20px; word-break: break-all; + width: 49rem; + overflow: hidden; + white-space: normal; + &:hover{ + text-decoration: underline; + } } .normalBox{ @@ -143,7 +152,7 @@ form.ant-form{ } form{ .ant-row.ant-form-item{ - margin-bottom: 15px; + margin-bottom: 20px; } } @media screen and (max-width: 1000px){ @@ -285,4 +294,50 @@ form{ border-bottom: none; } } +} +.btn-83{ + width: 83px; + height: 32px; + line-height: 30px; + text-align: center; + background: #FAFBFC; + border: 1px solid #D0D0D0; + display: inline-block; + border-radius: 5px; + font-weight: 500; + color: #333333!important; + margin-right: 15px; + &:hover{ + background: #F3F4F6; + color: #333333!important; + } + &:active{ + background: #D0D0D0; + color: #333333!important; + } +} +.shadow:hover{ + background: #eeeff1; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +a.hover:hover{ + text-decoration: underline; +} +button.ant-btn-primary.btnblue{ + background-color:rgba(70, 106, 255, 1); + border-color:rgba(70, 106, 255, 1); + &:hover{ + background-color:rgba(70, 106, 255, 0.85); + border-color:rgba(70, 106, 255, 0.85); + } +} +button.btngrey{ + background-color:#FFFFFF; + border-color:#D0D0D0; + color: #666666; + &:hover,&:focus{ + border-color:rgba(153, 153, 153, 0.5); + color: #666666; + } } \ No newline at end of file diff --git a/src/index.css b/src/index.css index e58df61f0..4c75d804f 100644 --- a/src/index.css +++ b/src/index.css @@ -30,11 +30,11 @@ .ant-upload-list-item-info .anticon-loading, .ant-upload-list-item-info .anticon-paper-clip { - color: #29bd8b !important; + color: rgba(102, 102, 102, 1) !important; } .anticon anticon-paper-clip { - color: #29bd8b !important; + color: rgba(102, 102, 102, 1) !important; } .MuiModal-root-15 { diff --git a/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js b/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js index 4f1e6d813..d6df12c4e 100644 --- a/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js +++ b/src/modules/courses/competitions/Competitioncommon/CompetitionCommonChild/CompetitionContentspdfChild/CompetitionContentspdfpeopledata.js @@ -53,8 +53,6 @@ class CompetitionContentspdfpeopledata extends Component { let url = `/users/accounts/${id}.json`; axios.get(url).then((result) => { if (result.data) { - console.log("GetuseridApi"); - console.log(result.data); this.setState({ userdata:result.data }) diff --git a/src/modules/courses/css/Courses.css b/src/modules/courses/css/Courses.css index 73d320ed7..cf5f1783e 100644 --- a/src/modules/courses/css/Courses.css +++ b/src/modules/courses/css/Courses.css @@ -938,7 +938,7 @@ body #root { } .ant-input:focus { - border: 1px solid #d9d9d9 !important; + border: 1px solid rgba(70, 106, 255, 1) !important; } /* 公用的文字按钮:蓝、白、灰 */ @@ -1423,7 +1423,7 @@ samp { } .newcourses .ant-select-selection--single:hover { - border: 1px solid #d9d9d9 !important; + border: 1px solid rgba(70, 106, 255, 1) !important; } .pd20 { @@ -1528,9 +1528,6 @@ samp { display: none; } -.exerciselist .ant-input { - border: 1px solid #d9d9d9 !important; -} .exercisetime .ant-form-explain { margin-left: 107px; @@ -1689,18 +1686,12 @@ samp { height: 40px; } -.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled) { - border: 1px solid #d9d9d9 !important; -} .ant-input-affix-wrapper .ant-input-prefix, .ant-input-affix-wrapper .ant-input-suffix { background: #fafafa !important; } -.ant-input:hover { - border: 1px solid #d9d9d9 !important; -} .ant-input:focus { box-shadow: none !important; diff --git a/src/modules/courses/publicNav/nav.css b/src/modules/courses/publicNav/nav.css index b6d8c7aab..1d6edf785 100644 --- a/src/modules/courses/publicNav/nav.css +++ b/src/modules/courses/publicNav/nav.css @@ -11,9 +11,6 @@ .ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled){ border:1px solid #d9d9d9!important; } -.ant-input:hover{ - border:1px solid #d9d9d9!important; -} .ant-input:focus{ box-shadow:none!important; background-color: #fff!important; diff --git a/src/modules/tpm/TPMIndex.css b/src/modules/tpm/TPMIndex.css index 859ddcf96..bdd6d36a8 100644 --- a/src/modules/tpm/TPMIndex.css +++ b/src/modules/tpm/TPMIndex.css @@ -163,7 +163,6 @@ body>.-task-title { outline: 0; -webkit-box-shadow: 0 0 0 2px transparent; box-shadow: 0 0 0 2px transparent; - border: 1px solid #d9d9d9; } .HeaderSearch .ant-input-search .ant-input::-webkit-input-placeholder {