Compare commits
No commits in common. "master" and "master" have entirely different histories.
File diff suppressed because it is too large
Load Diff
|
@ -1,2 +0,0 @@
|
||||||
{
|
|
||||||
}
|
|
124
LICENSE
124
LICENSE
|
@ -1,124 +0,0 @@
|
||||||
木兰宽松许可证, 第2版
|
|
||||||
|
|
||||||
2020年1月 http://license.coscl.org.cn/MulanPSL2
|
|
||||||
|
|
||||||
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
|
|
||||||
|
|
||||||
0. 定义
|
|
||||||
|
|
||||||
“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
|
|
||||||
|
|
||||||
“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
|
|
||||||
|
|
||||||
“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
|
|
||||||
|
|
||||||
“法人实体” 是指提交贡献的机构及其“关联实体”。
|
|
||||||
|
|
||||||
“关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
|
|
||||||
|
|
||||||
1. 授予版权许可
|
|
||||||
|
|
||||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
|
|
||||||
|
|
||||||
2. 授予专利许可
|
|
||||||
|
|
||||||
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
|
|
||||||
|
|
||||||
3. 无商标许可
|
|
||||||
|
|
||||||
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
|
|
||||||
|
|
||||||
4. 分发限制
|
|
||||||
|
|
||||||
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
|
|
||||||
|
|
||||||
5. 免责声明与责任限制
|
|
||||||
|
|
||||||
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
|
|
||||||
|
|
||||||
6. 语言
|
|
||||||
|
|
||||||
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
|
|
||||||
|
|
||||||
条款结束
|
|
||||||
|
|
||||||
如何将木兰宽松许可证,第2版,应用到您的软件
|
|
||||||
|
|
||||||
如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
|
|
||||||
|
|
||||||
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
|
|
||||||
|
|
||||||
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
|
|
||||||
|
|
||||||
3, 请将如下声明文本放入每个源文件的头部注释中。
|
|
||||||
|
|
||||||
Copyright (c) [Year] [name of copyright holder]
|
|
||||||
[Software Name] is licensed under Mulan PSL v2.
|
|
||||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
http://license.coscl.org.cn/MulanPSL2
|
|
||||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
See the Mulan PSL v2 for more details.
|
|
||||||
Mulan Permissive Software License,Version 2
|
|
||||||
Mulan Permissive Software License,Version 2 (Mulan PSL v2)
|
|
||||||
|
|
||||||
January 2020 http://license.coscl.org.cn/MulanPSL2
|
|
||||||
|
|
||||||
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
|
|
||||||
|
|
||||||
0. Definition
|
|
||||||
|
|
||||||
Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
|
|
||||||
|
|
||||||
Contribution means the copyrightable work licensed by a particular Contributor under this License.
|
|
||||||
|
|
||||||
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
|
|
||||||
|
|
||||||
Legal Entity means the entity making a Contribution and all its Affiliates.
|
|
||||||
|
|
||||||
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
|
|
||||||
|
|
||||||
1. Grant of Copyright License
|
|
||||||
|
|
||||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
|
|
||||||
|
|
||||||
2. Grant of Patent License
|
|
||||||
|
|
||||||
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
|
|
||||||
|
|
||||||
3. No Trademark License
|
|
||||||
|
|
||||||
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.
|
|
||||||
|
|
||||||
4. Distribution Restriction
|
|
||||||
|
|
||||||
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
|
|
||||||
|
|
||||||
5. Disclaimer of Warranty and Limitation of Liability
|
|
||||||
|
|
||||||
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
6. Language
|
|
||||||
|
|
||||||
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
|
|
||||||
|
|
||||||
END OF THE TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software
|
|
||||||
|
|
||||||
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
|
|
||||||
|
|
||||||
Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
|
|
||||||
Create a file named "LICENSE" which contains the whole context of this License in the first directory of your software package;
|
|
||||||
Attach the statement to the appropriate annotated syntax at the beginning of each source file.
|
|
||||||
Copyright (c) [Year] [name of copyright holder]
|
|
||||||
[Software Name] is licensed under Mulan PSL v2.
|
|
||||||
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
http://license.coscl.org.cn/MulanPSL2
|
|
||||||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
See the Mulan PSL v2 for more details.
|
|
|
@ -19,8 +19,7 @@ const getClientEnvironment = require("./env");
|
||||||
|
|
||||||
let publicPath = "/react/build/";
|
let publicPath = "/react/build/";
|
||||||
const publicUrl = publicPath.slice(0, -1);
|
const publicUrl = publicPath.slice(0, -1);
|
||||||
// const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
|
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
|
||||||
const shouldUseSourceMap = process.env.NODE_ENV !== "production";
|
|
||||||
const env = getClientEnvironment(publicPath);
|
const env = getClientEnvironment(publicPath);
|
||||||
|
|
||||||
// This is the production configuration.
|
// This is the production configuration.
|
||||||
|
@ -55,8 +54,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
bail: true,
|
bail: true,
|
||||||
mode: "production",
|
mode: "production",
|
||||||
// devtool: false, //测试版
|
devtool: false, //测试版
|
||||||
devtool: shouldUseSourceMap?'source-map':false,
|
|
||||||
entry: [require.resolve("./polyfills"), paths.appIndexJs],
|
entry: [require.resolve("./polyfills"), paths.appIndexJs],
|
||||||
output: {
|
output: {
|
||||||
path: paths.appBuild,
|
path: paths.appBuild,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "forge",
|
"name": "forge",
|
||||||
"version": "3.0.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@monaco-editor/react": "^2.3.0",
|
"@monaco-editor/react": "^2.3.0",
|
||||||
|
@ -14,7 +14,6 @@
|
||||||
"babel-jest": "20.0.3",
|
"babel-jest": "20.0.3",
|
||||||
"babel-loader": "7.1.2",
|
"babel-loader": "7.1.2",
|
||||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||||
"babel-polyfill": "^6.26.0",
|
|
||||||
"babel-preset-react-app": "^3.1.1",
|
"babel-preset-react-app": "^3.1.1",
|
||||||
"babel-runtime": "6.26.0",
|
"babel-runtime": "6.26.0",
|
||||||
"bizcharts": "^3.5.8",
|
"bizcharts": "^3.5.8",
|
||||||
|
@ -22,17 +21,15 @@
|
||||||
"case-sensitive-paths-webpack-plugin": "2.1.1",
|
"case-sensitive-paths-webpack-plugin": "2.1.1",
|
||||||
"chalk": "1.1.3",
|
"chalk": "1.1.3",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"clipboard": "^2.0.8",
|
"clipboard": "^2.0.6",
|
||||||
"code-prettify": "^0.1.0",
|
"code-prettify": "^0.1.0",
|
||||||
"codemirror": "^5.53.0",
|
"codemirror": "^5.53.0",
|
||||||
"connected-react-router": "4.4.1",
|
"connected-react-router": "4.4.1",
|
||||||
"cross-env": "^7.0.3",
|
|
||||||
"css-loader": "^3.5.2",
|
"css-loader": "^3.5.2",
|
||||||
"dompurify": "^2.0.15",
|
"dompurify": "^2.0.15",
|
||||||
"dotenv": "4.0.0",
|
"dotenv": "4.0.0",
|
||||||
"dotenv-expand": "4.2.0",
|
"dotenv-expand": "4.2.0",
|
||||||
"echarts": "^4.9.0",
|
"echarts": "^4.7.0",
|
||||||
"echarts-wordcloud": "^2.0.0",
|
|
||||||
"editor.md": "^1.5.0",
|
"editor.md": "^1.5.0",
|
||||||
"eslint": "4.10.0",
|
"eslint": "4.10.0",
|
||||||
"eslint-config-react-app": "^2.1.0",
|
"eslint-config-react-app": "^2.1.0",
|
||||||
|
@ -49,7 +46,6 @@
|
||||||
"install": "^0.12.2",
|
"install": "^0.12.2",
|
||||||
"jest": "20.0.4",
|
"jest": "20.0.4",
|
||||||
"js-base64": "^2.5.2",
|
"js-base64": "^2.5.2",
|
||||||
"js2wordcloud": "^1.1.12",
|
|
||||||
"katex": "^0.11.1",
|
"katex": "^0.11.1",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"loglevel": "^1.6.8",
|
"loglevel": "^1.6.8",
|
||||||
|
@ -66,7 +62,7 @@
|
||||||
"postcss-loader": "2.0.8",
|
"postcss-loader": "2.0.8",
|
||||||
"promise": "8.0.1",
|
"promise": "8.0.1",
|
||||||
"prop-types": "^15.6.1",
|
"prop-types": "^15.6.1",
|
||||||
"qrcode.react": "^1.0.1",
|
"qrcode.react": "^1.0.0",
|
||||||
"qs": "^6.9.3",
|
"qs": "^6.9.3",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
"quill-delta-to-html": "^0.11.0",
|
"quill-delta-to-html": "^0.11.0",
|
||||||
|
@ -96,7 +92,6 @@
|
||||||
"react-resizable": "^1.10.1",
|
"react-resizable": "^1.10.1",
|
||||||
"react-router": "^4.2.0",
|
"react-router": "^4.2.0",
|
||||||
"react-router-dom": "^4.2.2",
|
"react-router-dom": "^4.2.2",
|
||||||
"react-slick": "^0.28.1",
|
|
||||||
"react-split-pane": "^0.1.91",
|
"react-split-pane": "^0.1.91",
|
||||||
"react-url-query": "^1.5.0",
|
"react-url-query": "^1.5.0",
|
||||||
"react-zmage": "^0.8.5-beta.31",
|
"react-zmage": "^0.8.5-beta.31",
|
||||||
|
@ -104,11 +99,9 @@
|
||||||
"redux-thunk": "2.3.0",
|
"redux-thunk": "2.3.0",
|
||||||
"rsuite": "^4.3.4",
|
"rsuite": "^4.3.4",
|
||||||
"sass-loader": "7.3.1",
|
"sass-loader": "7.3.1",
|
||||||
"save-dev": "0.0.1-security",
|
|
||||||
"scroll-into-view": "^1.14.2",
|
"scroll-into-view": "^1.14.2",
|
||||||
"showdown": "^1.9.1",
|
"showdown": "^1.9.1",
|
||||||
"showdown-katex": "^0.8.0",
|
"showdown-katex": "^0.8.0",
|
||||||
"slick-carousel": "^1.8.1",
|
|
||||||
"store": "^2.0.12",
|
"store": "^2.0.12",
|
||||||
"style-loader": "0.19.0",
|
"style-loader": "0.19.0",
|
||||||
"styled-components": "^4.4.1",
|
"styled-components": "^4.4.1",
|
||||||
|
@ -124,8 +117,8 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node --max_old_space_size=15360 scripts/start.js",
|
"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",
|
"build": "NODE_ENV=production 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",
|
"test-build": "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",
|
"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",
|
"gen_stats": "NODE_ENV=production webpack --profile --config=./config/webpack.config.prod.js --json > stats.json",
|
||||||
"ana": "webpack-bundle-analyzer ./stats.json",
|
"ana": "webpack-bundle-analyzer ./stats.json",
|
||||||
|
@ -187,7 +180,7 @@
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "react-app"
|
"extends": "react-app"
|
||||||
},
|
},
|
||||||
"proxy": "http://localhost:3001",
|
"proxy": "http://localhost:3000",
|
||||||
"port": "3007",
|
"port": "3007",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/runtime": "7.0.0-beta.51",
|
"@babel/runtime": "7.0.0-beta.51",
|
||||||
|
@ -195,7 +188,6 @@
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
"babel-plugin-import": "^1.13.0",
|
"babel-plugin-import": "^1.13.0",
|
||||||
"babel-plugin-transform-runtime": "^6.23.0",
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
"babel-polyfill": "^6.26.0",
|
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"babel-preset-stage-2": "^6.24.1",
|
"babel-preset-stage-2": "^6.24.1",
|
||||||
|
@ -206,7 +198,6 @@
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^4.12.0",
|
||||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||||
"purgecss": "^2.1.2",
|
"purgecss": "^2.1.2",
|
||||||
"react-json-view": "^1.21.3",
|
|
||||||
"reqwest": "^2.0.5",
|
"reqwest": "^2.0.5",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"terser-webpack-plugin": "^2.3.5",
|
"terser-webpack-plugin": "^2.3.5",
|
||||||
|
|
|
@ -38,6 +38,78 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li {
|
||||||
|
float: left;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
margin-right: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
font-size: 16px
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li a {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
color: #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li a:hover {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li:last-child {
|
||||||
|
margin-right: 0px
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li.active a {
|
||||||
|
color: #459be5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li.active p {
|
||||||
|
color: #459be5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li p:hover {
|
||||||
|
color: #cccccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li p {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
color: #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li.active div ul li a {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li.active div ul li a:hover {
|
||||||
|
color: #FFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li.active ul li a {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li.active ul li a:hover {
|
||||||
|
color: #FFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-nav ul#header-nav li.active:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
top: auto;
|
||||||
|
bottom: 10px;
|
||||||
|
right: auto;
|
||||||
|
height: 2px;
|
||||||
|
width: 14px;
|
||||||
|
background-color: #459be5;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-img {
|
.nav-img {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
|
|
|
@ -114,6 +114,14 @@ a:visited {
|
||||||
color: #898989;
|
color: #898989;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #FF7500;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover.fa {
|
||||||
|
color: #FF7500;
|
||||||
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
textarea,
|
textarea,
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -97,6 +97,10 @@ a:visited {
|
||||||
color: #05101a;
|
color: #05101a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #459be5;
|
||||||
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul,
|
ul,
|
||||||
li {
|
li {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
@charset "utf-8";
|
|
||||||
/* 头部 */
|
/* 头部 */
|
||||||
.header {
|
.header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1272,7 +1271,7 @@ html body {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 2.0;
|
line-height: 2.0;
|
||||||
background: #fafafa;
|
background: #fafafa;
|
||||||
font-family: "Microsoft YaHei", "SimSun";
|
font-family: "微软雅黑", "宋体";
|
||||||
color: #05101a;
|
color: #05101a;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -1308,7 +1307,6 @@ td,
|
||||||
span {
|
span {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-bottom: 0px!important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table,
|
table,
|
||||||
|
@ -1365,6 +1363,10 @@ a:visited {
|
||||||
color: #05101a;
|
color: #05101a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #459be5;
|
||||||
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul,
|
ul,
|
||||||
li {
|
li {
|
||||||
|
@ -1471,7 +1473,7 @@ a.edu-txt-w80,
|
||||||
|
|
||||||
/*隐藏*/
|
/*隐藏*/
|
||||||
.none {
|
.none {
|
||||||
display: none!important;
|
display: none
|
||||||
}
|
}
|
||||||
|
|
||||||
.block {
|
.block {
|
||||||
|
@ -1520,15 +1522,7 @@ a.edu-txt-w80,
|
||||||
.font-16 {
|
.font-16 {
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
}
|
}
|
||||||
.weight400{
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
.weight500{
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.weight{
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.font-17 {
|
.font-17 {
|
||||||
font-size: 17px !important;
|
font-size: 17px !important;
|
||||||
}
|
}
|
||||||
|
@ -1548,9 +1542,6 @@ a.edu-txt-w80,
|
||||||
.font-25 {
|
.font-25 {
|
||||||
font-size: 25px !important;
|
font-size: 25px !important;
|
||||||
}
|
}
|
||||||
.font-26 {
|
|
||||||
font-size: 26px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-24 {
|
.font-24 {
|
||||||
font-size: 24px !important;
|
font-size: 24px !important;
|
||||||
|
@ -1572,9 +1563,6 @@ a.edu-txt-w80,
|
||||||
font-size: 36px !important;
|
font-size: 36px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-40 {
|
|
||||||
font-size: 40px !important;
|
|
||||||
}
|
|
||||||
.font-50 {
|
.font-50 {
|
||||||
font-size: 50px !important;
|
font-size: 50px !important;
|
||||||
}
|
}
|
||||||
|
@ -1760,20 +1748,12 @@ a.decoration {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb12 {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb13 {
|
|
||||||
margin-bottom: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mb14 {
|
.mb14 {
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb15 {
|
.mb15 {
|
||||||
margin-bottom: 15px!important;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb16 {
|
.mb16 {
|
||||||
|
@ -2444,23 +2424,13 @@ input::-ms-clear {
|
||||||
.color-grey-c {
|
.color-grey-c {
|
||||||
color: #ccc !important;
|
color: #ccc !important;
|
||||||
}
|
}
|
||||||
a.hoverLine:hover{
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.color-grey-cd {
|
.color-grey-cd {
|
||||||
color: #cdcdcd !important;
|
color: #cdcdcd !important;
|
||||||
}
|
}
|
||||||
.color-grey-d {
|
|
||||||
color: #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.color-grey-9 {
|
.color-grey-9 {
|
||||||
color: #999 !important;
|
color: #999999 !important;
|
||||||
}
|
|
||||||
|
|
||||||
a:hover{
|
|
||||||
color: #466AFF !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-grey-98 {
|
.color-grey-98 {
|
||||||
|
@ -2495,23 +2465,33 @@ a:hover{
|
||||||
a.color-grey-name:hover,
|
a.color-grey-name:hover,
|
||||||
a.color-dark:hover,
|
a.color-dark:hover,
|
||||||
a.color-grey-6:hover,
|
a.color-grey-6:hover,
|
||||||
a.color-grey-3:hover,a.color-ooo:hover {
|
a.color-grey-3:hover {
|
||||||
color: #2A61FF !important;
|
color: #4cacff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.color-grey-9:hover,
|
||||||
|
a.color-grey-8:hover,
|
||||||
|
a.color-grey-c:hover {
|
||||||
|
color: #111C24 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*蓝色*/
|
/*蓝色*/
|
||||||
.color-blue {
|
.color-blue {
|
||||||
color: #2A61FF !important;
|
color: #4CACFF !important;
|
||||||
}
|
|
||||||
.color-blue-file {
|
|
||||||
color: #4598FA!important;
|
|
||||||
}
|
}
|
||||||
/* 绿色 */
|
/* 绿色 */
|
||||||
|
.color-green-file{
|
||||||
|
color: #28BD6C;
|
||||||
|
}
|
||||||
/*主*/
|
/*主*/
|
||||||
.color-blue_4C {
|
.color-blue_4C {
|
||||||
color: #4CACFF !important;
|
color: #4CACFF !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.color-blue:hover,
|
||||||
|
a.color-blue_4C:hover {
|
||||||
|
color: #459BE6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
/*橙色*/
|
/*橙色*/
|
||||||
.color-orange {
|
.color-orange {
|
||||||
|
@ -3429,7 +3409,7 @@ a.user_bluebg_btn {
|
||||||
}
|
}
|
||||||
|
|
||||||
.cdefault {
|
.cdefault {
|
||||||
cursor: default!important;
|
cursor: default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3604,6 +3584,42 @@ a.user_bluebg_btn {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------个人主页:右侧提示区域--------------------------*/
|
||||||
|
.-task-sidebar {
|
||||||
|
position: fixed;
|
||||||
|
width: 40px;
|
||||||
|
height: 180px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 80px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.-task-sidebar div {
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 40px;
|
||||||
|
background: #4CACFF;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 20px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.-task-sidebar div i {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.-task-sidebar div i:hover {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gotop {
|
||||||
|
background-color: rgba(208, 207, 207, 0.5) !important;
|
||||||
|
padding: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***** loading ******/
|
/***** loading ******/
|
||||||
/*****载入中******/
|
/*****载入中******/
|
||||||
|
@ -3928,21 +3944,11 @@ html>body #ajax-indicator {
|
||||||
max-height: 340px;
|
max-height: 340px;
|
||||||
}/*头部导航条样式---2018-03-19--by-cs*/
|
}/*头部导航条样式---2018-03-19--by-cs*/
|
||||||
|
|
||||||
.privateTag{
|
|
||||||
display: block;
|
|
||||||
padding:0px 6px;
|
|
||||||
border-radius: 12px;
|
|
||||||
border:1px solid #2FC25B;
|
|
||||||
height: 18px;
|
|
||||||
line-height: 18px;
|
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 10px;
|
|
||||||
color: #2FC25B;
|
|
||||||
}
|
|
||||||
.head-nav {
|
.head-nav {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
min-width: 780px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -3964,7 +3970,7 @@ html>body #ajax-indicator {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding-right:40px;
|
padding:0px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.head-nav ul#header-nav li a {
|
.head-nav ul#header-nav li a {
|
||||||
|
@ -6706,9 +6712,3 @@ p{
|
||||||
top:4px;
|
top:4px;
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
.ant-input, .ant-input .ant-input-suffix{
|
|
||||||
background-color: #fff!important;
|
|
||||||
}
|
|
||||||
.has-error .ant-input{
|
|
||||||
background-color: #FEF1F0!important;
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -5,916 +5,6 @@
|
||||||
"css_prefix_text": "icon-",
|
"css_prefix_text": "icon-",
|
||||||
"description": "",
|
"description": "",
|
||||||
"glyphs": [
|
"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": "项目标签",
|
|
||||||
"font_class": "xiangmubiaoqian",
|
|
||||||
"unicode": "e8da",
|
|
||||||
"unicode_decimal": 59610
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24368060",
|
|
||||||
"name": "icon",
|
|
||||||
"font_class": "icon",
|
|
||||||
"unicode": "e8ce",
|
|
||||||
"unicode_decimal": 59598
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24368061",
|
|
||||||
"name": "tar",
|
|
||||||
"font_class": "tar",
|
|
||||||
"unicode": "e8cf",
|
|
||||||
"unicode_decimal": 59599
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289113",
|
|
||||||
"name": "复制 (2)",
|
|
||||||
"font_class": "a-fuzhi2",
|
|
||||||
"unicode": "e8d0",
|
|
||||||
"unicode_decimal": 59600
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289114",
|
|
||||||
"name": "附件",
|
|
||||||
"font_class": "fujian1",
|
|
||||||
"unicode": "e8d1",
|
|
||||||
"unicode_decimal": 59601
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289115",
|
|
||||||
"name": "编 辑",
|
|
||||||
"font_class": "a-bianji1",
|
|
||||||
"unicode": "e8d2",
|
|
||||||
"unicode_decimal": 59602
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289116",
|
|
||||||
"name": "版本icon",
|
|
||||||
"font_class": "banbenicon",
|
|
||||||
"unicode": "e8d3",
|
|
||||||
"unicode_decimal": 59603
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289117",
|
|
||||||
"name": "删除icon",
|
|
||||||
"font_class": "shanchuicon2",
|
|
||||||
"unicode": "e8d4",
|
|
||||||
"unicode_decimal": 59604
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289118",
|
|
||||||
"name": "垃圾桶_icon@3x",
|
|
||||||
"font_class": "a-lajitong_icon3x",
|
|
||||||
"unicode": "e8d5",
|
|
||||||
"unicode_decimal": 59605
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289119",
|
|
||||||
"name": "下拉按钮",
|
|
||||||
"font_class": "xialaanniu2",
|
|
||||||
"unicode": "e8d6",
|
|
||||||
"unicode_decimal": 59606
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289120",
|
|
||||||
"name": "下载-icon",
|
|
||||||
"font_class": "xiazai-icon",
|
|
||||||
"unicode": "e8d7",
|
|
||||||
"unicode_decimal": 59607
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289121",
|
|
||||||
"name": "master_icon",
|
|
||||||
"font_class": "master_icon1",
|
|
||||||
"unicode": "e8d8",
|
|
||||||
"unicode_decimal": 59608
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24289122",
|
|
||||||
"name": "上传icon",
|
|
||||||
"font_class": "shangchuanicon",
|
|
||||||
"unicode": "e8d9",
|
|
||||||
"unicode_decimal": 59609
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24059956",
|
|
||||||
"name": "个人资料",
|
|
||||||
"font_class": "gerenziliao1",
|
|
||||||
"unicode": "e8c7",
|
|
||||||
"unicode_decimal": 59591
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24059409",
|
|
||||||
"name": "里程碑icon",
|
|
||||||
"font_class": "lichengbeiicon",
|
|
||||||
"unicode": "e885",
|
|
||||||
"unicode_decimal": 59525
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24059410",
|
|
||||||
"name": "仓库设置icon",
|
|
||||||
"font_class": "cangkushezhiicon",
|
|
||||||
"unicode": "e889",
|
|
||||||
"unicode_decimal": 59529
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24059411",
|
|
||||||
"name": "动态icon",
|
|
||||||
"font_class": "dongtaiicon",
|
|
||||||
"unicode": "e88a",
|
|
||||||
"unicode_decimal": 59530
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24059412",
|
|
||||||
"name": "工作流icon",
|
|
||||||
"font_class": "gongzuoliuicon",
|
|
||||||
"unicode": "e88b",
|
|
||||||
"unicode_decimal": 59531
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24059413",
|
|
||||||
"name": "易修icon",
|
|
||||||
"font_class": "yixiuicon1",
|
|
||||||
"unicode": "e89b",
|
|
||||||
"unicode_decimal": 59547
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24059414",
|
|
||||||
"name": "wiki icon",
|
|
||||||
"font_class": "a-wikiicon1",
|
|
||||||
"unicode": "e8c6",
|
|
||||||
"unicode_decimal": 59590
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24047186",
|
|
||||||
"name": "代码库icon",
|
|
||||||
"font_class": "daimakuicon1",
|
|
||||||
"unicode": "e8c5",
|
|
||||||
"unicode_decimal": 59589
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24047189",
|
|
||||||
"name": "我的通知",
|
|
||||||
"font_class": "wodetongzhi",
|
|
||||||
"unicode": "e8c8",
|
|
||||||
"unicode_decimal": 59592
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24047190",
|
|
||||||
"name": "通知管理",
|
|
||||||
"font_class": "tongzhiguanli",
|
|
||||||
"unicode": "e8c9",
|
|
||||||
"unicode_decimal": 59593
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24047191",
|
|
||||||
"name": "选中",
|
|
||||||
"font_class": "xuanzhong3",
|
|
||||||
"unicode": "e8ca",
|
|
||||||
"unicode_decimal": 59594
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24047192",
|
|
||||||
"name": "系统通知icon",
|
|
||||||
"font_class": "xitongtongzhiicon",
|
|
||||||
"unicode": "e8cb",
|
|
||||||
"unicode_decimal": 59595
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24047193",
|
|
||||||
"name": "消息",
|
|
||||||
"font_class": "xiaoxi2",
|
|
||||||
"unicode": "e8cc",
|
|
||||||
"unicode_decimal": 59596
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24047194",
|
|
||||||
"name": "ssh密钥",
|
|
||||||
"font_class": "sshmiyue",
|
|
||||||
"unicode": "e8cd",
|
|
||||||
"unicode_decimal": 59597
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "24014152",
|
|
||||||
"name": "个人资料",
|
|
||||||
"font_class": "gerenziliao",
|
|
||||||
"unicode": "e8c4",
|
|
||||||
"unicode_decimal": 59588
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23655968",
|
|
||||||
"name": "新手指引",
|
|
||||||
"font_class": "xinshouzhiyin",
|
|
||||||
"unicode": "e8e4",
|
|
||||||
"unicode_decimal": 59620
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23655969",
|
|
||||||
"name": "新建项目",
|
|
||||||
"font_class": "xinjianxiangmu",
|
|
||||||
"unicode": "e8e6",
|
|
||||||
"unicode_decimal": 59622
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23658111",
|
|
||||||
"name": "加入课堂",
|
|
||||||
"font_class": "jiaruketang1",
|
|
||||||
"unicode": "e8e9",
|
|
||||||
"unicode_decimal": 59625
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23791639",
|
|
||||||
"name": "项目公告",
|
|
||||||
"font_class": "xiangmugonggao",
|
|
||||||
"unicode": "e8c2",
|
|
||||||
"unicode_decimal": 59586
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23791640",
|
|
||||||
"name": "成果",
|
|
||||||
"font_class": "chengguo",
|
|
||||||
"unicode": "e8c3",
|
|
||||||
"unicode_decimal": 59587
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23791410",
|
|
||||||
"name": "成交公告",
|
|
||||||
"font_class": "chengjiaogonggao",
|
|
||||||
"unicode": "e8c0",
|
|
||||||
"unicode_decimal": 59584
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23791411",
|
|
||||||
"name": "技术资产",
|
|
||||||
"font_class": "jishuzichan",
|
|
||||||
"unicode": "e8c1",
|
|
||||||
"unicode_decimal": 59585
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23790928",
|
|
||||||
"name": "废标公告",
|
|
||||||
"font_class": "feibiaogonggao",
|
|
||||||
"unicode": "e8bc",
|
|
||||||
"unicode_decimal": 59580
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23790929",
|
|
||||||
"name": "中标公告",
|
|
||||||
"font_class": "zhongbiaogonggao",
|
|
||||||
"unicode": "e8bd",
|
|
||||||
"unicode_decimal": 59581
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23790930",
|
|
||||||
"name": "更正公告",
|
|
||||||
"font_class": "gengzhenggonggao",
|
|
||||||
"unicode": "e8be",
|
|
||||||
"unicode_decimal": 59582
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23790931",
|
|
||||||
"name": "招标公告",
|
|
||||||
"font_class": "zhaobiaogonggao",
|
|
||||||
"unicode": "e8bf",
|
|
||||||
"unicode_decimal": 59583
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23732532",
|
|
||||||
"name": "文件",
|
|
||||||
"font_class": "wenjian6",
|
|
||||||
"unicode": "e8ba",
|
|
||||||
"unicode_decimal": 59578
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23732533",
|
|
||||||
"name": "文件夹",
|
|
||||||
"font_class": "wenjianjia4",
|
|
||||||
"unicode": "e8bb",
|
|
||||||
"unicode_decimal": 59579
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23642443",
|
|
||||||
"name": "取消关注",
|
|
||||||
"font_class": "quxiaoguanzhu",
|
|
||||||
"unicode": "e89a",
|
|
||||||
"unicode_decimal": 59546
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23642444",
|
|
||||||
"name": "点赞_icon",
|
|
||||||
"font_class": "dianzan_icon",
|
|
||||||
"unicode": "e8a2",
|
|
||||||
"unicode_decimal": 59554
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23639530",
|
|
||||||
"name": "文件",
|
|
||||||
"font_class": "wenjian5",
|
|
||||||
"unicode": "e896",
|
|
||||||
"unicode_decimal": 59542
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23639533",
|
|
||||||
"name": "文件夹",
|
|
||||||
"font_class": "wenjianjia3",
|
|
||||||
"unicode": "e8a9",
|
|
||||||
"unicode_decimal": 59561
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23639440",
|
|
||||||
"name": "复制icon",
|
|
||||||
"font_class": "fuzhiicon",
|
|
||||||
"unicode": "e886",
|
|
||||||
"unicode_decimal": 59526
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23639422",
|
|
||||||
"name": "主页-fill",
|
|
||||||
"font_class": "zhuye-fill",
|
|
||||||
"unicode": "e876",
|
|
||||||
"unicode_decimal": 59510
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23639423",
|
|
||||||
"name": "代码库icon",
|
|
||||||
"font_class": "daimakuicon",
|
|
||||||
"unicode": "e884",
|
|
||||||
"unicode_decimal": 59524
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23572260",
|
|
||||||
"name": "新建",
|
|
||||||
"font_class": "xinjian2",
|
|
||||||
"unicode": "e8b0",
|
|
||||||
"unicode_decimal": 59568
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23567674",
|
|
||||||
"name": "协议icon",
|
|
||||||
"font_class": "xieyiicon",
|
|
||||||
"unicode": "e870",
|
|
||||||
"unicode_decimal": 59504
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23567675",
|
|
||||||
"name": "内存icon",
|
|
||||||
"font_class": "neicunicon",
|
|
||||||
"unicode": "e891",
|
|
||||||
"unicode_decimal": 59537
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23567676",
|
|
||||||
"name": "自述文件_icon",
|
|
||||||
"font_class": "zishuwenjian_icon",
|
|
||||||
"unicode": "e8a6",
|
|
||||||
"unicode_decimal": 59558
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472253",
|
|
||||||
"name": "标签icon",
|
|
||||||
"font_class": "biaoqianicon",
|
|
||||||
"unicode": "e882",
|
|
||||||
"unicode_decimal": 59522
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472254",
|
|
||||||
"name": "编 辑",
|
|
||||||
"font_class": "a-bianji",
|
|
||||||
"unicode": "e883",
|
|
||||||
"unicode_decimal": 59523
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472258",
|
|
||||||
"name": "链接icon",
|
|
||||||
"font_class": "lianjieicon",
|
|
||||||
"unicode": "e887",
|
|
||||||
"unicode_decimal": 59527
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472259",
|
|
||||||
"name": "合并请求icon",
|
|
||||||
"font_class": "hebingqingqiuicon",
|
|
||||||
"unicode": "e888",
|
|
||||||
"unicode_decimal": 59528
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472263",
|
|
||||||
"name": "默认点赞_icon",
|
|
||||||
"font_class": "morendianzan_icon",
|
|
||||||
"unicode": "e88e",
|
|
||||||
"unicode_decimal": 59534
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472265",
|
|
||||||
"name": "目录icon",
|
|
||||||
"font_class": "muluicon",
|
|
||||||
"unicode": "e894",
|
|
||||||
"unicode_decimal": 59540
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472267",
|
|
||||||
"name": "设 置",
|
|
||||||
"font_class": "a-shezhi",
|
|
||||||
"unicode": "e899",
|
|
||||||
"unicode_decimal": 59545
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472269",
|
|
||||||
"name": "提交icon",
|
|
||||||
"font_class": "tijiaoicon",
|
|
||||||
"unicode": "e89e",
|
|
||||||
"unicode_decimal": 59550
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472270",
|
|
||||||
"name": "默认关注_ICON",
|
|
||||||
"font_class": "morenguanzhu_ICON",
|
|
||||||
"unicode": "e89f",
|
|
||||||
"unicode_decimal": 59551
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472272",
|
|
||||||
"name": "下拉按钮",
|
|
||||||
"font_class": "xialaanniu1",
|
|
||||||
"unicode": "e8a4",
|
|
||||||
"unicode_decimal": 59556
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472276",
|
|
||||||
"name": "左滑icon",
|
|
||||||
"font_class": "zuohuaicon",
|
|
||||||
"unicode": "e8b5",
|
|
||||||
"unicode_decimal": 59573
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472277",
|
|
||||||
"name": "master_icon",
|
|
||||||
"font_class": "master_icon",
|
|
||||||
"unicode": "e8b6",
|
|
||||||
"unicode_decimal": 59574
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472278",
|
|
||||||
"name": "默认复刻_icon",
|
|
||||||
"font_class": "morenfuke_icon",
|
|
||||||
"unicode": "e8b7",
|
|
||||||
"unicode_decimal": 59575
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472279",
|
|
||||||
"name": "wiki icon",
|
|
||||||
"font_class": "a-wikiicon",
|
|
||||||
"unicode": "e8b8",
|
|
||||||
"unicode_decimal": 59576
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23472280",
|
|
||||||
"name": "易修icon",
|
|
||||||
"font_class": "yixiuicon",
|
|
||||||
"unicode": "e8b9",
|
|
||||||
"unicode_decimal": 59577
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23436350",
|
|
||||||
"name": "缩放",
|
|
||||||
"font_class": "suofang",
|
|
||||||
"unicode": "e87f",
|
|
||||||
"unicode_decimal": 59519
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23436351",
|
|
||||||
"name": "放大icon",
|
|
||||||
"font_class": "fangdaicon",
|
|
||||||
"unicode": "e881",
|
|
||||||
"unicode_decimal": 59521
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23384231",
|
|
||||||
"name": "搜索_icon",
|
|
||||||
"font_class": "sousuo_icon1",
|
|
||||||
"unicode": "e873",
|
|
||||||
"unicode_decimal": 59507
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23384232",
|
|
||||||
"name": "欢迎_icon",
|
|
||||||
"font_class": "huanying_icon",
|
|
||||||
"unicode": "e878",
|
|
||||||
"unicode_decimal": 59512
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23384233",
|
|
||||||
"name": "文件夹",
|
|
||||||
"font_class": "wenjianjia2",
|
|
||||||
"unicode": "e879",
|
|
||||||
"unicode_decimal": 59513
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23384234",
|
|
||||||
"name": "删除icon",
|
|
||||||
"font_class": "shanchuicon1",
|
|
||||||
"unicode": "e87a",
|
|
||||||
"unicode_decimal": 59514
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23261798",
|
|
||||||
"name": "请求icon",
|
|
||||||
"font_class": "qingqiuicon",
|
|
||||||
"unicode": "e871",
|
|
||||||
"unicode_decimal": 59505
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23261799",
|
|
||||||
"name": "响应icon",
|
|
||||||
"font_class": "xiangyingicon",
|
|
||||||
"unicode": "e87c",
|
|
||||||
"unicode_decimal": 59516
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144143",
|
|
||||||
"name": "多选选中",
|
|
||||||
"font_class": "duoxuanxuanzhong",
|
|
||||||
"unicode": "e88f",
|
|
||||||
"unicode_decimal": 59535
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144144",
|
|
||||||
"name": "错误icon",
|
|
||||||
"font_class": "cuowuicon",
|
|
||||||
"unicode": "e890",
|
|
||||||
"unicode_decimal": 59536
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144146",
|
|
||||||
"name": "成功icon",
|
|
||||||
"font_class": "chenggongicon",
|
|
||||||
"unicode": "e892",
|
|
||||||
"unicode_decimal": 59538
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144147",
|
|
||||||
"name": "未选中响应icon",
|
|
||||||
"font_class": "weixuanzhongxiangyingicon",
|
|
||||||
"unicode": "e893",
|
|
||||||
"unicode_decimal": 59539
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144149",
|
|
||||||
"name": "必填icon",
|
|
||||||
"font_class": "bitianicon",
|
|
||||||
"unicode": "e895",
|
|
||||||
"unicode_decimal": 59541
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144151",
|
|
||||||
"name": "未选中项目标签icon",
|
|
||||||
"font_class": "weixuanzhongxiangmubiaoqianicon",
|
|
||||||
"unicode": "e897",
|
|
||||||
"unicode_decimal": 59543
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144152",
|
|
||||||
"name": "列表icon",
|
|
||||||
"font_class": "liebiaoicon",
|
|
||||||
"unicode": "e898",
|
|
||||||
"unicode_decimal": 59544
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144158",
|
|
||||||
"name": "协作者管理icon",
|
|
||||||
"font_class": "xiezuozheguanliicon",
|
|
||||||
"unicode": "e8a1",
|
|
||||||
"unicode_decimal": 59553
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144160",
|
|
||||||
"name": "选中分支icon",
|
|
||||||
"font_class": "xuanzhongfenzhiicon",
|
|
||||||
"unicode": "e8a3",
|
|
||||||
"unicode_decimal": 59555
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144162",
|
|
||||||
"name": "选中基本设置icon",
|
|
||||||
"font_class": "xuanzhongjibenshezhiicon",
|
|
||||||
"unicode": "e8a5",
|
|
||||||
"unicode_decimal": 59557
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144165",
|
|
||||||
"name": "选中项目标签icon",
|
|
||||||
"font_class": "xuanzhongxiangmubiaoqianicon",
|
|
||||||
"unicode": "e8aa",
|
|
||||||
"unicode_decimal": 59562
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23144167",
|
|
||||||
"name": "选中webhook icon",
|
|
||||||
"font_class": "a-xuanzhongwebhookicon",
|
|
||||||
"unicode": "e8af",
|
|
||||||
"unicode_decimal": 59567
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046290",
|
|
||||||
"name": "shanchu_tc_icon",
|
|
||||||
"font_class": "shanchu_tc_icon",
|
|
||||||
"unicode": "e88c",
|
|
||||||
"unicode_decimal": 59532
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046293",
|
|
||||||
"name": "wiki_icon",
|
|
||||||
"font_class": "wiki_icon",
|
|
||||||
"unicode": "e88d",
|
|
||||||
"unicode_decimal": 59533
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046244",
|
|
||||||
"name": "导入模版_icon",
|
|
||||||
"font_class": "daorumoban_icon",
|
|
||||||
"unicode": "e86f",
|
|
||||||
"unicode_decimal": 59503
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046252",
|
|
||||||
"name": "错误",
|
|
||||||
"font_class": "cuowu",
|
|
||||||
"unicode": "e872",
|
|
||||||
"unicode_decimal": 59506
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046255",
|
|
||||||
"name": "更多_icon",
|
|
||||||
"font_class": "gengduo_icon",
|
|
||||||
"unicode": "e874",
|
|
||||||
"unicode_decimal": 59508
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046258",
|
|
||||||
"name": "复层关闭_icon",
|
|
||||||
"font_class": "fucengguanbi_icon",
|
|
||||||
"unicode": "e875",
|
|
||||||
"unicode_decimal": 59509
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046268",
|
|
||||||
"name": "删除icon",
|
|
||||||
"font_class": "shanchuicon",
|
|
||||||
"unicode": "e877",
|
|
||||||
"unicode_decimal": 59511
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046273",
|
|
||||||
"name": "搜索_删除icon",
|
|
||||||
"font_class": "sousuo_shanchuicon",
|
|
||||||
"unicode": "e87b",
|
|
||||||
"unicode_decimal": 59515
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046275",
|
|
||||||
"name": "搜索_icon",
|
|
||||||
"font_class": "sousuo_icon",
|
|
||||||
"unicode": "e87d",
|
|
||||||
"unicode_decimal": 59517
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046276",
|
|
||||||
"name": "文档预览_icon",
|
|
||||||
"font_class": "wendangyulan_icon",
|
|
||||||
"unicode": "e87e",
|
|
||||||
"unicode_decimal": 59518
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "23046278",
|
|
||||||
"name": "下拉按钮",
|
|
||||||
"font_class": "xialaanniu",
|
|
||||||
"unicode": "e880",
|
|
||||||
"unicode_decimal": 59520
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "22906287",
|
|
||||||
"name": "二次确认_icon",
|
|
||||||
"font_class": "erciqueren_icon",
|
|
||||||
"unicode": "e867",
|
|
||||||
"unicode_decimal": 59495
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "22906288",
|
|
||||||
"name": "选中ssh_icon",
|
|
||||||
"font_class": "xuanzhongssh_icon",
|
|
||||||
"unicode": "e868",
|
|
||||||
"unicode_decimal": 59496
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "22906289",
|
|
||||||
"name": "未选中安全设置_icon",
|
|
||||||
"font_class": "weixuanzhonganquanshezhi_icon",
|
|
||||||
"unicode": "e869",
|
|
||||||
"unicode_decimal": 59497
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "22906290",
|
|
||||||
"name": "未选中ssh_icon",
|
|
||||||
"font_class": "weixuanzhongssh_icon",
|
|
||||||
"unicode": "e86a",
|
|
||||||
"unicode_decimal": 59498
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "22906291",
|
|
||||||
"name": "选中安全设置_icon",
|
|
||||||
"font_class": "xuanzhonganquanshezhi_icon",
|
|
||||||
"unicode": "e86b",
|
|
||||||
"unicode_decimal": 59499
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "22906292",
|
|
||||||
"name": "删除_icon",
|
|
||||||
"font_class": "shanchu_icon",
|
|
||||||
"unicode": "e86c",
|
|
||||||
"unicode_decimal": 59500
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "22906293",
|
|
||||||
"name": "列表ssh_icon",
|
|
||||||
"font_class": "liebiaossh_icon",
|
|
||||||
"unicode": "e86e",
|
|
||||||
"unicode_decimal": 59502
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "17575494",
|
|
||||||
"name": "file-submodule",
|
|
||||||
"font_class": "file-submodule",
|
|
||||||
"unicode": "e866",
|
|
||||||
"unicode_decimal": 59494
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "7539612",
|
|
||||||
"name": "nv",
|
|
||||||
"font_class": "nv1",
|
|
||||||
"unicode": "e864",
|
|
||||||
"unicode_decimal": 59492
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "7539613",
|
|
||||||
"name": "nan",
|
|
||||||
"font_class": "nan1",
|
|
||||||
"unicode": "e865",
|
|
||||||
"unicode_decimal": 59493
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936935",
|
|
||||||
"name": "邮箱",
|
|
||||||
"font_class": "youxiang",
|
|
||||||
"unicode": "e8b2",
|
|
||||||
"unicode_decimal": 59570
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936924",
|
|
||||||
"name": "单位",
|
|
||||||
"font_class": "danwei",
|
|
||||||
"unicode": "e8a7",
|
|
||||||
"unicode_decimal": 59559
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936925",
|
|
||||||
"name": "待办事项",
|
|
||||||
"font_class": "daibanshixiang",
|
|
||||||
"unicode": "e8a8",
|
|
||||||
"unicode_decimal": 59560
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936928",
|
|
||||||
"name": "概览",
|
|
||||||
"font_class": "gailan",
|
|
||||||
"unicode": "e8ab",
|
|
||||||
"unicode_decimal": 59563
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936929",
|
|
||||||
"name": "男",
|
|
||||||
"font_class": "nan",
|
|
||||||
"unicode": "e8ac",
|
|
||||||
"unicode_decimal": 59564
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936930",
|
|
||||||
"name": "女",
|
|
||||||
"font_class": "nv",
|
|
||||||
"unicode": "e8ad",
|
|
||||||
"unicode_decimal": 59565
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936931",
|
|
||||||
"name": "工作流",
|
|
||||||
"font_class": "gongzuoliu1",
|
|
||||||
"unicode": "e8ae",
|
|
||||||
"unicode_decimal": 59566
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936934",
|
|
||||||
"name": "数据统计",
|
|
||||||
"font_class": "shujutongji",
|
|
||||||
"unicode": "e8b1",
|
|
||||||
"unicode_decimal": 59569
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936936",
|
|
||||||
"name": "项目",
|
|
||||||
"font_class": "xiangmu",
|
|
||||||
"unicode": "e8b3",
|
|
||||||
"unicode_decimal": 59571
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21936937",
|
|
||||||
"name": "组织",
|
|
||||||
"font_class": "zuzhi",
|
|
||||||
"unicode": "e8b4",
|
|
||||||
"unicode_decimal": 59572
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "14835599",
|
|
||||||
"name": "右箭头",
|
|
||||||
"font_class": "arrowRight",
|
|
||||||
"unicode": "e863",
|
|
||||||
"unicode_decimal": 59491
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21151489",
|
|
||||||
"name": "箭头镂空-左",
|
|
||||||
"font_class": "jiantouloukong-zuo",
|
|
||||||
"unicode": "e861",
|
|
||||||
"unicode_decimal": 59489
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21151557",
|
|
||||||
"name": "箭头镂空-右",
|
|
||||||
"font_class": "jiantouloukong-you",
|
|
||||||
"unicode": "e862",
|
|
||||||
"unicode_decimal": 59490
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21568989",
|
|
||||||
"name": "分享",
|
|
||||||
"font_class": "fenxiang1",
|
|
||||||
"unicode": "e89c",
|
|
||||||
"unicode_decimal": 59548
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21568990",
|
|
||||||
"name": "回到顶部",
|
|
||||||
"font_class": "huidaodingbu1",
|
|
||||||
"unicode": "e89d",
|
|
||||||
"unicode_decimal": 59549
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"icon_id": "21568993",
|
|
||||||
"name": "帮助",
|
|
||||||
"font_class": "bangzhu",
|
|
||||||
"unicode": "e8a0",
|
|
||||||
"unicode_decimal": 59552
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"icon_id": "991344",
|
"icon_id": "991344",
|
||||||
"name": "提交",
|
"name": "提交",
|
||||||
|
@ -5146,7 +4236,7 @@
|
||||||
{
|
{
|
||||||
"icon_id": "1004630",
|
"icon_id": "1004630",
|
||||||
"name": "点赞2",
|
"name": "点赞2",
|
||||||
"font_class": "dianzaned",
|
"font_class": "dianzan1",
|
||||||
"unicode": "e639",
|
"unicode": "e639",
|
||||||
"unicode_decimal": 58937
|
"unicode_decimal": 58937
|
||||||
},
|
},
|
||||||
|
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 733 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.8 KiB |
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN" class="notranslate translated-ltr" translate="no">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name=”Keywords” Content=”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″>
|
<meta name=”Keywords” Content=”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″>
|
||||||
|
|
|
@ -3319,9 +3319,9 @@
|
||||||
text = text.replace(emailReg, function ($1, $2, $3, $4) {
|
text = text.replace(emailReg, function ($1, $2, $3, $4) {
|
||||||
return $1.replace(/@/g, "_#_@_#_");
|
return $1.replace(/@/g, "_#_@_#_");
|
||||||
});
|
});
|
||||||
// " + editormd.urls.atLinkBase + "" + $2 + "
|
|
||||||
text = text.replace(atLinkReg, function ($1, $2) {
|
text = text.replace(atLinkReg, function ($1, $2) {
|
||||||
return "<span title=\"@" + $2 + "\" class=\"at-link\"> " + $1 + " </span>";
|
return "<a href=\"" + editormd.urls.atLinkBase + "" + $2 + "\" title=\"@" + $2 + "\" class=\"at-link\">" + $1 + "</a>";
|
||||||
}).replace(/_#_@_#_/g, "@");
|
}).replace(/_#_@_#_/g, "@");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,13 +60,12 @@ body {
|
||||||
.ant-progress-textno {
|
.ant-progress-textno {
|
||||||
color: #f5222d;
|
color: #f5222d;
|
||||||
}
|
}
|
||||||
.CodeMirror pre.CodeMirror-line{
|
|
||||||
font-size: 16px!important;
|
|
||||||
}
|
|
||||||
/* md多空格 */
|
/* md多空格 */
|
||||||
.markdown-body p {
|
.markdown-body p {
|
||||||
margin:10px 0px!important;
|
margin:10px 0px!important;
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
|
line-height: 2 !important;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,10 +87,6 @@ body {
|
||||||
border-left: 1px solid rgb(221, 221, 221);
|
border-left: 1px solid rgb(221, 221, 221);
|
||||||
/* 某些情况下,被cm盖住了 */
|
/* 某些情况下,被cm盖住了 */
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
padding:8px 8px 50px;
|
|
||||||
}
|
|
||||||
.editormd-preview .markdown-body{
|
|
||||||
padding:0px !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 图片点击放大的场景,隐藏图片链接 */
|
/* 图片点击放大的场景,隐藏图片链接 */
|
||||||
|
|
218
src/App.js
218
src/App.js
|
@ -3,7 +3,7 @@ import './App.css';
|
||||||
import { ConfigProvider } from 'antd'
|
import { ConfigProvider } from 'antd'
|
||||||
import zhCN from 'antd/lib/locale-provider/zh_CN';
|
import zhCN from 'antd/lib/locale-provider/zh_CN';
|
||||||
import {
|
import {
|
||||||
// BrowserRouter as Router,
|
BrowserRouter as Router,
|
||||||
Route,
|
Route,
|
||||||
Switch
|
Switch
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
|
@ -17,9 +17,10 @@ import marked from './common/marked';
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
|
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
|
||||||
import SiderBar from './forge/Component/SiderBar'
|
|
||||||
|
|
||||||
import { SnackbarHOC } from 'educoder';
|
import history from './history';
|
||||||
|
|
||||||
|
import { SnackbarHOC } from 'educoder'
|
||||||
import { initAxiosInterceptors } from './AppConfig'
|
import { initAxiosInterceptors } from './AppConfig'
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import configureStore from './redux/stores/configureStore';
|
import configureStore from './redux/stores/configureStore';
|
||||||
|
@ -39,16 +40,6 @@ const Projects = Loadable({
|
||||||
loader: () => import('./forge/Index'),
|
loader: () => import('./forge/Index'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
// forge项目详情
|
|
||||||
const ProjectDetail = Loadable({
|
|
||||||
loader: () => import("./forge/Main/DetailAdaptor"),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
//forge安全设置
|
|
||||||
const Security = Loadable({
|
|
||||||
loader: () => import('./forge/SecuritySetting/Index'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
//forge项目-devOps详情
|
//forge项目-devOps详情
|
||||||
const OpsDetail = Loadable({
|
const OpsDetail = Loadable({
|
||||||
loader: () => import('./forge/DevOps/opsDetail'),
|
loader: () => import('./forge/DevOps/opsDetail'),
|
||||||
|
@ -83,27 +74,6 @@ const EducoderLogin = Loadable({
|
||||||
loader: () => import('./modules/login/EducoderLogin'),
|
loader: () => import('./modules/login/EducoderLogin'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const Search = Loadable({
|
|
||||||
loader: () => import('./modules/search/'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
const WikiPreview = Loadable({
|
|
||||||
loader: () => import('./forge/Wiki/Preview'),
|
|
||||||
loading: Loading,
|
|
||||||
})
|
|
||||||
|
|
||||||
const ProjectIndex = Loadable({
|
|
||||||
loader: () => import("./forge/Index"),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
|
|
||||||
// const CreateMerge = Loadable({
|
|
||||||
// loader: () => import('./forge/Merge/NewMerge'),
|
|
||||||
// loading: Loading,
|
|
||||||
// })
|
|
||||||
|
|
||||||
// 此处仅维护前端可能的一级路由,不用进行项目或者组织判断的字段。
|
|
||||||
const keyWord = ["explore", "settings", "setting", "mulan", "wiki", "issues", "setting", "trending", "code", "projects", "pulls", "mine", "login", "register", "email", "export", "nopage", "404", "403", "500", "501", "search", "organize"];
|
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -114,51 +84,6 @@ class App extends Component {
|
||||||
mydisplay: false,
|
mydisplay: false,
|
||||||
occupation: 0,
|
occupation: 0,
|
||||||
mygetHelmetapi: null,
|
mygetHelmetapi: null,
|
||||||
pathType: null,
|
|
||||||
pathName: null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UNSAFE_componentWillMount() {
|
|
||||||
initAxiosInterceptors(this.props);
|
|
||||||
let pathname = window.location.pathname ? window.location.pathname.split('/')[1] : '';
|
|
||||||
pathname && this.getPathnameType(pathname);
|
|
||||||
|
|
||||||
// 添加路由监听,决定组织还是个人
|
|
||||||
this.unlisten = this.props.history.listen((location) => {
|
|
||||||
let newPathname = location.pathname.split('/')[1];
|
|
||||||
if (this.state.pathName !== newPathname) {
|
|
||||||
// this.setState({ pathType: '' });
|
|
||||||
newPathname && this.getPathnameType(newPathname);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
|
||||||
// (!keyWord.includes(this.props.location.pathname.split('/')[1])) &&
|
|
||||||
if (nextProps.location.pathname.split('/')[1] !== this.props.location.pathname.split('/')[1] && nextState.pathType === this.state.pathType) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getPathnameType = (pathname) => {
|
|
||||||
if (!keyWord.includes(pathname)) {
|
|
||||||
let url = `/owners/${pathname}.json`;
|
|
||||||
axios.get(url).then((response) => {
|
|
||||||
if (response && response.status === 200) {
|
|
||||||
this.setState({
|
|
||||||
pathType: response.data.type || '404',
|
|
||||||
pathName: pathname,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
this.setState({
|
|
||||||
pathType: pathname,
|
|
||||||
pathName: pathname,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,22 +100,43 @@ class App extends Component {
|
||||||
Addcoursestypes: false
|
Addcoursestypes: false
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
ModalCancelsy = () => {
|
||||||
|
this.setState({
|
||||||
|
mydisplay: false,
|
||||||
|
})
|
||||||
|
window.location.href = "/";
|
||||||
|
};
|
||||||
|
ModalshowCancelsy = () => {
|
||||||
|
this.setState({
|
||||||
|
mydisplay: true,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
disableVideoContextMenu = () => {
|
||||||
|
window.$("body").on("mousedown", "video", function (event) {
|
||||||
|
if (event.which === 3) {
|
||||||
|
window.$('video').bind('contextmenu', function () { return false; });
|
||||||
|
} else {
|
||||||
|
window.$('video').unbind('contextmenu');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
document.title = "loading...";
|
document.title = "loading...";
|
||||||
|
this.disableVideoContextMenu();
|
||||||
|
history.listen(() => {
|
||||||
|
this.forceUpdate()
|
||||||
|
const $ = window.$
|
||||||
|
$("html").animate({ scrollTop: $('html').scrollTop() - 0 })
|
||||||
|
});
|
||||||
|
|
||||||
|
initAxiosInterceptors(this.props);
|
||||||
this.getAppdata();
|
this.getAppdata();
|
||||||
|
|
||||||
window.addEventListener('error', (event) => {
|
window.addEventListener('error', (event) => {
|
||||||
const msg = `${event.type}: ${event.message}`;
|
const msg = `${event.type}: ${event.message}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.unlisten && this.unlisten(); // 执行解绑
|
|
||||||
}
|
|
||||||
|
|
||||||
//修改登录方法
|
//修改登录方法
|
||||||
Modifyloginvalue = () => {
|
Modifyloginvalue = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -261,48 +207,31 @@ class App extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { mygetHelmetapi, pathType} = this.state;
|
|
||||||
let personal = mygetHelmetapi && mygetHelmetapi.personal;
|
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ConfigProvider locale={zhCN}>
|
<ConfigProvider locale={zhCN}>
|
||||||
<MuiThemeProvider theme={theme}>
|
<MuiThemeProvider theme={theme}>
|
||||||
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
|
||||||
<SiderBar />
|
<Router>
|
||||||
{/* <Router> */}
|
|
||||||
<Switch>
|
<Switch>
|
||||||
{/* wiki预览 */}
|
|
||||||
<Route path="/:owner/:projectsId/wiki/preview/:projectName/:projectId" render={
|
|
||||||
(props) => {
|
|
||||||
return (<WikiPreview {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
} />
|
|
||||||
|
|
||||||
{/* 项目PR */}
|
|
||||||
<Route path="/:owner/:projectsId/compare"
|
|
||||||
render={
|
|
||||||
(props) => (<ProjectDetail {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
{/*项目*/}
|
{/*项目*/}
|
||||||
<Route
|
<Route
|
||||||
path={"/:owner/:projectId/devops/:opsId/detail"}
|
path={"/projects/:owner/:projectId/devops/:opsId/detail"}
|
||||||
render={
|
render={
|
||||||
(props) => {
|
(props) => {
|
||||||
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
return (<OpsDetail {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
</Route>
|
</Route>
|
||||||
|
{/*项目*/}
|
||||||
<Route
|
<Route
|
||||||
path={"/settings"}
|
path={"/projects"}
|
||||||
render={
|
render={
|
||||||
(props) => {
|
(props) => {
|
||||||
return (<Security {...this.props} {...props} {...this.state} />)
|
return (<Projects {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path="/register"
|
path="/register"
|
||||||
render={
|
render={
|
||||||
|
@ -315,23 +244,6 @@ class App extends Component {
|
||||||
<Route path="/403" component={Shixunauthority} />
|
<Route path="/403" component={Shixunauthority} />
|
||||||
|
|
||||||
<Route path="/500" component={http500} />
|
<Route path="/500" component={http500} />
|
||||||
|
|
||||||
{/*404*/}
|
|
||||||
<Route path="/nopage" component={Shixunnopage} />
|
|
||||||
|
|
||||||
{/* 查询 */}
|
|
||||||
<Route path="/search" component={Search} />
|
|
||||||
|
|
||||||
<Route exact path="/explore"
|
|
||||||
render={
|
|
||||||
(props) => (
|
|
||||||
<ProjectIndex {...this.props} {...props} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
{/* 组织 */}
|
|
||||||
<Route path={"/organize"}
|
<Route path={"/organize"}
|
||||||
render={
|
render={
|
||||||
(props) => {
|
(props) => {
|
||||||
|
@ -339,61 +251,25 @@ class App extends Component {
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
</Route>
|
</Route>
|
||||||
|
{/*404*/}
|
||||||
{/*新建项目等*/}
|
<Route path="/nopage" component={Shixunnopage} />
|
||||||
<Route
|
|
||||||
path={"/projects"}
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<Projects {...this.props} {...props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
{/* 判断为用户/组织,并进入对应页面 */}
|
|
||||||
{
|
|
||||||
pathType === 'User' ?
|
|
||||||
<Route exact path="/:username"
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<InfosIndex {...this.props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/> : pathType === 'Organization' ? <Route path={"/:OIdentifier"}
|
|
||||||
render={
|
|
||||||
(props) => {
|
|
||||||
return (<OrganizeIndex {...props} {...this.props} {...this.state} />)
|
|
||||||
}
|
|
||||||
}>
|
|
||||||
</Route> : pathType === '404' ? <Route component={Shixunnopage} />:
|
|
||||||
<Route exact path="/"
|
|
||||||
render={
|
|
||||||
(props) => (
|
|
||||||
personal && personal.length > 0 ?
|
|
||||||
<InfosIndex {...this.props} {...props} />
|
|
||||||
:
|
|
||||||
<ProjectIndex {...this.props} {...props} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
// <Route path="/" component={Loading} />
|
|
||||||
// <Route path="/" component={Shixunnopage} />
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* 个人主页 */}
|
{/* 个人主页 */}
|
||||||
<Route path="/:username"
|
<Route path="/users/:username"
|
||||||
render={
|
render={
|
||||||
(props) => {
|
(props) => {
|
||||||
return (<InfosIndex {...this.props} {...this.state} />)
|
return (<InfosIndex {...this.props} {...this.state} />)
|
||||||
}
|
}
|
||||||
}></Route>
|
}></Route>
|
||||||
|
<Route exact path="/"
|
||||||
|
render={
|
||||||
|
(props) => (
|
||||||
|
<Projects {...this.props} {...props} {...this.state}></Projects>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Route component={Shixunnopage} />
|
<Route component={Shixunnopage} />
|
||||||
</Switch>
|
</Switch>
|
||||||
{/* </Router> */}
|
</Router>
|
||||||
</MuiThemeProvider>
|
</MuiThemeProvider>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|
|
@ -85,11 +85,8 @@ export function initAxiosInterceptors(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.data.status === 404) {
|
if (response.data.status === 404) {
|
||||||
let responseURL = response.request ? response.request.responseURL:'';
|
|
||||||
if (responseURL.indexOf('/api/users/') === -1 && responseURL.indexOf('/api/organizations/') === -1 ) {
|
|
||||||
locationurl('/nopage');
|
locationurl('/nopage');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (response.data.status === 500) {
|
if (response.data.status === 500) {
|
||||||
locationurl('/500');
|
locationurl('/500');
|
||||||
|
|
|
@ -9,7 +9,20 @@ class Loading extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return ""
|
return (
|
||||||
|
<div className="App" style={{ minHeight: '800px', width: "100%" }}>
|
||||||
|
<style>
|
||||||
|
{
|
||||||
|
`
|
||||||
|
.margintop{
|
||||||
|
margin-top:20%;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<Spin size="large" className={"margintop"} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ class College extends Component {
|
||||||
align: 'center',
|
align: 'center',
|
||||||
className: "edu-txt-center font-14 maxnamewidth105",
|
className: "edu-txt-center font-14 maxnamewidth105",
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<a href={`/${record.login}`} title={record.name} target="_blank" className="task-hide maxnamewidth105" style={{
|
<a href={`/users/${record.login}`} title={record.name} target="_blank" className="task-hide maxnamewidth105" style={{
|
||||||
color:'#007bff',
|
color:'#007bff',
|
||||||
|
|
||||||
}}> {
|
}}> {
|
||||||
|
|
|
@ -218,7 +218,7 @@ a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-blue {
|
.color-blue {
|
||||||
color: #2A61FF;
|
color: #4CACFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-huang {
|
.color-huang {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { number } from "prop-types";
|
|
||||||
|
|
||||||
// 处理整点 半点
|
// 处理整点 半点
|
||||||
// 取传入时间往后的第一个半点
|
// 取传入时间往后的第一个半点
|
||||||
|
@ -98,41 +97,3 @@ export function formatDuring(mss){
|
||||||
}
|
}
|
||||||
return days + "天" + hours + "小时" + minutes + "分";
|
return days + "天" + hours + "小时" + minutes + "分";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
返回:多久以前
|
|
||||||
backDate:以前的某个日期
|
|
||||||
*/
|
|
||||||
export function timeAgo(backDate) {
|
|
||||||
try {
|
|
||||||
moment(backDate);
|
|
||||||
} catch (e) {
|
|
||||||
return '刚刚';
|
|
||||||
}
|
|
||||||
if(typeof backDate ==='number'){
|
|
||||||
backDate=backDate*1000
|
|
||||||
}else{
|
|
||||||
backDate= moment(backDate);
|
|
||||||
}
|
|
||||||
let time = new Date() - backDate;
|
|
||||||
var days = Math.floor(time / (1000 * 60 * 60 * 24));
|
|
||||||
var hours = Math.floor((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
||||||
var minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60));
|
|
||||||
var seconds = Math.floor((time % (1000 * 60 * 60)) / 1000);
|
|
||||||
if (time <= 0) {
|
|
||||||
return "刚刚";
|
|
||||||
}
|
|
||||||
if (days) {
|
|
||||||
return days + "天前";
|
|
||||||
}
|
|
||||||
if (hours) {
|
|
||||||
return hours + "小时前";
|
|
||||||
}
|
|
||||||
if (minutes) {
|
|
||||||
return minutes + "分前";
|
|
||||||
}
|
|
||||||
if (seconds) {
|
|
||||||
return seconds + "秒前";
|
|
||||||
}
|
|
||||||
return "刚刚";
|
|
||||||
}
|
|
|
@ -69,7 +69,7 @@ export function appendFileSizeToUploadFile(item) {
|
||||||
}
|
}
|
||||||
export function appendFileSizeToUploadFileAll(fileList) {
|
export function appendFileSizeToUploadFileAll(fileList) {
|
||||||
return fileList.map(item => {
|
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 Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` })
|
||||||
}
|
}
|
||||||
return item
|
return item
|
||||||
|
|
|
@ -18,23 +18,6 @@ export function getImageUrl(path) {
|
||||||
return `${path}`;
|
return `${path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function numFormat(num, digits){
|
|
||||||
let d = digits || 1;
|
|
||||||
var si = [
|
|
||||||
{ value: 1, symbol: "" },
|
|
||||||
{ value: 1E3, symbol: "k" },
|
|
||||||
{ value: 1E4, symbol: "W" }
|
|
||||||
];
|
|
||||||
var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
|
|
||||||
var i;
|
|
||||||
for (i = si.length - 1; i > 0; i--) {
|
|
||||||
if (num >= si[i].value) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (num / si[i].value).toFixed(d).replace(rx, "$1") + si[i].symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getImage(path) {
|
export function getImage(path) {
|
||||||
// https://www.educoder.net
|
// https://www.educoder.net
|
||||||
// https://testbdweb.trustie.net
|
// https://testbdweb.trustie.net
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil';
|
// export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getUploadLogoActionUrl as getUploadLogoActionUrl,numFormat as numFormat,
|
getUploadLogoActionUrl as getUploadLogoActionUrl,
|
||||||
getImageUrl as getImageUrl,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
|
getImageUrl as getImageUrl,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
|
||||||
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
|
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
|
||||||
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl
|
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl
|
||||||
|
@ -27,7 +27,7 @@ export {
|
||||||
markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
|
markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
|
||||||
downloadFile, sortDirections, validateLength, mdJSONParse, exportMdtoHtml
|
downloadFile, sortDirections, validateLength, mdJSONParse, exportMdtoHtml
|
||||||
} from './TextUtil'
|
} from './TextUtil'
|
||||||
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds ,timeAgo} from './DateUtil'
|
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds } from './DateUtil'
|
||||||
|
|
||||||
export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil'
|
export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil'
|
||||||
|
|
||||||
|
|
|
@ -46,18 +46,18 @@ export default ({
|
||||||
let id = decodeURIComponent(u.split("#")[1]);
|
let id = decodeURIComponent(u.split("#")[1]);
|
||||||
let ele = document.getElementById(id);
|
let ele = document.getElementById(id);
|
||||||
if(ele){
|
if(ele){
|
||||||
window.scrollTo(0, ele.offsetTop + 120);
|
window.scrollTo(0, ele.offsetTop + 220);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},[url,html])
|
},[url])
|
||||||
|
|
||||||
const el = useRef();
|
const el = useRef();
|
||||||
function onAncherHandler(e) {
|
function onAncherHandler(e) {
|
||||||
let target = e.target;
|
let target = e.target
|
||||||
if (target.tagName.toUpperCase() === 'A') {
|
if (target.tagName.toUpperCase() === 'A') {
|
||||||
let ancher = target.getAttribute('href');
|
let ancher = target.getAttribute('href')
|
||||||
if (ancher && ancher.startsWith('#')) {
|
if (ancher.startsWith('#')) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
let viewEl = document.getElementById(ancher.replace('#', ''))
|
let viewEl = document.getElementById(ancher.replace('#', ''))
|
||||||
if (viewEl) {
|
if (viewEl) {
|
||||||
|
|
|
@ -435,11 +435,11 @@ class TPIContextProvider extends Component {
|
||||||
image_url: "avatars/User/1"
|
image_url: "avatars/User/1"
|
||||||
login: "innov"
|
login: "innov"
|
||||||
name: "Coder"
|
name: "Coder"
|
||||||
user_url: "/innov"
|
user_url: "/users/innov"
|
||||||
*/
|
*/
|
||||||
let user = resData.user;
|
let user = resData.user;
|
||||||
user.username = resData.user.name;
|
user.username = resData.user.name;
|
||||||
user.user_url = `/${resData.user.login}`;
|
user.user_url = `/users/${resData.user.login}`;
|
||||||
// user.image_url = resData.image_url;
|
// user.image_url = resData.image_url;
|
||||||
user.is_teacher = resData.is_teacher;
|
user.is_teacher = resData.is_teacher;
|
||||||
resData.user = user;
|
resData.user = user;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React , { Component } from 'react';
|
import React , { Component } from 'react';
|
||||||
import { Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
|
import { Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
|
||||||
import '../css/index.scss';
|
import '../css/index.scss';
|
||||||
import '../Branch/branch.scss';
|
import '../Branch/branch.css';
|
||||||
import './activity.css';
|
import './activity.css';
|
||||||
import NoneData from '../Nodata';
|
import NoneData from '../Nodata';
|
||||||
|
|
||||||
|
@ -10,10 +10,6 @@ import ActivityItem from './ActivityItem';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
const LIMIT = 15;
|
const LIMIT = 15;
|
||||||
const ARRAY = [
|
const ARRAY = [
|
||||||
{
|
|
||||||
id:"",
|
|
||||||
name:'全部'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id:1,
|
id:1,
|
||||||
name:'1天'
|
name:'1天'
|
||||||
|
@ -36,15 +32,10 @@ class Activity extends Component{
|
||||||
constructor(props){
|
constructor(props){
|
||||||
super(props);
|
super(props);
|
||||||
this.state={
|
this.state={
|
||||||
time:undefined,
|
time:'30',
|
||||||
type:undefined,
|
type:undefined,
|
||||||
state:undefined,
|
state:undefined,
|
||||||
page:1,
|
page:1,
|
||||||
pr_count:undefined,
|
|
||||||
new_pr_count:undefined,
|
|
||||||
close_issues_count:undefined,
|
|
||||||
open_issues_count:undefined,
|
|
||||||
pr_all_count:undefined,issues_count:undefined,
|
|
||||||
|
|
||||||
data:undefined,
|
data:undefined,
|
||||||
project_trends:undefined,
|
project_trends:undefined,
|
||||||
|
@ -72,15 +63,8 @@ class Activity extends Component{
|
||||||
this.setState({
|
this.setState({
|
||||||
data:result.data,
|
data:result.data,
|
||||||
project_trends:result.data.project_trends,
|
project_trends:result.data.project_trends,
|
||||||
isSpin:false,
|
isSpin:false
|
||||||
pr_count:result.data.pr_count,
|
|
||||||
new_pr_count:result.data.new_pr_count,
|
|
||||||
close_issues_count:result.data.close_issues_count,
|
|
||||||
open_issues_count:result.data.open_issues_count,
|
|
||||||
pr_all_count:result.data.pr_all_count,
|
|
||||||
issues_count:result.data.issues_count,
|
|
||||||
})
|
})
|
||||||
window.scrollTo(0,0);
|
|
||||||
}
|
}
|
||||||
}).catch(error=>{
|
}).catch(error=>{
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
@ -90,19 +74,19 @@ class Activity extends Component{
|
||||||
// 切换周期
|
// 切换周期
|
||||||
changeTime=(e)=>{
|
changeTime=(e)=>{
|
||||||
this.setState({
|
this.setState({
|
||||||
time:e.key ==="item_0"?undefined:e.key,
|
time:e.key,
|
||||||
isSpin:true
|
isSpin:true
|
||||||
})
|
})
|
||||||
const { type,status,page } = this.state;
|
const { type,status,page } = this.state;
|
||||||
this.getInfo(e.key ==="item_0"?undefined:e.key,type,status,page);
|
this.getInfo(e.key,type,status,page);
|
||||||
}
|
}
|
||||||
//筛选
|
//筛选
|
||||||
changeTrends=(type,status)=>{
|
changeTrends=(type,status)=>{
|
||||||
this.setState({
|
this.setState({
|
||||||
type,status,page:1
|
type,status
|
||||||
})
|
})
|
||||||
const {time}=this.state;
|
const {time,page}=this.state;
|
||||||
this.getInfo(time,type,status,1);
|
this.getInfo(time,type,status,page);
|
||||||
}
|
}
|
||||||
// 分页
|
// 分页
|
||||||
ChangePage=(page)=>{
|
ChangePage=(page)=>{
|
||||||
|
@ -124,14 +108,12 @@ class Activity extends Component{
|
||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
render(){
|
render(){
|
||||||
const { time , data , page , project_trends , isSpin , pr_count , new_pr_count , close_issues_count , open_issues_count , pr_all_count ,issues_count } = this.state;
|
const { time , data , page , project_trends , isSpin } = this.state;
|
||||||
let name = time ? ARRAY.filter(item=>item.id === parseInt(time)) :[{name:"全部"}];
|
|
||||||
|
|
||||||
const first_per = pr_all_count > 0 ? `${parseFloat(pr_count/pr_all_count).toFixed(2)*100}%` :"50%";
|
|
||||||
const second_per =pr_all_count > 0 ? `${parseFloat(new_pr_count/pr_all_count).toFixed(2)*100}%` :"50%";
|
|
||||||
const third_per =issues_count > 0 ?`${parseFloat(close_issues_count/issues_count).toFixed(2)*100}%` :"50%";
|
|
||||||
const fourth_per =issues_count > 0 ?`${parseFloat(open_issues_count/issues_count).toFixed(2)*100}%` :"50%";
|
|
||||||
|
|
||||||
|
let name = time && ARRAY.filter(item=>item.id === parseInt(time)) ;
|
||||||
|
const second_per = (parseInt(data && data.close_issues_count)/parseInt(data && data.issues_count)*100)+'%';
|
||||||
|
const third_per = (parseInt(data && data.close_issues_count)/parseInt(data && data.issues_count)*100)+'%';
|
||||||
|
const fourth_per = (parseInt(data && data.open_issues_count)/parseInt(data && data.issues_count)*100)+'%';
|
||||||
return(
|
return(
|
||||||
<div className="main">
|
<div className="main">
|
||||||
|
|
||||||
|
@ -140,7 +122,7 @@ class Activity extends Component{
|
||||||
<div className="orderInfo">
|
<div className="orderInfo">
|
||||||
<div>
|
<div>
|
||||||
<div className="percentLine prPercent">
|
<div className="percentLine prPercent">
|
||||||
<p className="percent_purple" style={{width:first_per}}></p>
|
<p className="percent_purple" style={{width:'100%'}}></p>
|
||||||
<p className="percent_green resetStyle" style={{width:`${second_per}`}}></p>
|
<p className="percent_green resetStyle" style={{width:`${second_per}`}}></p>
|
||||||
</div>
|
</div>
|
||||||
<span>{data && data.pr_all_count}合并请求</span>
|
<span>{data && data.pr_all_count}合并请求</span>
|
||||||
|
@ -150,25 +132,25 @@ class Activity extends Component{
|
||||||
<p className="percent_red" style={{width:`${third_per}`}}></p>
|
<p className="percent_red" style={{width:`${third_per}`}}></p>
|
||||||
<p className="percent_green" style={{width:`${fourth_per}`}}></p>
|
<p className="percent_green" style={{width:`${fourth_per}`}}></p>
|
||||||
</div>
|
</div>
|
||||||
<span>{data && data.issues_count}易修</span>
|
<span>{data && data.issues_count}任务</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul className="percentBox">
|
<ul className="percentBox">
|
||||||
<li>
|
<li>
|
||||||
<span className="purple">{data && data.pr_count}</span>
|
<span className="purple">{data && data.pr_count}</span>
|
||||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","delay")}>已处理的合并请求</span>
|
<span className="change" onClick={()=>this.changeTrends("PullRequest","close")}>已处理的合并请求</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span className="green">{data && data.new_pr_count}</span>
|
<span className="green">{data && data.new_pr_count}</span>
|
||||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","not_delay")}>未处理的合并请求</span>
|
<span className="change" onClick={()=>this.changeTrends("PullRequest","create")}>未处理的合并请求</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span className="red">{data && data.close_issues_count}</span>
|
<span className="red">{data && data.close_issues_count}</span>
|
||||||
<span className="change" onClick={()=>this.changeTrends("Issue","delay")}>已关闭的易修</span>
|
<span className="change" onClick={()=>this.changeTrends("Issue","close")}>已关闭的任务</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span className="green">{data && data.open_issues_count}</span>
|
<span className="green">{data && data.open_issues_count}</span>
|
||||||
<span className="change" onClick={()=>this.changeTrends("Issue","not_delay")}>未处理的易修</span>
|
<span className="change" onClick={()=>this.changeTrends("Issue","create")}>未处理的任务</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,25 +14,25 @@ class ActivityItem extends Component {
|
||||||
{/* 如果是版本发布 */}
|
{/* 如果是版本发布 */}
|
||||||
{item.trend_type === "VersionRelease" ?
|
{item.trend_type === "VersionRelease" ?
|
||||||
<p className="itemLine">
|
<p className="itemLine">
|
||||||
<Link to={`/${owner}/${projectsId}/releases`} className="color-blue font-16">{item.name}</Link>
|
<Link to={`/projects/${owner}/${projectsId}/version`} className="color-blue font-16">{item.name}</Link>
|
||||||
<span className="activity_type">{item.trend_type}</span>
|
<span className="activity_type">{item.trend_type}</span>
|
||||||
</p >
|
</p >
|
||||||
:
|
:
|
||||||
// 如果是任务
|
// 如果是任务
|
||||||
item.trend_type === "Issue" ?
|
item.trend_type === "Issue" ?
|
||||||
<p className="itemLine">
|
<p className="itemLine">
|
||||||
<Link to={`/${owner}/${projectsId}/issues/${item.trend_id}`} className="color-blue font-16">{item.name}</Link>
|
<Link to={`/projects/${owner}/${projectsId}/issues/${item.trend_id}/detail`} className="color-blue font-16">{item.name}</Link>
|
||||||
<span className="activity_type">{item.trend_type}</span>
|
<span className="activity_type">{item.trend_type}</span>
|
||||||
</p >
|
</p >
|
||||||
:
|
:
|
||||||
// 如果是合并请求
|
// 如果是合并请求
|
||||||
<p className="itemLine">
|
<p className="itemLine">
|
||||||
<Link to={`/${owner}/${projectsId}/pulls/${item.trend_id}`} className="color-blue font-16">{item.name}</Link>
|
<Link to={`/projects/${owner}/${projectsId}/pulls/${item.trend_id}/Messagecount`} className="color-blue font-16">{item.name}</Link>
|
||||||
<span className="activity_type">{item.trend_type}</span>
|
<span className="activity_type">{item.trend_type}</span>
|
||||||
</p >
|
</p >
|
||||||
}
|
}
|
||||||
<p className="itemLine mt10">
|
<p className="itemLine mt10">
|
||||||
<Link to={`/${item && item.user_login}`} className="show-user-link">
|
<Link to={`/users/${item && item.user_login}`} className="show-user-link">
|
||||||
<img alt="" src={getImageUrl(`/${item.user_avatar}`)} className="createImage" />
|
<img alt="" src={getImageUrl(`/${item.user_avatar}`)} className="createImage" />
|
||||||
<span className="mr20">{item.user_name}</span>
|
<span className="mr20">{item.user_name}</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -1,27 +1,39 @@
|
||||||
import React, { useState } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Menu } from 'antd';
|
import { Dropdown, Icon, Tooltip } from 'antd';
|
||||||
import "./branch.scss";
|
import "./branch.css";
|
||||||
import CopyTool from '../Component/CopyTool';
|
|
||||||
|
|
||||||
function CloneAddress({http_url , ssh_url , zip_url , tar_url}) {
|
class CloneAddress extends Component {
|
||||||
const [ key , setKey ] = useState("HTTP");
|
// 点击按钮复制功能
|
||||||
|
jsCopy = () => {
|
||||||
|
var e = document.getElementById("copy_rep_content");
|
||||||
|
e.select();
|
||||||
|
document.execCommand("Copy");
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { http_url, downloadUrl } = this.props;
|
||||||
return (
|
return (
|
||||||
<div className="downMenu">
|
|
||||||
<div style={{borderBottom:"1px solid #eee"}}>
|
|
||||||
<Menu className="urlMenu" selectedKeys={[key]} mode={"horizontal"}>
|
|
||||||
<Menu.Item key="HTTP" onClick={(e)=>{setKey(e.key)}}>HTTP</Menu.Item>
|
|
||||||
<Menu.Item key="SSH" onClick={(e)=>{setKey(e.key)}}>SSH</Menu.Item>
|
|
||||||
</Menu>
|
|
||||||
<div className="gitAddressClone">
|
<div className="gitAddressClone">
|
||||||
<input type="text" id="copy_rep_content" value={key==="HTTP" ? http_url:ssh_url} />
|
{/* <p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p> */}
|
||||||
<CopyTool inputId="copy_rep_content" className="copytool"/>
|
{
|
||||||
</div>
|
http_url && <span>HTTP</span>
|
||||||
</div>
|
}
|
||||||
<Menu className="edu-txt-center">
|
<input type="text" id="copy_rep_content" value={http_url} />
|
||||||
<Menu.Item><a href={zip_url}>下载 ZIP</a></Menu.Item>
|
<Tooltip title="复制链接">
|
||||||
<Menu.Item><a href={tar_url}>下载 TAR.GZ</a></Menu.Item>
|
<span className="color-blue" onClick={() => this.jsCopy()}><i className="iconfont icon-fuzhi"></i></span>
|
||||||
</Menu>
|
</Tooltip>
|
||||||
|
{
|
||||||
|
downloadUrl &&
|
||||||
|
<span>
|
||||||
|
<Dropdown overlay={downloadUrl} trigger={['click']} placement="bottomRight">
|
||||||
|
<a className="ant-dropdown-link">
|
||||||
|
<Icon type="cloud-download" className="font-18 fl color-blue" />
|
||||||
|
</a>
|
||||||
|
</Dropdown>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export default CloneAddress;
|
export default CloneAddress;
|
|
@ -1,65 +1,116 @@
|
||||||
import React , { useState , useEffect , useRef } from 'react';
|
import React , { useState , useEffect } from 'react';
|
||||||
import { Dropdown} from 'antd';
|
import { Popover , Input , Spin } from 'antd';
|
||||||
import './branch.scss';
|
import './branch.css';
|
||||||
import SelectOverlay from './SelectOverlay';
|
import { getBranch , getTag } from '../GetData/getData';
|
||||||
import { findDOMNode } from 'react-dom';
|
|
||||||
|
|
||||||
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true })=>{
|
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true })=>{
|
||||||
const [ showValue , setShowValue ] = useState(branch);
|
const [ showValue , setShowValue ] = useState(branch);
|
||||||
const [ visible , setVisible ] = useState(false);
|
const [ inputValue , setInputValue] = useState(undefined);
|
||||||
|
const [ nav , setNav ] = useState(0);
|
||||||
|
const [ isSpin , setIsSpin ] = useState(true);
|
||||||
|
const [ flag , setFlag ] = useState(false);
|
||||||
|
|
||||||
const refFa = useRef(null);
|
const [ data , setData ] = useState(undefined);
|
||||||
const refBox = useRef(null);
|
const [ datas , setDatas ] = useState(undefined);
|
||||||
|
|
||||||
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(()=>{
|
useEffect(()=>{
|
||||||
setShowValue(branch);
|
setShowValue(branch);
|
||||||
},[branch])
|
},[branch])
|
||||||
|
|
||||||
function ChangeB(params) {
|
useEffect(()=>{
|
||||||
setVisible(false);
|
document.body.addEventListener('click', e => {
|
||||||
changeBranch(params);
|
let name = e.target.className;
|
||||||
|
let turn = name === "ant-input OptionsInput" || name === "navli active"|| name === "navli" || name === "padding10 bor-bottom-greyE";
|
||||||
|
if(turn){
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
setFlag(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(branchList){
|
||||||
|
setData(branchList);
|
||||||
|
setDatas(branchList);
|
||||||
|
setIsSpin(false);
|
||||||
|
}
|
||||||
|
},[branchList])
|
||||||
|
|
||||||
|
|
||||||
|
async function getBranchs(id,owner){
|
||||||
|
let result = await getBranch(id,owner);
|
||||||
|
setData(result);
|
||||||
|
setDatas(result);
|
||||||
|
setIsSpin(false);
|
||||||
|
}
|
||||||
|
async function getTags(id,owner){
|
||||||
|
let result = await getTag(id,owner);
|
||||||
|
setData(result);
|
||||||
|
setDatas(result);
|
||||||
|
setIsSpin(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeInputValue(e){
|
||||||
|
setInputValue(e.target.value);
|
||||||
|
let filter = e.target.value ? data && data.length>0 && data.filter(item=>item.name.indexOf(e.target.value)>-1) : data;
|
||||||
|
setDatas(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeNav(nav){
|
||||||
|
setNav(nav);
|
||||||
|
setIsSpin(true);
|
||||||
|
if(nav === 0){
|
||||||
|
getBranchs(projectsId,owner);
|
||||||
|
}else{
|
||||||
|
getTags(projectsId,owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function chooseitem(value){
|
||||||
|
// setShowValue(value);
|
||||||
|
changeBranch(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const menu = (
|
const menu = (
|
||||||
<div ref={refFa}>
|
<div>
|
||||||
<SelectOverlay
|
<div className="padding10 bor-bottom-greyE">
|
||||||
visible={visible}
|
<Input
|
||||||
changeBranch={ChangeB}
|
placeholder="请输入分支或标签名称搜索"
|
||||||
tagflag={tagflag}
|
autocomplete="off" className="OptionsInput" value={inputValue}
|
||||||
projectsId={projectsId}
|
onChange={changeInputValue} style={{width:"220px"}}
|
||||||
owner={owner}
|
|
||||||
branchList={branchList}
|
|
||||||
/>
|
/>
|
||||||
|
<ul className="navUl">
|
||||||
|
<li className={nav === 0?"navli active":"navli"} onClick={()=>changeNav(0)}><i className="iconfont icon-fenzhi1 font-14 mr3"></i>分支列表</li>
|
||||||
|
{ tagflag && <li className={nav === 1?"navli active":"navli"} onClick={()=>changeNav(1)}><i className="iconfont icon-biaoqian3 font-14 mr3"></i>标签列表</li> }
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<Spin spinning={isSpin}>
|
||||||
|
<ul className="OptionsUl" id="ul-btn">
|
||||||
|
{
|
||||||
|
datas && datas.length>0 ?
|
||||||
|
datas.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<li key={key} onClick={()=>chooseitem(item.name)}><a className="task-hide ulALink">{item.name}</a></li>
|
||||||
|
)
|
||||||
|
}):
|
||||||
|
<p className="listTips">暂无{inputValue}{nav === 0 ?"分支":"标签"}~</p>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</Spin>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
return(
|
return(
|
||||||
<Dropdown placement='bottomLeft' visible={visible} overlay={menu} overlayClassName="branch-tagBox-list" trigger={['click']} >
|
<Popover placement='bottomLeft' visible={flag} content={menu} onClick={()=>setFlag(!flag)} overlayClassName="branch-tagBox-list">
|
||||||
<div className="branch-tagBox" ref={refBox} onClick={()=>setVisible(visible ? false : true)}>
|
<div className="branch-tagBox">
|
||||||
{/* {nav === 0 ?"分支":"标签"} */}
|
{/* {nav === 0 ?"分支":"标签"} */}
|
||||||
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
|
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
|
||||||
<span className="ant-dropdown-link task-hide" style={{fontWeight:"500",minWidth:"45px",maxWidth:"270px"}}>
|
<a className="ant-dropdown-link">
|
||||||
{showValue}
|
{showValue}
|
||||||
</span>
|
</a>
|
||||||
<i className="showtag iconfont icon-sanjiaoxing-down font-15 color-grey-9 mr5 ml5 mt1" />
|
<i className="showtag iconfont icon-xiajiantou font-14 color-grey-9 mr8" />
|
||||||
</div>
|
</div>
|
||||||
</Dropdown>
|
</Popover>
|
||||||
)
|
)
|
||||||
})
|
})
|
|
@ -1,90 +0,0 @@
|
||||||
import React , { useState , useEffect } from 'react';
|
|
||||||
import { Input , Spin , Menu } from 'antd';
|
|
||||||
import { getBranch , getTag } from '../GetData/getData';
|
|
||||||
|
|
||||||
function SelectOverlay({ changeBranch , tagflag , projectsId , owner , visible }) {
|
|
||||||
const [ inputValue , setInputValue] = useState(undefined);
|
|
||||||
const [ nav , setNav ] = useState(0);
|
|
||||||
const [ isSpin , setIsSpin ] = useState(true);
|
|
||||||
|
|
||||||
const [ data , setData ] = useState(undefined);
|
|
||||||
const [ datas , setDatas ] = useState(undefined);
|
|
||||||
const [ keys ,setKeys] = useState("branch");
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
if(visible){
|
|
||||||
setKeys("branch");
|
|
||||||
getBranchs(projectsId,owner);
|
|
||||||
setIsSpin(true);
|
|
||||||
}
|
|
||||||
},[visible])
|
|
||||||
|
|
||||||
async function getBranchs(id,owner){
|
|
||||||
let result = await getBranch(id,owner);
|
|
||||||
setData(result);
|
|
||||||
setDatas(result);
|
|
||||||
setIsSpin(false);
|
|
||||||
}
|
|
||||||
async function getTags(id,owner){
|
|
||||||
let result = await getTag(id,owner);
|
|
||||||
setData(result);
|
|
||||||
setDatas(result);
|
|
||||||
setIsSpin(false);
|
|
||||||
}
|
|
||||||
function chooseitem(value){
|
|
||||||
changeBranch(value);
|
|
||||||
}
|
|
||||||
function changeInputValue(e){
|
|
||||||
setInputValue(e.target.value);
|
|
||||||
let filter = e.target.value ? data && data.length>0 && data.filter(item=>item.name.indexOf(e.target.value)>-1) : data;
|
|
||||||
setDatas(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeNav(e){
|
|
||||||
setKeys(e.key);
|
|
||||||
setIsSpin(true);
|
|
||||||
if(e.key === "branch"){
|
|
||||||
getBranchs(projectsId,owner);
|
|
||||||
setNav(0);
|
|
||||||
}else{
|
|
||||||
getTags(projectsId,owner);
|
|
||||||
setNav(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
|
||||||
<div className="overlayBranch">
|
|
||||||
<div className="padding15" style={{paddingBottom:"0px"}}>
|
|
||||||
<Input
|
|
||||||
prefix={<i className="iconfont icon-sousuo_icon1 font-14"></i>}
|
|
||||||
placeholder={`请输入分支${tagflag ? "或标签" :""}名称搜索`}
|
|
||||||
autocomplete="off" className="OptionsInput"
|
|
||||||
value={inputValue}
|
|
||||||
onChange={changeInputValue}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<Menu mode="horizontal" className="navUl" selectedKeys={[keys]} onClick={changeNav}>
|
|
||||||
<Menu.Item key={"branch"}>分支</Menu.Item>
|
|
||||||
{ tagflag && <Menu.Item key={"tag"}>标签</Menu.Item> }
|
|
||||||
</Menu>
|
|
||||||
<Spin spinning={isSpin}>
|
|
||||||
<ul className="OptionsUl" id="ul-btn">
|
|
||||||
{
|
|
||||||
datas && datas.length>0 &&
|
|
||||||
datas.map((item,key)=>{
|
|
||||||
return(
|
|
||||||
<li key={key} onClick={()=>chooseitem(item.name)}><a className="task-hide ulALink">{item.name}</a></li>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
{
|
|
||||||
datas && datas.length === 0 &&
|
|
||||||
<p className="listTips">暂无{inputValue}{nav === 0 ?"分支":"标签"}~</p>
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</Spin>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default SelectOverlay;
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
.branchDropdown{
|
||||||
|
border:1px solid #eee;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
min-width: 220px;
|
||||||
|
}
|
||||||
|
.branchDropdown .ant-dropdown-trigger{
|
||||||
|
width: 100%;
|
||||||
|
padding:0px 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.branchOptions{
|
||||||
|
width: 220px;
|
||||||
|
box-shadow: 0px 0px 3px 1px rgba(134, 134, 134, 0.4);
|
||||||
|
border-radius: 3px;
|
||||||
|
background: #fff;
|
||||||
|
max-height: 300px;
|
||||||
|
}
|
||||||
|
.OptionsUl{
|
||||||
|
max-height: 220px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.OptionsUl li{
|
||||||
|
height: 35px;
|
||||||
|
line-height: 35px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding:0px 10px;
|
||||||
|
}
|
||||||
|
.OptionsUl li:hover{
|
||||||
|
background-color: #F0F0F0;
|
||||||
|
}
|
||||||
|
.OptionsUl li a{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.OptionsInput{
|
||||||
|
height: 32px;
|
||||||
|
padding-left: 4px;
|
||||||
|
line-height: 32px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.branch-tagBox{
|
||||||
|
border:1px solid #eee;
|
||||||
|
border-radius: 3px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
min-width: 140px;
|
||||||
|
}
|
||||||
|
.branch-tagBox-list .ant-popover-arrow{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.branch-tagBox-list.ant-popover.ant-popover-placement-bottom{
|
||||||
|
padding-top:0px;
|
||||||
|
}
|
||||||
|
.branch-tagBox .ant-dropdown-link{
|
||||||
|
display: block;
|
||||||
|
flex:1;
|
||||||
|
}
|
||||||
|
.branch-tagBox-list .ant-popover-inner-content{
|
||||||
|
padding:0px;
|
||||||
|
}
|
||||||
|
.navUl{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.navUl li{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.navUl li.active{
|
||||||
|
color:#5091FF;
|
||||||
|
}
|
||||||
|
.listTips{
|
||||||
|
padding:20px 0px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
|
@ -1,129 +0,0 @@
|
||||||
.branchDropdown{
|
|
||||||
border:1px solid #eee;
|
|
||||||
border-radius: 4px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
min-width: 220px;
|
|
||||||
}
|
|
||||||
.branchDropdown .ant-dropdown-trigger{
|
|
||||||
width: 100%;
|
|
||||||
padding:0px 15px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.branchOptions{
|
|
||||||
width: 220px;
|
|
||||||
box-shadow: 0px 0px 3px 1px rgba(134, 134, 134, 0.4);
|
|
||||||
border-radius: 3px;
|
|
||||||
background: #fff;
|
|
||||||
max-height: 300px;
|
|
||||||
}
|
|
||||||
.OptionsUl{
|
|
||||||
min-height: 50px;
|
|
||||||
max-height: 220px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.OptionsUl li{
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
cursor: pointer;
|
|
||||||
padding:0px 20px;
|
|
||||||
margin:5px 0px;
|
|
||||||
}
|
|
||||||
.OptionsUl li:hover{
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
.OptionsUl li a{
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.OptionsInput{
|
|
||||||
height: 32px;
|
|
||||||
padding-left: 4px;
|
|
||||||
line-height: 32px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.branch-tagBox{
|
|
||||||
border:1px solid #D0D0D0;
|
|
||||||
border-radius: 3px;
|
|
||||||
height: 32px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
min-width: 104px;
|
|
||||||
}
|
|
||||||
.branch-tagBox:hover{
|
|
||||||
background-color: #F3F4F6;
|
|
||||||
}
|
|
||||||
.branch-tagBox-list{
|
|
||||||
background: #FFFFFF;
|
|
||||||
box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5);
|
|
||||||
border-radius: 4px;
|
|
||||||
.ant-popover-arrow{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
&.ant-popover.ant-popover-placement-bottom{
|
|
||||||
padding-top:0px;
|
|
||||||
}
|
|
||||||
.branch-tagBox .ant-dropdown-link{
|
|
||||||
display: block;
|
|
||||||
flex:1;
|
|
||||||
max-width: 105px;
|
|
||||||
}
|
|
||||||
.ant-popover-inner-content{
|
|
||||||
padding:0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.overlayBranch{
|
|
||||||
width: 325px;
|
|
||||||
.navUl{
|
|
||||||
margin-top: 8px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
li{
|
|
||||||
height: 30px;
|
|
||||||
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 ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.listTips{
|
|
||||||
padding:20px 0px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.urlMenu{
|
|
||||||
line-height: 30px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding:15px 20px 0px 20px;
|
|
||||||
border-bottom: none;
|
|
||||||
li.ant-menu-item{
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
padding:0px 5px;
|
|
||||||
margin-right: 20px!important;
|
|
||||||
&.ant-menu-item-selected,&.ant-menu-item-active{
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
&.ant-menu-item-selected{
|
|
||||||
border-color:#466aff!important;
|
|
||||||
}
|
|
||||||
&.ant-menu-item-active{
|
|
||||||
border-color:transparent ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.copytool{
|
|
||||||
margin:0px 10px;
|
|
||||||
}
|
|
|
@ -55,7 +55,6 @@ function AddGroup({organizeId,getGroupID}){
|
||||||
|
|
||||||
function addCollaborator(){
|
function addCollaborator(){
|
||||||
getGroupID && getGroupID(id);
|
getGroupID && getGroupID(id);
|
||||||
setID(undefined);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
|
|
|
@ -4,7 +4,7 @@ import axios from 'axios';
|
||||||
import { getImageUrl } from 'educoder';
|
import { getImageUrl } from 'educoder';
|
||||||
|
|
||||||
const { Option } = AutoComplete;
|
const { Option } = AutoComplete;
|
||||||
function AddMember({getID,login,showNotification}){
|
function AddMember({getID,login}){
|
||||||
const [ id , setID ] = useState(undefined);
|
const [ id , setID ] = useState(undefined);
|
||||||
const [ source , setSource ] = useState(undefined);
|
const [ source , setSource ] = useState(undefined);
|
||||||
const [ searchKey , setSearchKey ] = useState(undefined);
|
const [ searchKey , setSearchKey ] = useState(undefined);
|
||||||
|
@ -45,7 +45,7 @@ function AddMember({getID,login,showNotification}){
|
||||||
src={getImageUrl(`/${item && item.image_url}`)}
|
src={getImageUrl(`/${item && item.image_url}`)}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
<span className="ml10" style={{ verticalAlign: "middle" }}>
|
<span className="ml10" style={{ "vertical-align": "middle" }}>
|
||||||
{item.username}
|
{item.username}
|
||||||
<span className="color-grey ml10">({item.login})</span>
|
<span className="color-grey ml10">({item.login})</span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -66,12 +66,7 @@ function AddMember({getID,login,showNotification}){
|
||||||
};
|
};
|
||||||
|
|
||||||
function addCollaborator(){
|
function addCollaborator(){
|
||||||
if(source && source.length>0){
|
|
||||||
getID && getID(id);
|
getID && getID(id);
|
||||||
setSearchKey(undefined);
|
|
||||||
}else{
|
|
||||||
showNotification("请选择存在的用户!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
|
|
|
@ -113,14 +113,7 @@ li.ant-menu-item{
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
}
|
}
|
||||||
.laterest{
|
.laterest{
|
||||||
background-color: #EF3131;
|
color: #05690d;
|
||||||
color: #fff;
|
|
||||||
font-size: 12px;
|
|
||||||
margin-left: 10px;
|
|
||||||
padding:0px 5px;
|
|
||||||
border-radius: 2px;
|
|
||||||
height: 18px;
|
|
||||||
line-height: 18px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1800px){
|
@media screen and (max-width: 1800px){
|
||||||
|
@ -162,280 +155,41 @@ li.ant-menu-item{
|
||||||
margin:0px 20px!important;
|
margin:0px 20px!important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.hoverA{
|
|
||||||
display:flex;
|
|
||||||
align-items: center;
|
|
||||||
max-width: 78px;
|
|
||||||
&:hover a{
|
|
||||||
color:#2A61FF !important ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.menuPanels{
|
.menuPanels{
|
||||||
width: 295px;
|
width: 240px;
|
||||||
.leftline{
|
height: 180px;
|
||||||
position: relative;
|
|
||||||
color: #666;
|
|
||||||
height: 16px;
|
|
||||||
margin-left: 14px;
|
|
||||||
font-size: 12px;
|
|
||||||
&::before{
|
|
||||||
position: absolute;
|
|
||||||
left: -7px;
|
|
||||||
top:3px;
|
|
||||||
height: 12px;
|
|
||||||
width: 1px;
|
|
||||||
background-color: #999;
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ant-btn{
|
|
||||||
height: 36px;
|
|
||||||
line-height: 34px;
|
|
||||||
width: 83px;
|
|
||||||
text-align: center;
|
|
||||||
padding:0px ;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 14px;
|
|
||||||
&.currentBtn{
|
|
||||||
cursor: default;
|
|
||||||
color: #333;
|
|
||||||
&:hover{
|
|
||||||
color: #333;
|
|
||||||
border-color: #d0d0d0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ant-btn-default{
|
|
||||||
color: #333;
|
|
||||||
border-color: #d0d0d0;
|
|
||||||
&:hover{
|
|
||||||
background: #F3F4F6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ant-btn{
|
|
||||||
width: 102px;
|
|
||||||
height: 32px;
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
.ant-btn-primary{
|
|
||||||
color: #fff;
|
|
||||||
background-color: #466AFF;
|
|
||||||
border:none;
|
|
||||||
&:hover{
|
|
||||||
background-color: rgba(70,106,255,0.85);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.focusPanelHeadInfo{
|
|
||||||
padding:14px 16px;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
.ant-popover-content,.ant-popover-inner{
|
.ant-popover-content,.ant-popover-inner{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.ant-popover-inner-content{
|
|
||||||
padding:0px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.halfs{
|
.halfs{
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
padding:24px 0px 0px 0px;
|
padding:24px 0px 0px 0px;
|
||||||
border-top: 1px solid #e8e8e8;
|
border-top: 1px solid #e8e8e8;
|
||||||
}
|
.attrPerson{
|
||||||
.aboutSubTitle{
|
padding-bottom: 24px;
|
||||||
display: flex;
|
}
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.menuMaininfos{
|
|
||||||
padding:10px 16px 14px;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
}
|
||||||
.menuinfos{
|
.menuinfos{
|
||||||
padding:10px 20px 16px;
|
padding:15px 0px;
|
||||||
&>a{
|
&>a{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
& >span:first-child{
|
& >span:first-child{
|
||||||
font-size: 16px;
|
font-size: 18px;
|
||||||
font-weight: 500;
|
font-weight: 400;
|
||||||
color: #333;
|
color: #333;
|
||||||
line-height: 22px;
|
|
||||||
}
|
}
|
||||||
& >span:last-child{
|
& >span:last-child{
|
||||||
color: #666;
|
color: #666;
|
||||||
font-weight: 400;
|
}
|
||||||
line-height: 20px;
|
&:last-child{
|
||||||
margin-top: 6px;
|
border-right: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------个人主页:右侧提示区域--------------------------*/
|
|
||||||
.-task-sidebar {
|
|
||||||
position: fixed;
|
|
||||||
width: 40px;
|
|
||||||
right: 0;
|
|
||||||
bottom: 80px;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1920px){
|
|
||||||
.-task-sidebar{
|
|
||||||
right:220px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 1750px){
|
|
||||||
.-task-sidebar{
|
|
||||||
right:160px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 1650px){
|
|
||||||
.-task-sidebar{
|
|
||||||
right:115px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 1550px){
|
|
||||||
.-task-sidebar{
|
|
||||||
right:90px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 1450px){
|
|
||||||
.-task-sidebar{
|
|
||||||
right:45px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: 1200px){
|
|
||||||
.-task-sidebar{
|
|
||||||
right:0px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.-task-sidebar>div {
|
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 40px;
|
|
||||||
color: #999;
|
|
||||||
font-size: 20px;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #FFFFFF;
|
|
||||||
box-shadow: 0px 0px 10px 1px #F1F1F1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.-task-sidebar>div i {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.-task-sidebar>div:hover i {
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
.-task-sidebar>div:hover{
|
|
||||||
background: #1890FF;
|
|
||||||
box-shadow: 0px 0px 10px 2px #B6D0FC;
|
|
||||||
}
|
|
||||||
.helpBox{
|
|
||||||
width: 260px;
|
|
||||||
z-index: 103;
|
|
||||||
&.shareContent{
|
|
||||||
width: 200px;
|
|
||||||
}
|
|
||||||
.ant-popover-inner-content{
|
|
||||||
padding:0px;
|
|
||||||
}
|
|
||||||
p.titlecontent{
|
|
||||||
font-size: 18px;
|
|
||||||
color: #333;
|
|
||||||
line-height: 20px;
|
|
||||||
padding:15px 20px;
|
|
||||||
}
|
|
||||||
.faqUl{
|
|
||||||
padding:0px 20px 10px;
|
|
||||||
max-height: 230px;
|
|
||||||
overflow-y: auto;
|
|
||||||
li{
|
|
||||||
background: #F5F5F5;
|
|
||||||
border-radius: 20px;
|
|
||||||
padding:0px 20px;
|
|
||||||
color: #333;
|
|
||||||
height: 34px;
|
|
||||||
line-height: 34px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
a{
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
&:hover{
|
|
||||||
background-color: #D1E9FF;
|
|
||||||
a{
|
|
||||||
color: #333!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.shareUl{
|
|
||||||
padding:10px 0px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.titlecontent{
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
li > i{
|
|
||||||
font-size: 32px!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.-task-desc {
|
|
||||||
background: #494949;
|
|
||||||
width: 90px;
|
|
||||||
line-height: 36px;
|
|
||||||
text-align: center;
|
|
||||||
position: absolute;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 13px;
|
|
||||||
z-index: 999999;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.-task-desc div {
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
right: -7px;
|
|
||||||
height: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.-task-desc div img {
|
|
||||||
float: left
|
|
||||||
}
|
|
||||||
|
|
||||||
.-task-sidebar .scan_ewm {
|
|
||||||
position: absolute !important;
|
|
||||||
right: 45px !important;
|
|
||||||
bottom: 0px !important;
|
|
||||||
background-color: #494949 !important;
|
|
||||||
-webkit-box-sizing: border-box !important;
|
|
||||||
box-sizing: border-box !important;
|
|
||||||
font-size: 14px !important;
|
|
||||||
line-height: 16px !important;
|
|
||||||
display: none;
|
|
||||||
height: 213px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trangle_right {
|
|
||||||
position: absolute;
|
|
||||||
right: -5px;
|
|
||||||
bottom: 15px;
|
|
||||||
width: 0;
|
|
||||||
height: 0px;
|
|
||||||
border-top: 6px solid transparent;
|
|
||||||
border-left: 5px solid #494949;
|
|
||||||
border-bottom: 6px solid transparent
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { AlignCenter , FlexAJ } from '../Component/layout';
|
import { AlignCenter , FlexAJ } from '../Component/layout';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Popover , Spin , Button } from 'antd';
|
import { Popover , Spin } from 'antd';
|
||||||
import { getImageUrl } from 'educoder';
|
import { getImageUrl } from 'educoder';
|
||||||
import './Component.scss';
|
import './Component.scss';
|
||||||
import { getUser } from '../GetData/getData';
|
import { getUser } from '../GetData/getData';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
function Contributors({contributors,owner,projectsId,currentLogin}){
|
function Contributors({contributors,owner,projectsId}){
|
||||||
const [ menuList ,setMenuList ]= useState([]);
|
const [ menuList ,setMenuList ]= useState([]);
|
||||||
const [ list , setList ]= useState(undefined);
|
const [ list , setList ]= useState(undefined);
|
||||||
const [ total , setTotal ]= useState(0);
|
const [ total , setTotal ]= useState(0);
|
||||||
|
@ -46,60 +46,46 @@ function Contributors({contributors,owner,projectsId,currentLogin}){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderOrganize(list) {
|
|
||||||
let str = "";
|
|
||||||
list.map(i=>{
|
|
||||||
str = str+i.name + "、";
|
|
||||||
})
|
|
||||||
return str && str.substr(0,str.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setMenusFunc(data){
|
function setMenusFunc(data){
|
||||||
if(data){
|
if(data){
|
||||||
let ele = (
|
let ele = (
|
||||||
<Spin spinning={isSpin}>
|
<Spin spinning={isSpin}>
|
||||||
<FlexAJ className="menuMaininfos">
|
<FlexAJ>
|
||||||
<AlignCenter>
|
<AlignCenter>
|
||||||
<Link to={`/${data.login}`}><img src={getImageUrl(`/${data.image_url}`)} alt="" className="radius" width="38px" height="38px"/></Link>
|
<Link to={`/users/${data.login}`}><img src={getImageUrl(`/${data.image_url}`)} alt="" className="radius" width="38px" height="38px"/></Link>
|
||||||
|
<Link to={`/users/${data.login}`} className="ml10">{data.name}</Link>
|
||||||
<div className="ml10">
|
|
||||||
<Link to={`/${data.login}`}>{data.name}</Link>
|
|
||||||
{ data.location && <span className="leftline">{data.location}</span> }
|
|
||||||
{
|
|
||||||
data.organizations && data.organizations.length>0&&
|
|
||||||
<p className="task-hide" style={{maxWidth:"215px"}}>
|
|
||||||
所属组织:{renderOrganize(data.organizations)}
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</AlignCenter>
|
</AlignCenter>
|
||||||
|
{
|
||||||
|
data.is_watch ? <a className="color-grey-9" onClick={()=>FocusFunc(false,data.login)}>取消关注</a>:<a className="color-blue" onClick={()=>FocusFunc(true,data.login)}>关注</a>
|
||||||
|
}
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
<AlignCenter className="menuinfos">
|
<AlignCenter className="menuinfos">
|
||||||
<Link to={`/${data.login}/projects`}>
|
<a href={data.projects_url}>
|
||||||
<span>{data.projects_count}</span>
|
<span>{data.projects_count}</span>
|
||||||
<span>项目数</span>
|
<span>项目数</span>
|
||||||
</Link>
|
</a>
|
||||||
<Link to={`/${data.login}/followers`}>
|
<a href={data.followers_url}>
|
||||||
<span>{data.followers_count}</span>
|
<span>{data.followers_count}</span>
|
||||||
<span>粉丝数</span>
|
<span>粉丝数</span>
|
||||||
</Link>
|
</a>
|
||||||
<Link to={`/${data.login}/following`}>
|
<a href={data.following_url}>
|
||||||
<span>{data.following_count}</span>
|
<span>{data.following_count}</span>
|
||||||
<span>关注数</span>
|
<span>关注数</span>
|
||||||
</Link>
|
</a>
|
||||||
</AlignCenter>
|
</AlignCenter>
|
||||||
<div className={"pb20"} style={{display:"flex",justifyContent:'center'}}>
|
|
||||||
{
|
{
|
||||||
currentLogin && (currentLogin === data.login)
|
data.organizations && data.organizations.length > 0 ?
|
||||||
?
|
<AlignCenter className="font-12 pt4 pb4">
|
||||||
<Button className="currentBtn">当前用户</Button>
|
<span>所属组织:</span>
|
||||||
:
|
<div className="task-hide flex1">
|
||||||
data.is_watch ?
|
{renderArray(data.organizations)}
|
||||||
<Button type={"default"} onClick={()=>FocusFunc(false,data.login)}>已关注</Button>
|
|
||||||
:
|
|
||||||
<Button type={"primary"} onClick={()=>FocusFunc(true,data.login)}>关注TA</Button>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
</AlignCenter>
|
||||||
|
:""
|
||||||
|
}
|
||||||
|
{
|
||||||
|
data.location && <AlignCenter className="font-12 pt4 pb4"><span>所在地址:</span><span className="ml5">{data.location}</span></AlignCenter>
|
||||||
|
}
|
||||||
</Spin>
|
</Spin>
|
||||||
)
|
)
|
||||||
setMenu(ele);
|
setMenu(ele);
|
||||||
|
@ -149,17 +135,17 @@ function Contributors({contributors,owner,projectsId,currentLogin}){
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="halfs">
|
<div className="halfs">
|
||||||
<Link to={`/${owner}/${projectsId}/contribute`} className="font-16 color-ooo hoverA">
|
<FlexAJ>
|
||||||
<span>贡献者</span>
|
<AlignCenter><span className="font-16 color-grey-6">贡献者</span>{ contributors && contributors.total_count > 0 && <span className="infoCount">{contributors.total_count}</span>}</AlignCenter>
|
||||||
{ contributors && contributors.total_count > 0 && <span className="infoCount">{contributors.total_count}</span>}
|
<Link className="font-12 color-grey-9" to={`/projects/${owner}/${projectsId}/contribute`}>全部</Link>
|
||||||
</Link>
|
</FlexAJ>
|
||||||
<div className="attrPerson" onMouseLeave={()=>setVisibleFunc(false)}>
|
<div className="attrPerson" onMouseLeave={()=>setVisibleFunc(false)}>
|
||||||
{
|
{
|
||||||
total > 0 ?
|
total > 0 ?
|
||||||
list.map((item,key)=>{
|
list.map((item,key)=>{
|
||||||
return(
|
return(
|
||||||
<Popover content={menu} visible={item.visible} overlayClassName="menuPanels" placement="top">
|
<Popover content={menu} visible={item.visible} overlayClassName="menuPanels" placement="top">
|
||||||
<Link key={key} to={`/${item.login}`}>
|
<Link key={key} to={`/users/${item.login}`}>
|
||||||
<img src={getImageUrl(`/${item.image_url}`)} alt="" onMouseOver={()=>setVisibleFunc(true,item.login,key)}/>
|
<img src={getImageUrl(`/${item.image_url}`)} alt="" onMouseOver={()=>setVisibleFunc(true,item.login,key)}/>
|
||||||
</Link>
|
</Link>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
import React, { useState, useCallback, memo } from 'react';
|
|
||||||
import { Tooltip } from 'antd';
|
|
||||||
|
|
||||||
CopyTool.defaultProps = {
|
|
||||||
beforeText: '复制链接', //浮动过去显示的文字
|
|
||||||
afterText: '复制成功', //点击后显示的文字
|
|
||||||
className: '', //传给svg的class
|
|
||||||
inputId: 'copyText', //要复制的文本的ID
|
|
||||||
timeOut:true, //复制后将浮动的文字改为beforeText
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function CopyTool({ beforeText, afterText, className , inputId , timeOut }) {
|
|
||||||
const [title, setTitle] = useState(() => {
|
|
||||||
return beforeText;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 复制链接
|
|
||||||
const copyUrl = useCallback(() => {
|
|
||||||
const copyEle = document.querySelector(`#${inputId}`); // 获取要复制的节点
|
|
||||||
if (!copyEle) {
|
|
||||||
console.error("您的CopyTool未设置正确的inputId");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
copyEle.select(); // 执行选中元素
|
|
||||||
if (document.execCommand('copy')) {
|
|
||||||
document.execCommand('copy');
|
|
||||||
}
|
|
||||||
document.getSelection().removeAllRanges();
|
|
||||||
|
|
||||||
setTitle(afterText);
|
|
||||||
if(timeOut){
|
|
||||||
setTimeout(function(){
|
|
||||||
setTitle(beforeText);
|
|
||||||
},1500)
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tooltip
|
|
||||||
placement="top"
|
|
||||||
title={title}
|
|
||||||
onVisibleChange={() => { setTitle(beforeText) }}
|
|
||||||
>
|
|
||||||
<i className={`iconfont icon-fuzhiicon ${className}`} style={{ color: '#466aff' }} onClick={copyUrl}></i>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default memo(CopyTool);
|
|
|
@ -1,33 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { AlignCenter } from '../layout';
|
|
||||||
import { Button } from 'antd';
|
|
||||||
import Modals from '../PublicModal/Index';
|
|
||||||
|
|
||||||
function DeleteBox({
|
|
||||||
visible ,
|
|
||||||
onCancel ,
|
|
||||||
onSuccess ,
|
|
||||||
title ,
|
|
||||||
subTitle,
|
|
||||||
content
|
|
||||||
}) {
|
|
||||||
return(
|
|
||||||
<Modals
|
|
||||||
title={title}
|
|
||||||
btn={
|
|
||||||
<div>
|
|
||||||
<Button size={'large'} onClick={onCancel}>取消</Button>
|
|
||||||
<Button type={"danger"} size={"large"} onClick={onSuccess}>确认删除</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
onCancel={onCancel}
|
|
||||||
visible={visible}
|
|
||||||
>
|
|
||||||
<div className="desc">
|
|
||||||
<AlignCenter className="descMain"><i className="iconfont icon-shanchu_tc_icon mr10"></i>{content}</AlignCenter>
|
|
||||||
<p>{subTitle}</p>
|
|
||||||
</div>
|
|
||||||
</Modals>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default DeleteBox;
|
|
|
@ -4,12 +4,6 @@ import './Component.scss';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
const { TreeNode , DirectoryTree } = Tree;
|
const { TreeNode , DirectoryTree } = Tree;
|
||||||
|
|
||||||
function turnbar(str){
|
|
||||||
if(str && str.length>0 && str.indexOf("/")>-1){
|
|
||||||
return str.replaceAll('/','%2F');
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
function DrawerPanel({visible,onClose,branch,owner,projectsId,history, name , list}){
|
function DrawerPanel({visible,onClose,branch,owner,projectsId,history, name , list}){
|
||||||
const [ treeData , setTreeData ] = useState(undefined);
|
const [ treeData , setTreeData ] = useState(undefined);
|
||||||
const [ isSpin , setIsSpin ] = useState(true);
|
const [ isSpin , setIsSpin ] = useState(true);
|
||||||
|
@ -77,8 +71,7 @@ function DrawerPanel({visible,onClose,branch,owner,projectsId,history, name , li
|
||||||
let dataref = event.node.props.dataRef;
|
let dataref = event.node.props.dataRef;
|
||||||
if(dataref.type==="file"){
|
if(dataref.type==="file"){
|
||||||
onClose();
|
onClose();
|
||||||
let value = turnbar(branch);
|
history.push(`/projects/${owner}/${projectsId}/tree/${branch}/${dataref.path}`);
|
||||||
history.push(`/${owner}/${projectsId}/tree/${value}/${dataref.path}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
.ant-modal-mask{
|
.ant-modal-mask{
|
||||||
z-index: 1031;
|
z-index: 1001;
|
||||||
}
|
}
|
||||||
.ant-modal-wrap{
|
.ant-modal-wrap{
|
||||||
z-index: 1032;
|
z-index: 1002;
|
||||||
|
.ant-form-explain{
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
import React, { useState } from "react";
|
|
||||||
import { Input ,notification} from "antd";
|
|
||||||
|
|
||||||
const { Search } = Input;
|
|
||||||
export default ({history}) => {
|
|
||||||
const [openSearch, setOpenSearch] = useState(false);
|
|
||||||
|
|
||||||
function onGlobalSearch(value) {
|
|
||||||
history.push('/search?value=' + value);
|
|
||||||
// window.location.href = `search?value=` + value;
|
|
||||||
// history.push({
|
|
||||||
// pathname:'/search',
|
|
||||||
// state:value
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
{
|
|
||||||
openSearch ?
|
|
||||||
<div
|
|
||||||
onBlur={() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
setOpenSearch(false)
|
|
||||||
}, 500)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Search placeholder="请输入搜索关键字"
|
|
||||||
className={`search-input mr20`}
|
|
||||||
onSearch={onGlobalSearch}
|
|
||||||
autoFocus={true}
|
|
||||||
style={{width:'260px'}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<i className="iconfont icon-sousuo font-18 color-grey-6 ml30" onClick={() => {
|
|
||||||
setOpenSearch(true)
|
|
||||||
}} />
|
|
||||||
}
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
};
|
|
|
@ -25,7 +25,7 @@ function LanguagePower({languages}){
|
||||||
}
|
}
|
||||||
return(
|
return(
|
||||||
<div>
|
<div>
|
||||||
<p className="font-16 color-ooo aboutSubTitle">开发语言</p>
|
<p className="font-16 color-grey-6">开发语言</p>
|
||||||
<div className="progress">
|
<div className="progress">
|
||||||
{
|
{
|
||||||
array && array.map((item,key)=>{
|
array && array.map((item,key)=>{
|
||||||
|
|
|
@ -45,15 +45,15 @@ const Div = styled.div`{
|
||||||
export default (({ user , img, name, time, focusStatus, is_current_user, login , successFunc }) => {
|
export default (({ user , img, name, time, focusStatus, is_current_user, login , successFunc }) => {
|
||||||
return (
|
return (
|
||||||
<Div>
|
<Div>
|
||||||
<Link to={`/${user && user.login}`}><Img src={getImageUrl(`/${img}`)} /></Link>
|
<Link to={`/users/${user && user.login}`}><Img src={getImageUrl(`/${img}`)} /></Link>
|
||||||
<div className="m-infos">
|
<div className="m-infos">
|
||||||
<Link to={`/${user && user.login}`}><Name>{name}</Name></Link>
|
<Link to={`/users/${user && user.login}`}><Name>{name}</Name></Link>
|
||||||
<Time><I className="iconfont icon-shijian"></I>加入时间:{time}</Time>
|
<Time><I className="iconfont icon-shijian"></I>加入时间:{time}</Time>
|
||||||
{
|
{
|
||||||
is_current_user ?
|
is_current_user ?
|
||||||
<Button type="default">当前用户</Button>
|
<Button type="default">当前用户</Button>
|
||||||
:
|
:
|
||||||
<FocusButton is_watch={focusStatus} id={login} successFunc={successFunc} notReset={true}/>
|
<FocusButton is_watch={focusStatus} id={login} successFunc={successFunc}/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</Div>
|
</Div>
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
/* eslint-disable react/jsx-no-duplicate-props */
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
import * as ReactDOM from 'react-dom';
|
|
||||||
import { Modal, Button } from 'antd';
|
|
||||||
import './index.scss';
|
|
||||||
|
|
||||||
// 函数式调用删除、通知等模态框
|
|
||||||
|
|
||||||
InitModal.defaultProps = {
|
|
||||||
okText: '确认', //确定按钮的文字
|
|
||||||
cancelText: '取消', //取消按钮的文字
|
|
||||||
className: '', //传入的模态框类名
|
|
||||||
inputId: 'copyText', //要复制的文本的ID
|
|
||||||
onCancel:()=>{}, //取消的回调
|
|
||||||
onOk:()=>{}, //确认的回调
|
|
||||||
title:'提示', //模态框名字
|
|
||||||
contentTitle:'', //内容标题
|
|
||||||
content:'', //详细内容
|
|
||||||
afterClose:()=>{}, //关闭模态框以后的回调
|
|
||||||
};
|
|
||||||
|
|
||||||
// 使用函数调用删除组件
|
|
||||||
export default function DelModal(props) {
|
|
||||||
renderModal({ ...props, type: 'delete' })
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用函数调用选择模态框组件
|
|
||||||
export function Confirm(props) {
|
|
||||||
renderModal({ ...props, type: 'confirm' })
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderModal(props) {
|
|
||||||
const { type, afterClose } = props;
|
|
||||||
const div = document.createElement('div');
|
|
||||||
document.body.appendChild(div);
|
|
||||||
|
|
||||||
function destroy() {
|
|
||||||
afterClose && afterClose();
|
|
||||||
const unmountResult = ReactDOM.unmountComponentAtNode(div);
|
|
||||||
if (unmountResult && div.parentNode) {
|
|
||||||
div.parentNode.removeChild(div);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function modalType(type) {
|
|
||||||
if (type === 'delete') {
|
|
||||||
return <InitModal
|
|
||||||
title="删除"
|
|
||||||
contentTitle="确定要删除吗?"
|
|
||||||
okText="确认删除"
|
|
||||||
{...props}
|
|
||||||
|
|
||||||
afterClose={destroy}
|
|
||||||
contentTitle={<React.Fragment>
|
|
||||||
<i className="red-circle iconfont icon-shanchu_tc_icon mr3"></i>
|
|
||||||
{props.contentTitle}
|
|
||||||
</React.Fragment>}
|
|
||||||
/>
|
|
||||||
} else if (type === 'confirm') {
|
|
||||||
return <InitModal title="选择" afterClose={destroy} {...props} />
|
|
||||||
} else {
|
|
||||||
return <InitModal title="选择" afterClose={destroy} {...props} />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function render() {
|
|
||||||
setTimeout(() => {
|
|
||||||
ReactDOM.render(
|
|
||||||
modalType(type),
|
|
||||||
div,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
render();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 选择模态框组件
|
|
||||||
function InitModal({
|
|
||||||
onCancel,
|
|
||||||
onOk,
|
|
||||||
title,
|
|
||||||
contentTitle,
|
|
||||||
content,
|
|
||||||
okText,
|
|
||||||
cancelText,
|
|
||||||
afterClose,
|
|
||||||
className,
|
|
||||||
}) {
|
|
||||||
|
|
||||||
const [visible, setVisible] = useState(true);
|
|
||||||
|
|
||||||
function onCancelModal() {
|
|
||||||
setVisible(false);
|
|
||||||
onCancel && onCancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSuccess() {
|
|
||||||
setVisible(false);
|
|
||||||
onOk && onOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
visible={visible}
|
|
||||||
onCancel={onCancelModal}
|
|
||||||
afterClose={afterClose}
|
|
||||||
title={title}
|
|
||||||
className={`myself-modal ${className}`}
|
|
||||||
centered
|
|
||||||
footer={[
|
|
||||||
<Button type="default" key="back" onClick={onCancelModal}>
|
|
||||||
{cancelText}
|
|
||||||
</Button>,
|
|
||||||
<Button className="foot-submit" key="submit" onClick={onSuccess}>
|
|
||||||
{okText}
|
|
||||||
</Button>,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
{contentTitle && <p className="content-title">{contentTitle}</p>}
|
|
||||||
<p className="content-descibe">{content}</p>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
.myself-modal {
|
|
||||||
.ant-modal-header {
|
|
||||||
padding: 9px 24px;
|
|
||||||
background: #f8f8f8;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
.ant-modal-title {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.ant-modal-close {
|
|
||||||
top: 0px !important;
|
|
||||||
}
|
|
||||||
.ant-modal-close-x {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
.ant-modal-body {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.content-title {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin: 2rem 0 1rem !important;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #333;
|
|
||||||
letter-spacing: 0;
|
|
||||||
line-height: 29px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
.red-circle {
|
|
||||||
align-self: flex-start;
|
|
||||||
color: #ca0002;
|
|
||||||
font-size: 1.5rem !important;
|
|
||||||
}
|
|
||||||
.content-descibe {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
line-height: 33px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
.ant-modal-footer {
|
|
||||||
padding: 2rem 0;
|
|
||||||
text-align: center;
|
|
||||||
border: 0;
|
|
||||||
.ant-btn {
|
|
||||||
width: 6rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.foot-submit {
|
|
||||||
margin-left: 3rem;
|
|
||||||
color: #df0002;
|
|
||||||
&:hover {
|
|
||||||
border-color: #df0002;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ant-btn-default:hover,
|
|
||||||
.ant-btn-default:active,
|
|
||||||
.ant-btn-default:focus {
|
|
||||||
background: #f3f4f6;
|
|
||||||
color: #333;
|
|
||||||
border-color: #d0d0d0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
import React, {useEffect, useRef, useState} from 'react';
|
|
||||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
|
|
||||||
import './Component.scss';
|
|
||||||
|
|
||||||
function Monaco(props) {
|
|
||||||
const {
|
|
||||||
style = { // dom节点样式
|
|
||||||
height: '400px',
|
|
||||||
},
|
|
||||||
value = '', // 代码文本
|
|
||||||
onChange = () => { // 改变的事件
|
|
||||||
},
|
|
||||||
fontSize = 14, // 代码字体大小
|
|
||||||
monacoOptions = {
|
|
||||||
scrollBeyondLastLine: false,
|
|
||||||
lineNumbers: "off",
|
|
||||||
wordWrap: true,
|
|
||||||
overviewRulerBorder: true,
|
|
||||||
lineHeight: 24,
|
|
||||||
readOnly:true
|
|
||||||
}, // monaco 自定义属性
|
|
||||||
language = 'html', // 语言 支持 js ts sql css json html等
|
|
||||||
} = props;
|
|
||||||
const editOrRef = useRef();
|
|
||||||
const ThisEditor = useRef();
|
|
||||||
useEffect(() => {
|
|
||||||
ThisEditor.current = monaco.editor.create(editOrRef.current, {
|
|
||||||
value: value || '',
|
|
||||||
language,
|
|
||||||
theme: "vs-grey",
|
|
||||||
fontSize: fontSize + 'px',
|
|
||||||
minimap: { // 关闭代码缩略图
|
|
||||||
enabled: false,
|
|
||||||
},
|
|
||||||
...monacoOptions,
|
|
||||||
});
|
|
||||||
|
|
||||||
ThisEditor.current.onDidChangeModelContent((e) => {
|
|
||||||
let newValue = ThisEditor.current.getValue();
|
|
||||||
onChange(newValue);
|
|
||||||
});
|
|
||||||
return () => {
|
|
||||||
ThisEditor.current.dispose();
|
|
||||||
ThisEditor.current = undefined; // 清除编辑器对象
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
useEffect(() => {
|
|
||||||
if (ThisEditor.current) {
|
|
||||||
ThisEditor.current.updateOptions({
|
|
||||||
fontSize: fontSize + 'px',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [fontSize]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={style} ref={editOrRef}>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Monaco;
|
|
|
@ -1,90 +0,0 @@
|
||||||
.systemBox{
|
|
||||||
.ant-modal-body{
|
|
||||||
padding:1px 0px 0px 0px;
|
|
||||||
.sysBox{
|
|
||||||
background-image: url('./bg.png');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 100% 334px;
|
|
||||||
margin-top: -55px;
|
|
||||||
}
|
|
||||||
.sysnoticeBox{
|
|
||||||
width: 100%;
|
|
||||||
padding:80px 0px 34px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 780px;
|
|
||||||
margin: 0px auto;
|
|
||||||
p.ntitle{
|
|
||||||
height: 33px;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #31FFF7;
|
|
||||||
line-height: 33px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
p.nSubtitle{
|
|
||||||
height: 25px;
|
|
||||||
line-height: 25px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #FFFFFF;
|
|
||||||
margin-top: 60px;
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
.markdown-body{
|
|
||||||
box-shadow: 0px 0px 17px rgba(0,0,0,0.2);
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-top: 17px!important;
|
|
||||||
}
|
|
||||||
.nContent{
|
|
||||||
padding:20px 34px;
|
|
||||||
background-color: #fff;
|
|
||||||
line-height: 30px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #333;
|
|
||||||
.realmName{
|
|
||||||
margin-top: 20px;
|
|
||||||
display: flex;
|
|
||||||
ul{
|
|
||||||
width: 50%;
|
|
||||||
padding-left: 0px!important;
|
|
||||||
li{
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 32px;
|
|
||||||
text-align: left;
|
|
||||||
color: #000;
|
|
||||||
list-style-type: none!important;
|
|
||||||
&:first-child{
|
|
||||||
color: #E65714;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.nSubdesc{
|
|
||||||
font-size: 15px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #000000;
|
|
||||||
line-height: 31px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.nInfo{
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #333333;
|
|
||||||
text-align: right;
|
|
||||||
margin-top: 25px;
|
|
||||||
p{
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.nBtn{
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 33px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
import React , { useEffect , useState } from 'react';
|
|
||||||
import { Modal , Button } from 'antd';
|
|
||||||
import './Index.scss';
|
|
||||||
import '../../css/index.scss';
|
|
||||||
import RenderHtml from '../../../components/render-html';
|
|
||||||
import cookie from 'react-cookies';
|
|
||||||
|
|
||||||
function SystemNotice({system_notification,history}){
|
|
||||||
const [ visible , setVisible ] = useState(false);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
if(system_notification && !cookie.load('notice_stage')){
|
|
||||||
setVisible(true);
|
|
||||||
}
|
|
||||||
},[system_notification,history.location])
|
|
||||||
|
|
||||||
function sureContinue() {
|
|
||||||
cookie.remove('notice_stage');
|
|
||||||
|
|
||||||
let inFifteenMinutes = new Date(new Date().getTime() + 24 * 3600 * 1000);//一天
|
|
||||||
// let inFifteenMinutes = new Date(new Date().getTime() + 60 * 1000);//一分钟
|
|
||||||
cookie.save('notice_stage', true,{ expires: inFifteenMinutes,path:"/" });
|
|
||||||
|
|
||||||
setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
visible = {visible}
|
|
||||||
width="1000px"
|
|
||||||
footer={false}
|
|
||||||
title={false}
|
|
||||||
centered={true}
|
|
||||||
closable={false}
|
|
||||||
wrapClassName={'systemBox'}
|
|
||||||
>
|
|
||||||
<div className="sysBox">
|
|
||||||
<div className="sysnoticeBox">
|
|
||||||
<p className="ntitle">{system_notification && system_notification.subject}</p>
|
|
||||||
<p className="nSubtitle">{system_notification && system_notification.sub_subject}</p>
|
|
||||||
{/* <div className="nContent">
|
|
||||||
<div className="nMaindesc">
|
|
||||||
为了给用户提供更加稳定、优质的服务,我们即将对平台门户首页、平台名称、平台域名进行一次全面升级与变更。原平台名称:Trustie(中文名:确实)将于2021年10月xx日统一更改为Gitlink(中文名:确实开源)。届时平台域名将统一进行更换,更换规则如下
|
|
||||||
</div>
|
|
||||||
<div className="realmName">
|
|
||||||
<ul>
|
|
||||||
<li>原域名:</li>
|
|
||||||
<li>官网顶级域名https://www.trustie.net</li>
|
|
||||||
<li>版本库子域名https://forgeplus.trustie.net</li>
|
|
||||||
<li>论坛子域名https://forum.trustie.net/forums</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li>更换后域名:</li>
|
|
||||||
<li>官网顶级域名https://www.gitlink.org.cn</li>
|
|
||||||
<li>版本库子域名https://www.git.gitlink.org.cn</li>
|
|
||||||
<li>论坛子域名https://forum.gitlink.org.cn</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div className="nSubdesc">
|
|
||||||
自2021年10月xx日起,旧域名将停止访问。因平台名称与域名变更给您带来的不便,我们深表歉意!非常感谢您一直以来对本平台的信任与支持,我们将一如既往地为您提供优质的服务。 特此通知!
|
|
||||||
</div>
|
|
||||||
<div className="nInfo">
|
|
||||||
<p>Gitlink运营团队</p>
|
|
||||||
<p>2021年10月xx日</p>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
<RenderHtml className="break_word_comments imageLayerParent" value={system_notification && system_notification.content} url={history.location}/>
|
|
||||||
<div className="nBtn">
|
|
||||||
<Button type="primary" className="btnblue" onClick={sureContinue}>确认并继续</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default SystemNotice;
|
|
Binary file not shown.
Before Width: | Height: | Size: 280 KiB |
|
@ -1,72 +0,0 @@
|
||||||
import React , { useEffect , useState } from 'react';
|
|
||||||
import Modals from '../PublicModal/Index';
|
|
||||||
import { Button } from 'antd';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
import ProfileImg from './images/profile.png';
|
|
||||||
import './Index.scss';
|
|
||||||
|
|
||||||
function ProfileModal({visible,onCancel,history}) {
|
|
||||||
const [ modalVis , setModalVis ] = useState(visible);
|
|
||||||
const [ addMemberCheck , setAddMemberCheck ] = useState(false);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
axios.interceptors.response.use((response) => {
|
|
||||||
if (response && (response.data.status === 411 || response.data.status === 412)) {
|
|
||||||
setModalVis(true);
|
|
||||||
if(response.data.status === 412){
|
|
||||||
setAddMemberCheck(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}, (error) => {
|
|
||||||
});
|
|
||||||
},[])
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
setModalVis(visible);
|
|
||||||
},[visible])
|
|
||||||
|
|
||||||
function onOk(){
|
|
||||||
onCancel();
|
|
||||||
setModalVis(false);
|
|
||||||
setTimeout(function(){
|
|
||||||
window.open(`/settings/profile`,"_blank");
|
|
||||||
},200)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onNo() {
|
|
||||||
onCancel();
|
|
||||||
setModalVis(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
|
||||||
<Modals
|
|
||||||
title="完善资料"
|
|
||||||
onCancel={onNo}
|
|
||||||
visible={modalVis}
|
|
||||||
btn={
|
|
||||||
addMemberCheck?
|
|
||||||
<div>
|
|
||||||
<Button type={'primary'} size={"large"} onClick={onNo}>好的</Button>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<div>
|
|
||||||
<Button size={"large"} onClick={onNo}>暂不补充</Button>
|
|
||||||
<Button type={'primary'} size={"large"} onClick={onOk}>好的</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="contents">
|
|
||||||
<img src={ProfileImg} alt=""/>
|
|
||||||
{
|
|
||||||
addMemberCheck ?
|
|
||||||
<p>目标用户个人资料不完整,需提醒目标用户补充资料后以进行后续操作</p>
|
|
||||||
:
|
|
||||||
<p>您目前的个人资料不完整,需要补充资料以进行后续操作。是否前往补充个人信息?</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</Modals>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default ProfileModal;
|
|
|
@ -1,18 +0,0 @@
|
||||||
.contents{
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin:10px auto 0px;
|
|
||||||
img{
|
|
||||||
margin-right: 13px;
|
|
||||||
width: 44px;
|
|
||||||
}
|
|
||||||
p{
|
|
||||||
line-height: 29px;
|
|
||||||
max-width: 327px;
|
|
||||||
font-size: 16px!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.font-44{
|
|
||||||
font-size: 44px!important;
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
function Profile({children,sureFunc,showCompeleteDialog , completeProfile, className}) {
|
|
||||||
|
|
||||||
function checkProfile() {
|
|
||||||
if(!completeProfile){
|
|
||||||
showCompeleteDialog && showCompeleteDialog();
|
|
||||||
}else{
|
|
||||||
sureFunc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
|
||||||
<a className={className} onClick={checkProfile}>{children}</a>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Profile;
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.2 KiB |
|
@ -1,20 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Modal } from 'antd';
|
|
||||||
import './Index.scss';
|
|
||||||
|
|
||||||
function Modals({title,children,btn,onCancel,visible}) {
|
|
||||||
return(
|
|
||||||
<Modal
|
|
||||||
visible={visible}
|
|
||||||
onCancel={onCancel}
|
|
||||||
title={title}
|
|
||||||
width={"520px"}
|
|
||||||
footer={btn}
|
|
||||||
centered={true}
|
|
||||||
wrapClassName={"deleteBox"}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Modals;
|
|
|
@ -1,75 +0,0 @@
|
||||||
.deleteBox{
|
|
||||||
z-index: 1033;
|
|
||||||
.ant-modal-close-x{
|
|
||||||
font-size: 17px!important;
|
|
||||||
}
|
|
||||||
.ant-modal-header{
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
padding:10px 30px;
|
|
||||||
.ant-modal-title{
|
|
||||||
text-align: left;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ant-modal-close{
|
|
||||||
top:0px !important;
|
|
||||||
font-size: 24px !important;
|
|
||||||
}
|
|
||||||
.ant-modal-body{
|
|
||||||
padding:30px 50px;
|
|
||||||
p{
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 26px;
|
|
||||||
color:#666;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
.desc{
|
|
||||||
.descMain{
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
i.red{
|
|
||||||
color:#DF0002;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ant-modal-footer{
|
|
||||||
border-top: none;
|
|
||||||
text-align: center;
|
|
||||||
padding-bottom: 40px;
|
|
||||||
button,a{
|
|
||||||
width: 96px;
|
|
||||||
height: 32px;
|
|
||||||
margin:0px 20px;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 14px;
|
|
||||||
&.ant-btn{
|
|
||||||
border-color: #D0D0D0;
|
|
||||||
color: #666;
|
|
||||||
&:hover,&:active,&:focus{
|
|
||||||
background: #f3f4f6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.ant-btn-danger{
|
|
||||||
background-color: #fff;
|
|
||||||
color: #DF0002;
|
|
||||||
border-color: #D0D0D0;
|
|
||||||
&:hover,&:active,&:focus{
|
|
||||||
border-color: #DF0002;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.ant-btn.ant-btn-primary{
|
|
||||||
background-color: #466AFF;
|
|
||||||
color: #fff;
|
|
||||||
border-color: #466AFF;
|
|
||||||
&:hover,&:focus,&:active{
|
|
||||||
background-color: rgba(70,106,255,0.85);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +1,38 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AlignTop } from '../Component/layout';
|
import { AlignCenter , AlignTop , FlexAJ } from '../Component/layout';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
function Releases({ owner, projectsId, releaseVersions, distribution }) {
|
function Releases({owner,projectsId,releaseVersions}){
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div>
|
<div>
|
||||||
<Link to={`/${owner}/${projectsId}/releases`} className="font-16 color-ooo hoverA">
|
<FlexAJ>
|
||||||
<span>发行版</span>
|
<AlignCenter><span className="font-16 color-grey-6">发行版</span>
|
||||||
{ releaseVersions && releaseVersions.total_count > 0 && <span className="infoCount">{releaseVersions.total_count}</span>}
|
{ releaseVersions && releaseVersions.total_count > 0 && <span className="infoCount">{releaseVersions.total_count}</span>}
|
||||||
</Link>
|
</AlignCenter>
|
||||||
|
{ releaseVersions && releaseVersions.total_count > 0 ?
|
||||||
|
<Link className="font-12 color-grey-9" to={`/projects/${owner}/${projectsId}/releases`}>全部</Link>
|
||||||
|
:
|
||||||
|
<Link className="font-12 color-blue" to={`/projects/${owner}/${projectsId}/releases/new`}>新建</Link>
|
||||||
|
}
|
||||||
|
</FlexAJ>
|
||||||
{
|
{
|
||||||
releaseVersions && releaseVersions.total_count>0 ?
|
releaseVersions && releaseVersions.total_count>0 ?
|
||||||
releaseVersions.list.map((item,key)=>{
|
releaseVersions.list.map((item,key)=>{
|
||||||
return(
|
return(
|
||||||
key === 0 &&<AlignTop className="mt10">
|
key === 0 &&<AlignTop className="mt10">
|
||||||
|
<i className="iconfont icon-biaoqian3 color-grey-6 font-18 mr10"></i>
|
||||||
<div>
|
<div>
|
||||||
<p className="font-16 color-grey-6" style={{display:'flex',alignItems:'center'}}>
|
<p className="font-16 color-grey-6">
|
||||||
{/* 如果是点击最新则发行版列表页只展示最新的一个 */}
|
<Link to={`/projects/${owner}/${projectsId}/releases`}>{item.name}</Link>
|
||||||
<Link to={{pathname:`/${owner}/${projectsId}/releases`,query:{turnFromNew:true}}} style={{maxWidth:'200px',overflow: 'hidden',whiteSpace: 'nowrap',textOverflow:'ellipsis'}}>{item.name}</Link>
|
|
||||||
<span className="font-12 laterest ml5">最新</span>
|
<span className="font-12 laterest ml5">最新</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="color-grey-3 font-12">{item.created_at}</p>
|
<p className="color-grey-9 font-13">{item.created_at}</p>
|
||||||
</div>
|
</div>
|
||||||
</AlignTop>
|
</AlignTop>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
:
|
:""
|
||||||
<div className="mt8">
|
|
||||||
您暂未发布任何版本
|
|
||||||
{distribution && <Link className="color-blue ml20" to={{pathname:`/${owner}/${projectsId}/releases/new`,state:{stable:true}}}>创建新版本</Link>}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { Popover , Tooltip } from 'antd';
|
|
||||||
import './Component.scss';
|
|
||||||
import axios from 'axios';
|
|
||||||
import ShareModal from './SiderBarShareModal';
|
|
||||||
|
|
||||||
const $ = window.$;
|
|
||||||
|
|
||||||
$(window).scroll(function () {
|
|
||||||
if ($(".gotop").length > 0) {
|
|
||||||
if ($(document).scrollTop() > 0) {
|
|
||||||
$(".-task-sidebar .gotop").show();
|
|
||||||
$(".gotop").click(function () {
|
|
||||||
$("html,body").scrollTop(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if ($(document).scrollTop() === 0) {
|
|
||||||
$(".-task-sidebar .gotop").hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function SiderBar() {
|
|
||||||
const [ data , setData ] = useState([]);
|
|
||||||
const [ visible , setVisible ] = useState(false);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
getFAQ();
|
|
||||||
},[])
|
|
||||||
|
|
||||||
function getFAQ(){
|
|
||||||
const url = `/faqs.json`;
|
|
||||||
axios.get(url).then(result=>{
|
|
||||||
if(result && result.data){
|
|
||||||
setData(result.data);
|
|
||||||
}
|
|
||||||
}).catch(error=>{})
|
|
||||||
}
|
|
||||||
function content(list){
|
|
||||||
return <div>
|
|
||||||
<p className="titlecontent">帮助</p>
|
|
||||||
<ul className="faqUl">
|
|
||||||
{
|
|
||||||
list && list.map((i,k)=>{
|
|
||||||
return(
|
|
||||||
<li key={i.question+k}><a href={`${i.url}`} title={i.question} target="_blank">{i.question}</a></li>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
function shareContent(){
|
|
||||||
return <div>
|
|
||||||
<ul className="shareUl">
|
|
||||||
<p className="titlecontent">分享到</p>
|
|
||||||
<li onClick={()=>setVisible(true)}><i className="iconfont icon-weixin2" style={{color:"#62b900"}}></i></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className={"-task-sidebar"} >
|
|
||||||
<ShareModal visible={visible} urlValue={window.location.href} onCancel={()=>setVisible(false)}/>
|
|
||||||
{
|
|
||||||
data && data.length > 0 && (data[0] && data[0].question) ?
|
|
||||||
<Popover content={content(data)} overlayClassName="helpBox" placement={"left"}>
|
|
||||||
<div className="feedback">
|
|
||||||
<i className="iconfont icon-bangzhu font-22"></i>
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
{/* <div className="scan pr" title="微信扫一扫">
|
|
||||||
<span className="inline erweima"><i className="iconfont icon-erweima color-white font-22 fl"></i></span>
|
|
||||||
</div>*/}
|
|
||||||
<Popover content={shareContent()} overlayClassName="helpBox shareContent" placement={"left"}>
|
|
||||||
<div className="consult">
|
|
||||||
<i className="iconfont icon-fenxiang1"></i>
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
<div className="gotop">
|
|
||||||
<Tooltip title="返回顶部" placement={"right"}>
|
|
||||||
<a><i className="iconfont icon-huidaodingbu1"></i></a>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SiderBar;
|
|
|
@ -1,27 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { Modal } from 'antd';
|
|
||||||
import QRCode from 'qrcode.react';
|
|
||||||
|
|
||||||
function SiderBarShareModal({visible,urlValue,onCancel}) {
|
|
||||||
return(
|
|
||||||
<Modal
|
|
||||||
title={"分享到微信"}
|
|
||||||
visible={visible}
|
|
||||||
width="500px"
|
|
||||||
closable={true}
|
|
||||||
footer={false}
|
|
||||||
onCancel={onCancel}
|
|
||||||
>
|
|
||||||
<div style={{textAlign:"center"}}>
|
|
||||||
{urlValue &&<QRCode
|
|
||||||
value={urlValue}
|
|
||||||
size={200}
|
|
||||||
fgColor="#000000"
|
|
||||||
style={{margin:"20px"}}
|
|
||||||
/>}
|
|
||||||
<p>打开微信“扫一扫”,点击右上角菜单,即可将网页分享至朋友圈</p>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default SiderBarShareModal;
|
|
|
@ -2,9 +2,9 @@ import React from 'react';
|
||||||
import {Popover} from 'antd';
|
import {Popover} from 'antd';
|
||||||
import './Component.scss';
|
import './Component.scss';
|
||||||
|
|
||||||
export default (({menu , children, overlayClassName})=>{
|
export default (({menu , children})=>{
|
||||||
return(
|
return(
|
||||||
<Popover content={menu} trigger={['click']} placement='bottom' overlayClassName={overlayClassName}>
|
<Popover content={menu} trigger={['click']} placement='bottom'>
|
||||||
{children}
|
{children}
|
||||||
</Popover>
|
</Popover>
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { Link } from 'react-router-dom';
|
||||||
export default ({ url , name , column , id , login })=>{
|
export default ({ url , name , column , id , login })=>{
|
||||||
const Img = styled.span`
|
const Img = styled.span`
|
||||||
display:flex;
|
display:flex;
|
||||||
font-weight: bold;
|
|
||||||
${column && "flex-direction: column;text-align:center;"}
|
${column && "flex-direction: column;text-align:center;"}
|
||||||
align-items: center;
|
align-items: center;
|
||||||
& img{
|
& img{
|
||||||
|
@ -21,7 +20,7 @@ export default ({ url , name , column , id , login })=>{
|
||||||
`;
|
`;
|
||||||
return(
|
return(
|
||||||
id?
|
id?
|
||||||
<Link to={`/${login}`}>
|
<Link to={`/users/${login}`}>
|
||||||
<Img>
|
<Img>
|
||||||
{ url && <img src={url} alt=""/> }
|
{ url && <img src={url} alt=""/> }
|
||||||
<span>{name}</span>
|
<span>{name}</span>
|
||||||
|
|
|
@ -28,11 +28,6 @@ export const AlignTop = styled.div`{
|
||||||
display:flex;
|
display:flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}`
|
}`
|
||||||
export const AlignAJBottom = styled.div`{
|
|
||||||
display:flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-end;
|
|
||||||
}`
|
|
||||||
// 左右结构
|
// 左右结构
|
||||||
export const Box = styled.div`{
|
export const Box = styled.div`{
|
||||||
display:flex;
|
display:flex;
|
||||||
|
|
|
@ -149,7 +149,7 @@ function About(props, ref) {
|
||||||
axios.post(url).then(result=>{
|
axios.post(url).then(result=>{
|
||||||
setIsSpining(false);
|
setIsSpining(false);
|
||||||
if(result && result.data.status === 0){
|
if(result && result.data.status === 0){
|
||||||
props.history.push(`/${owner}/${projectsId}/devops`);
|
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
|
||||||
// 需要将顶部的open_devops修改
|
// 需要将顶部的open_devops修改
|
||||||
let { changeOpenDevops } = props;
|
let { changeOpenDevops } = props;
|
||||||
changeOpenDevops && changeOpenDevops(true);
|
changeOpenDevops && changeOpenDevops(true);
|
||||||
|
|
|
@ -96,7 +96,7 @@ function Dispose(props){
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
if(result && result.data){
|
if(result && result.data){
|
||||||
props.showNotification("流水线新增成功,请进行工作流配置!");
|
props.showNotification("流水线新增成功,请进行工作流配置!");
|
||||||
props.history.push(`/${owner}/${projectsId}/devops/${result.data.id}`);
|
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose/${result.data.id}`);
|
||||||
}else{
|
}else{
|
||||||
props.showNotification("流水线新增失败,请稍后再试!");
|
props.showNotification("流水线新增失败,请稍后再试!");
|
||||||
}
|
}
|
||||||
|
@ -134,12 +134,12 @@ function Dispose(props){
|
||||||
|
|
||||||
// 模板管理
|
// 模板管理
|
||||||
function toModalManage(){
|
function toModalManage(){
|
||||||
props.history.push(`/${owner}/${projectsId}/devops/mould`);
|
props.history.push(`/projects/${owner}/${projectsId}/devops/mould`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 参数管理
|
// 参数管理
|
||||||
function toparameter(){
|
function toparameter(){
|
||||||
props.history.push(`/${owner}/${projectsId}/devops/params`);
|
props.history.push(`/projects/${owner}/${projectsId}/devops/params`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const operate = current_user && (permission && permission !== "Reporter");
|
const operate = current_user && (permission && permission !== "Reporter");
|
||||||
|
|
|
@ -10,12 +10,6 @@ import { Link } from 'react-router-dom';
|
||||||
// killed:"已撤销",
|
// killed:"已撤销",
|
||||||
// pending:"准备中"
|
// pending:"准备中"
|
||||||
// }
|
// }
|
||||||
function turnbar(str){
|
|
||||||
if(str && str.length>0 && str.indexOf("/")>-1){
|
|
||||||
return str.replaceAll('/','%2F');
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
function renderTableStatus(status) {
|
function renderTableStatus(status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "running":
|
case "running":
|
||||||
|
@ -71,9 +65,8 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
width:"15%",
|
width:"15%",
|
||||||
ellipsis:true,
|
ellipsis:true,
|
||||||
render:(value,item)=>{
|
render:(value,item)=>{
|
||||||
let v = turnbar(item.branch);
|
|
||||||
return(
|
return(
|
||||||
<Link to={`/${owner}/${projectsId}/tree/${v}/${value}`} className="color-blue">{value}</Link>
|
<Link to={`/projects/${owner}/${projectsId}/tree/${item.branch}/${value}`} className="color-blue">{value}</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -117,7 +110,7 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
return(
|
return(
|
||||||
<span>
|
<span>
|
||||||
{ operate ?
|
{ operate ?
|
||||||
<Link to={`/${owner}/${projectsId}/devops/${item.id}`} className="mr10 color-grey-6">
|
<Link to={`/projects/${owner}/${projectsId}/devops/dispose/${item.id}`} className="mr10 color-grey-6">
|
||||||
<i className="iconfont icon-zaibianji font-13 mr3"></i>编辑</Link> :""
|
<i className="iconfont icon-zaibianji font-13 mr3"></i>编辑</Link> :""
|
||||||
}
|
}
|
||||||
{ operate ?
|
{ operate ?
|
||||||
|
@ -125,7 +118,7 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
|
||||||
<a className="mr10 color-grey-6"><i className="iconfont icon-lajitong font-13 mr3"></i>删除</a>
|
<a className="mr10 color-grey-6"><i className="iconfont icon-lajitong font-13 mr3"></i>删除</a>
|
||||||
</Popconfirm>:""
|
</Popconfirm>:""
|
||||||
}
|
}
|
||||||
<Link to={`/${owner}/${projectsId}/devops/list/${item.branch}`} className="color-grey-6"><i className="iconfont icon-yunhang font-13 mr3"></i>查看运行记录</Link>
|
<Link to={`/projects/${owner}/${projectsId}/devops/list/${item.branch}`} className="color-grey-6"><i className="iconfont icon-yunhang font-13 mr3"></i>查看运行记录</Link>
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ function PipelineName({visible,onCancel,onOk,value ,branchList}){
|
||||||
</div>
|
</div>
|
||||||
<div className="choosenList mt20">
|
<div className="choosenList mt20">
|
||||||
<span>触发条件:</span>
|
<span>触发条件:</span>
|
||||||
<Select value={branchValue} style={{width:"150px"}} dropdownClassName="chooseCon" onChange={(e)=>setBranchValue(e)}>
|
<Select value={branchValue} style={{width:"150px"}} onChange={(e)=>setBranchValue(e)}>
|
||||||
{
|
{
|
||||||
branchList && branchList.length>0 && branchList.map((item,key)=>{
|
branchList && branchList.length>0 && branchList.map((item,key)=>{
|
||||||
return(
|
return(
|
||||||
|
@ -51,7 +51,7 @@ function PipelineName({visible,onCancel,onOk,value ,branchList}){
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
<Select mode="multiple" allowClear value={eventValue} dropdownClassName="chooseCon" style={{width:"180px",marginLeft:"10px"}} onChange={(e)=>{setEventValue(e)}}>
|
<Select mode="multiple" allowClear value={eventValue} style={{width:"180px",marginLeft:"10px"}} onChange={(e)=>{console.log(e);setEventValue(e)}}>
|
||||||
{
|
{
|
||||||
EVENT.map((item,key)=>{
|
EVENT.map((item,key)=>{
|
||||||
return(
|
return(
|
||||||
|
|
|
@ -36,37 +36,39 @@ export default ((props)=>{
|
||||||
return(
|
return(
|
||||||
<WhiteBack className="opsPanel">
|
<WhiteBack className="opsPanel">
|
||||||
<Switch {...props}>
|
<Switch {...props}>
|
||||||
|
<Route path="/projects/:owner/:projectsId/devops/dispose/:disposeId"
|
||||||
<Route path="/:owner/:projectsId/devops/params"
|
render={
|
||||||
|
(p) => (<New {...props} {...p}/>)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
|
<Route path="/projects/:owner/:projectsId/devops/params"
|
||||||
render={
|
render={
|
||||||
(p) => (<Params {...props} {...p}/>)
|
(p) => (<Params {...props} {...p}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/devops/mould"
|
<Route path="/projects/:owner/:projectsId/devops/mould"
|
||||||
render={
|
render={
|
||||||
(p) => (<Mould {...props} {...p}/>)
|
(p) => (<Mould {...props} {...p}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/devops/new"
|
<Route path="/projects/:owner/:projectsId/devops/dispose/new"
|
||||||
render={
|
render={
|
||||||
(p) => (<New {...props} {...p}/>)
|
(p) => (<New {...props} {...p}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
<Route path="/projects/:owner/:projectsId/devops/dispose"
|
||||||
<Route path="/:owner/:projectsId/devops/list/:branch"
|
render={
|
||||||
|
(p) => (<Dispose {...props} {...p}/>)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
|
<Route path="/projects/:owner/:projectsId/devops/list/:branch"
|
||||||
render={
|
render={
|
||||||
(p) => (<Stucture {...props} {...p}/>)
|
(p) => (<Stucture {...props} {...p}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/devops/:disposeId"
|
<Route path="/projects/:owner/:projectsId/devops"
|
||||||
render={
|
render={
|
||||||
(p) => (<New {...props} {...p}/>)
|
(p) => (<About {...props} {...p}/>)
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* 原本的两种合为一个 */}
|
|
||||||
<Route path="/:owner/:projectsId/devops"
|
|
||||||
render={
|
|
||||||
(p) =>{return( p.location.state.open_devops?<Dispose {...props} {...p}/>:<About {...props} {...p}/>)}
|
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default ((props)=>{
|
||||||
return(
|
return(
|
||||||
<div className="disposePanel">
|
<div className="disposePanel">
|
||||||
<Banner>
|
<Banner>
|
||||||
{ permission !=="Reporter" && <Link to={`/${owner}/${props.match.params.projectsId}/devops`}>工作流配置</Link>}
|
{ permission !=="Reporter" && <Link to={`/projects/${owner}/${props.match.params.projectsId}/devops/dispose`}>工作流配置</Link>}
|
||||||
</Banner>
|
</Banner>
|
||||||
<Div>
|
<Div>
|
||||||
<Dispost {...props}/>
|
<Dispost {...props}/>
|
||||||
|
|
|
@ -104,7 +104,7 @@ function Params(props){
|
||||||
<Banner>
|
<Banner>
|
||||||
<FlexAJ>
|
<FlexAJ>
|
||||||
<span className="font-18">工作流 - 参数管理</span>
|
<span className="font-18">工作流 - 参数管理</span>
|
||||||
<Link to={`/${owner}/${projectsId}/devops`} className="font-14 color-grey-9 ml20">返回</Link>
|
<Link to={`/projects/${owner}/${projectsId}/devops/dispose`} className="font-14 color-grey-9 ml20">返回</Link>
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
</Banner>
|
</Banner>
|
||||||
<Div className="disposeList">
|
<Div className="disposeList">
|
||||||
|
|
|
@ -126,7 +126,7 @@ function Mould(props){
|
||||||
<div>
|
<div>
|
||||||
<New wrappedComponentRef={(f) => childRef.current = f} ref={childRef} visible={visible} onCancel={()=>setVisible(false)} onOk={onOk}></New>
|
<New wrappedComponentRef={(f) => childRef.current = f} ref={childRef} visible={visible} onCancel={()=>setVisible(false)} onOk={onOk}></New>
|
||||||
<Banner>
|
<Banner>
|
||||||
<FlexAJ><span>工作流 - 模板管理</span><Link to={`/${owner}/${projectsId}/devops`} className="font-14 color-grey-9">返回</Link></FlexAJ>
|
<FlexAJ><span>工作流 - 模板管理</span><Link to={`/projects/${owner}/${projectsId}/devops/dispose`} className="font-14 color-grey-9">返回</Link></FlexAJ>
|
||||||
</Banner>
|
</Banner>
|
||||||
<Div className="disposeList">
|
<Div className="disposeList">
|
||||||
<FlexAJ>
|
<FlexAJ>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, { useState, useEffect , useImperativeHandle ,forwardRef } from "re
|
||||||
import { FlexAJ, AlignCenter , Banner } from "../Component/layout";
|
import { FlexAJ, AlignCenter , Banner } from "../Component/layout";
|
||||||
import { Table, Pagination, Popconfirm } from "antd";
|
import { Table, Pagination, Popconfirm } from "antd";
|
||||||
import { truncateCommitId } from "../common/util";
|
import { truncateCommitId } from "../common/util";
|
||||||
import { getImageUrl } from 'educoder';
|
import {getUrl} from 'educoder';
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ function Structure(props,ref){
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickRows(event,e){
|
function clickRows(event,e){
|
||||||
props.history.push(`/${owner}/${projectsId}/devops/${e.number}/detail`);
|
props.history.push(`/projects/${owner}/${projectsId}/devops/${e.number}/detail`);
|
||||||
}
|
}
|
||||||
const column = [
|
const column = [
|
||||||
{
|
{
|
||||||
|
@ -245,7 +245,7 @@ function Structure(props,ref){
|
||||||
{meg.sha && <span className="color-orange">{meg.sha}</span>}
|
{meg.sha && <span className="color-orange">{meg.sha}</span>}
|
||||||
</div>
|
</div>
|
||||||
<AlignCenter>
|
<AlignCenter>
|
||||||
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} alt="" src={`${item.image_url && getImageUrl(`/${item.image_url}`)}`} />
|
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} alt="" src={`${item.image_url && getUrl(`/images/${item.image_url}`)}`} />
|
||||||
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
|
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
|
||||||
{meg.message}
|
{meg.message}
|
||||||
</div>
|
</div>
|
||||||
|
@ -290,7 +290,7 @@ function Structure(props,ref){
|
||||||
<Banner>
|
<Banner>
|
||||||
<FlexAJ>
|
<FlexAJ>
|
||||||
<span>构建列表</span>
|
<span>构建列表</span>
|
||||||
<Link to={`/${owner}/${projectsId}/devops`} className="font-15 color-grey-9">返回</Link>
|
<Link to={`/projects/${owner}/${projectsId}/devops/dispose`} className="font-15 color-grey-9">返回</Link>
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
</Banner>
|
</Banner>
|
||||||
<Div>
|
<Div>
|
||||||
|
|
|
@ -275,7 +275,7 @@ function disposePipeline(props){
|
||||||
...params
|
...params
|
||||||
}).then(result=>{
|
}).then(result=>{
|
||||||
if(result){
|
if(result){
|
||||||
props.history.push(`/${owner}/${projectsId}/devops`);
|
props.history.push(`/projects/${owner}/${projectsId}/devops/dispose`);
|
||||||
}
|
}
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}).catch(error=>{
|
}).catch(error=>{
|
||||||
|
|
|
@ -391,9 +391,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.chooseCon.ant-select-dropdown{
|
|
||||||
z-index: 100001;
|
|
||||||
}
|
|
||||||
|
|
||||||
.choosenList{
|
.choosenList{
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -48,7 +48,7 @@ export default (props) => {
|
||||||
axios.post(url).then((result) => {
|
axios.post(url).then((result) => {
|
||||||
if (result && result.data) {
|
if (result && result.data) {
|
||||||
props.showNotification("工作流正在重新构建!");
|
props.showNotification("工作流正在重新构建!");
|
||||||
props.history.push(`/${owner}/${projectId}/devops/${result.data.number}/detail`);
|
props.history.push(`/projects/${owner}/${projectId}/devops/${result.data.number}/detail`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
@ -87,7 +87,7 @@ export default (props) => {
|
||||||
</AlignCenter>
|
</AlignCenter>
|
||||||
<Link
|
<Link
|
||||||
style={{ color: "#ddd" }}
|
style={{ color: "#ddd" }}
|
||||||
to={`/${owner}/${projectId}/devops`}
|
to={`/projects/${owner}/${projectId}/devops/dispose`}
|
||||||
>
|
>
|
||||||
<i className="iconfont icon-yiguanbi font-15 mr5"></i>退出
|
<i className="iconfont icon-yiguanbi font-15 mr5"></i>退出
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -24,6 +24,7 @@ function onLayout(term, el) {
|
||||||
entry.target.offsetHeight,
|
entry.target.offsetHeight,
|
||||||
term,
|
term,
|
||||||
);
|
);
|
||||||
|
console.log('cols, rows', cols, rows);
|
||||||
term.resize(cols, rows);
|
term.resize(cols, rows);
|
||||||
mediator.publish('ssh-xterm-resize', {
|
mediator.publish('ssh-xterm-resize', {
|
||||||
columns: cols,
|
columns: cols,
|
||||||
|
@ -138,10 +139,12 @@ export default ({ sshConfigData, sid }) => {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
isFirstConnected.current = true;
|
isFirstConnected.current = true;
|
||||||
|
console.log('event:', event);
|
||||||
|
|
||||||
const data = Base64.decode(event.data.toString());
|
const data = Base64.decode(event.data.toString());
|
||||||
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
|
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
|
||||||
|
|
||||||
|
console.log('data:', data, w, term);
|
||||||
term.write(data);
|
term.write(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,14 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
||||||
// 确认转移
|
// 确认转移
|
||||||
function onOk(){
|
function onOk(){
|
||||||
validateFields((error,values)=>{
|
validateFields((error,values)=>{
|
||||||
|
console.log(...values);
|
||||||
if(!error){
|
if(!error){
|
||||||
const url = `/${owner}/${repo}/applied_transfer_projects.json`;
|
const url = `/${owner}/${repo}/applied_transfer_projects.json`;
|
||||||
Axios.post(url,{
|
Axios.post(url,{
|
||||||
...values
|
...values
|
||||||
}).then(result=>{
|
}).then(result=>{
|
||||||
if(result && result.data.id){
|
if(result){
|
||||||
onSuccess(result.data && result.data.owner);
|
onSuccess(result.data && result.data.owner);
|
||||||
}else{
|
|
||||||
onSuccess();
|
|
||||||
}
|
}
|
||||||
}).catch(error=>{})
|
}).catch(error=>{})
|
||||||
}
|
}
|
||||||
|
@ -105,7 +104,7 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
||||||
</ul>
|
</ul>
|
||||||
:
|
:
|
||||||
<ul className="descUl">
|
<ul className="descUl">
|
||||||
<li>仓库仅可以转移到您具有管理权限的组织中</li>
|
<li>仓库仅可以转移到您已经加入的组织中,不可以转移到未加入的组织中</li>
|
||||||
<li>涉及到仓库改名操作,请提前做好仓库备份并且在转移后对本地仓库的remote进行修改</li>
|
<li>涉及到仓库改名操作,请提前做好仓库备份并且在转移后对本地仓库的remote进行修改</li>
|
||||||
<li>转移仓库到组织后,你和组织创建者/管理员同时拥有对该仓库的管理操作</li>
|
<li>转移仓库到组织后,你和组织创建者/管理员同时拥有对该仓库的管理操作</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -153,21 +152,20 @@ function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
}
|
}
|
||||||
|
|
||||||
<Form.Item label="仓库标识:" style={{marginBottom:"0px"}}>
|
<Form.Item label="仓库名称:">
|
||||||
{getFieldDecorator("identifier",
|
{getFieldDecorator("identifier",
|
||||||
{
|
{
|
||||||
rules:[
|
rules:[
|
||||||
{required:true,message:"请输入仓库标识!"},
|
{required:true,message:"请输入仓库名称"},
|
||||||
{
|
{
|
||||||
validator:checkIdentifier
|
validator:checkIdentifier
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
)(
|
)(
|
||||||
<Input placeholder="请输入仓库标识" autoComplete={"off"}/>
|
<Input placeholder="请输入仓库名称" autoComplete={"off"}/>
|
||||||
)}
|
)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<span className="color-grey-9" style={{marginLeft:"120px"}}>请输入当前项目的标识:<span className="ml5 mr5 color-grey-3">{repo}</span>进行确认!</span>
|
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
import React, { useState , forwardRef, useEffect } from 'react';
|
|
||||||
import { Form , Modal , Input , Radio } from 'antd';
|
|
||||||
import Axios from 'axios';
|
|
||||||
import CheckProfile from '../Component/ProfileModal/Profile';
|
|
||||||
|
|
||||||
export default Form.create()(
|
|
||||||
forwardRef((props)=>{
|
|
||||||
const { getFieldDecorator, validateFields , setFieldsValue } = props && props.form;
|
|
||||||
const [ visible , setVisible ] = useState(false);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
if(!visible){
|
|
||||||
setFieldsValue({
|
|
||||||
code:undefined,
|
|
||||||
role:"developer"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},[visible])
|
|
||||||
|
|
||||||
function onOk() {
|
|
||||||
validateFields((error,values)=>{
|
|
||||||
if(!error){
|
|
||||||
const url = `/applied_projects.json`;
|
|
||||||
Axios.post(url,{
|
|
||||||
applied_project:{
|
|
||||||
...values
|
|
||||||
}
|
|
||||||
}).then(result=>{
|
|
||||||
if(result && result.data){
|
|
||||||
setVisible(false);
|
|
||||||
props.showNotification("申请加入项目成功,等待审核!");
|
|
||||||
}
|
|
||||||
}).catch(error=>{})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
function checkValue(rule, value, callback){
|
|
||||||
if(!value){
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
if(value.length < 6 || value.length > 6){
|
|
||||||
callback("请输入6位数的邀请码");
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(
|
|
||||||
<React.Fragment>
|
|
||||||
<Modal
|
|
||||||
title="加入项目"
|
|
||||||
width="480px"
|
|
||||||
visible={visible}
|
|
||||||
centered={true}
|
|
||||||
onOk={onOk}
|
|
||||||
onCancel={()=>setVisible(false)}
|
|
||||||
>
|
|
||||||
<Form layout={'inline'} className="inviteForm">
|
|
||||||
<Form.Item label="项目邀请码">
|
|
||||||
{getFieldDecorator("code",{
|
|
||||||
rules:[
|
|
||||||
{required:true,message:"请输入6位项目邀请码"},
|
|
||||||
{validator:checkValue}
|
|
||||||
]
|
|
||||||
})(
|
|
||||||
<Input placeholder="请输入6位项目邀请码" autoComplete={"off"} maxLength="6" style={{width:"300px"}}/>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="选择角色">
|
|
||||||
{getFieldDecorator("role",{
|
|
||||||
rules:[{required:true,message:"请选择角色"}]
|
|
||||||
})(
|
|
||||||
<Radio.Group defaultValue={"developer"}>
|
|
||||||
<Radio value="manager">管理员</Radio>
|
|
||||||
<Radio value="developer">开发者</Radio>
|
|
||||||
<Radio value="reporter">报告者</Radio>
|
|
||||||
</Radio.Group>
|
|
||||||
)}
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
</Modal>
|
|
||||||
<CheckProfile {...props} sureFunc={()=>setVisible(true)}>加入项目</CheckProfile>
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
|
@ -1,108 +0,0 @@
|
||||||
import React, { Component } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Icon } from 'antd';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import Nodata from '../Nodata';
|
|
||||||
|
|
||||||
|
|
||||||
class PullRefresh extends Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
}
|
|
||||||
this.pullRef = {};
|
|
||||||
// 节流
|
|
||||||
this.onScrollList = _.throttle(this.handleScroll, 200, {
|
|
||||||
leading: false,
|
|
||||||
trailing: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
let dom = document.querySelector('.pull-refresh-wrap');
|
|
||||||
dom && dom.addEventListener('scroll', this.onScrollList);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
let dom = document.querySelector('.pull-refresh-wrap');
|
|
||||||
dom && dom.removeEventListener('scroll', this.onScrollList)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleScroll = () => {
|
|
||||||
if (this.props.count < this.props.pageSize) return;
|
|
||||||
if (this.props.type === 1 || this.props.type === 2) return;
|
|
||||||
const wrap = this.pullRef;
|
|
||||||
const currentScroll = wrap.scrollTop + wrap.clientHeight
|
|
||||||
|
|
||||||
// 触底
|
|
||||||
if (currentScroll >= (wrap.scrollHeight - 200)) {
|
|
||||||
this.loadData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleLoadClick = () => {
|
|
||||||
this.loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
loadData = () => {
|
|
||||||
this.props.onPullRefresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
renderLoading() {
|
|
||||||
switch (this.props.type) {
|
|
||||||
case 0: // 加载更多
|
|
||||||
return <div className='text-center' onClick={this.handleLoadClick}>显示更多</div>
|
|
||||||
case 1: // 加载中
|
|
||||||
return (
|
|
||||||
<div className='text-center'>
|
|
||||||
<Icon type="loading" />
|
|
||||||
<span className='text-center'>加载中...</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
case 2: // 无样式
|
|
||||||
return <div className='text-center'>没有更多了</div>
|
|
||||||
default:
|
|
||||||
return <div className='text-center'>没有更多了</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { className, count, children } = this.props;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={`pull-refresh-wrap ${className}`}
|
|
||||||
ref={dom => { this.pullRef = dom }}
|
|
||||||
>
|
|
||||||
|
|
||||||
{children}
|
|
||||||
|
|
||||||
{
|
|
||||||
count < 1 && <Nodata _html="暂无未读消息"/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{/* 大于分页数据才显示loading */}
|
|
||||||
{/* {this.props.count >= this.props.pageSize ? this.renderLoading() : null} */}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PullRefresh.propTypes = {
|
|
||||||
className: PropTypes.string,
|
|
||||||
children: PropTypes.any,
|
|
||||||
onPullRefresh: PropTypes.func.isRequired,
|
|
||||||
type: PropTypes.oneOf([0, 1, 2]),
|
|
||||||
count: PropTypes.number.isRequired,
|
|
||||||
pageSize: PropTypes.number.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default PullRefresh
|
|
|
@ -19,7 +19,7 @@ function Footer(){
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div>
|
<div>
|
||||||
<div style={{height:"543px"}}></div>
|
<div style={{height:"483px"}}></div>
|
||||||
<div className="newFooter edu-txt-center">
|
<div className="newFooter edu-txt-center">
|
||||||
{value && showhtml(value)}
|
{value && showhtml(value)}
|
||||||
{/* <div className="footerInfos">
|
{/* <div className="footerInfos">
|
||||||
|
|
|
@ -2,18 +2,15 @@ import React, { Component } from 'react';
|
||||||
import AccountProfile from "../../modules/user/AccountProfile";
|
import AccountProfile from "../../modules/user/AccountProfile";
|
||||||
import { getImageUrl } from 'educoder'
|
import { getImageUrl } from 'educoder'
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Input , notification , Dropdown ,Popover, Menu,Badge, Button } from 'antd';
|
import { Modal, Input, message, notification , Dropdown , Menu } from 'antd';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
import LoginDialog from '../../modules/login/LoginDialog';
|
import LoginDialog from '../../modules/login/LoginDialog';
|
||||||
import HeadSearch from '../Component/HeadSearch';
|
import GotoQQgroup from '../../modal/GotoQQgroup'
|
||||||
|
|
||||||
import AddProjectModal from './AddProjectModal';
|
|
||||||
import '../../modules/tpm/TPMIndex.css';
|
import '../../modules/tpm/TPMIndex.css';
|
||||||
import CheckProfile from '../Component/ProfileModal/Profile';
|
import logo from '../../modules/tpm/images/logo.png';
|
||||||
|
|
||||||
import './header.scss';
|
import './header.scss';
|
||||||
import NoticeContent from './NoticeContent';
|
|
||||||
const $ = window.$
|
const $ = window.$
|
||||||
// TODO 这部分脚本从公共脚本中直接调用
|
// TODO 这部分脚本从公共脚本中直接调用
|
||||||
const { Search } = Input;
|
const { Search } = Input;
|
||||||
|
@ -36,9 +33,11 @@ class NewHeader extends Component {
|
||||||
Checkboxteachertype: false,
|
Checkboxteachertype: false,
|
||||||
Checkboxteachingtype: false,
|
Checkboxteachingtype: false,
|
||||||
code_notice: false,
|
code_notice: false,
|
||||||
|
checked_notice: false,
|
||||||
RadioGroupvalue: undefined,
|
RadioGroupvalue: undefined,
|
||||||
submitapplications: false,
|
submitapplications: false,
|
||||||
isRender: false,
|
isRender: false,
|
||||||
|
showSearchOpentype: false,
|
||||||
showTrial: false,
|
showTrial: false,
|
||||||
setevaluatinghides: false,
|
setevaluatinghides: false,
|
||||||
occupation: 0,
|
occupation: 0,
|
||||||
|
@ -46,12 +45,13 @@ class NewHeader extends Component {
|
||||||
headtypesonClickbool: false,
|
headtypesonClickbool: false,
|
||||||
headtypess: "/",
|
headtypess: "/",
|
||||||
settings: null,
|
settings: null,
|
||||||
|
goshowqqgtounp: false,
|
||||||
visiblemyss: false,
|
visiblemyss: false,
|
||||||
openSearch:false,
|
openSearch:false,
|
||||||
visible:false, //浮动消息框展示控制
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// this.getAppdata();
|
||||||
this.geturlsdata();
|
this.geturlsdata();
|
||||||
window._header_componentHandler = this;
|
window._header_componentHandler = this;
|
||||||
|
|
||||||
|
@ -82,6 +82,36 @@ class NewHeader extends Component {
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SearchInput = (open,item)=>{
|
||||||
|
if(open){
|
||||||
|
return(
|
||||||
|
<div
|
||||||
|
onBlur={() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState({
|
||||||
|
openSearch:false
|
||||||
|
})
|
||||||
|
}, 300)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Search placeholder="实践课程/教学课堂/实践项目/交流问答"
|
||||||
|
className={`search-input mr20`}
|
||||||
|
onSearch={(value)=>this.onGlobalSearch(value,item)}
|
||||||
|
autoFocus={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
return <i className="iconfont icon-sousuo font-18 color-grey-6 ml30" onClick={() => {
|
||||||
|
this.setState({openSearch:true})
|
||||||
|
}} />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onGlobalSearch=(value,item)=>{
|
||||||
|
window.location.href=`${item}?value=` + value;
|
||||||
|
}
|
||||||
|
|
||||||
openNotification = (messge) => {
|
openNotification = (messge) => {
|
||||||
notification.open({
|
notification.open({
|
||||||
message: "提示",
|
message: "提示",
|
||||||
|
@ -90,12 +120,168 @@ class NewHeader extends Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
componentWillReceiveProps(newProps, oldProps) {
|
componentWillReceiveProps(newProps, oldProps) {
|
||||||
this.setState({
|
this.setState({
|
||||||
user: newProps.user
|
user: newProps.user
|
||||||
})
|
})
|
||||||
|
if (newProps.Headertop !== undefined) {
|
||||||
|
old_url = newProps.Headertop.old_url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getCookie = (key) => {
|
||||||
|
var arr, reg = RegExp('(^| )' + key + '=([^;]+)(;|$)');
|
||||||
|
if (arr === document.cookie.match(reg))
|
||||||
|
return decodeURIComponent(arr[2]);
|
||||||
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delCookie = (name) => {
|
||||||
|
var exp = new Date();
|
||||||
|
exp.setTime(exp.getTime() - 1);
|
||||||
|
var cval = this.getCookie(name);
|
||||||
|
if (cval != null) {
|
||||||
|
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onLogout = () => {
|
||||||
|
const url = `/accounts/logout.json`
|
||||||
|
this.delCookie("autologin_trustie")
|
||||||
|
axios.get(url, {
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.data.status === 1) {
|
||||||
|
this.setState({
|
||||||
|
user: undefined
|
||||||
|
})
|
||||||
|
window.location.href = "/login"
|
||||||
|
message.success('退出成功');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
tojoinclass = () => {
|
||||||
|
let { user } = this.state;
|
||||||
|
if (user === undefined) {
|
||||||
|
this.setState({
|
||||||
|
isRender: true
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (user && user.login === "") {
|
||||||
|
this.setState({
|
||||||
|
isRender: true
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (user && user.profile_completed === false) {
|
||||||
|
this.setState({
|
||||||
|
AccountProfiletype: true
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
Addcoursestypes: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
tojoinitem = () => {
|
||||||
|
if (this.props.user && this.props.user.email === undefined || this.props.user && this.props.user.email === null || this.props.user && this.props.user.email === "") {
|
||||||
|
this.openNotification("请先绑定邮箱,谢谢");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let { user } = this.state;
|
||||||
|
if (user === undefined) {
|
||||||
|
this.setState({
|
||||||
|
isRender: true
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (user && user.login === "") {
|
||||||
|
this.setState({
|
||||||
|
isRender: true
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user && user.profile_completed === false) {
|
||||||
|
this.setState({
|
||||||
|
AccountProfiletype: true
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
tojoinitemtype: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
submitstatevalue = (sum, value, data) => {
|
||||||
|
this.setState({
|
||||||
|
Addcoursestypes: false,
|
||||||
|
tojoinitemtype: false,
|
||||||
|
tojoinclasstitle: undefined,
|
||||||
|
rolearr: ["", ""],
|
||||||
|
Checkboxteacherchecked: false,
|
||||||
|
Checkboxstudentchecked: false,
|
||||||
|
Checkboxteachingchecked: false,
|
||||||
|
Checkboxteachertype: false,
|
||||||
|
Checkboxteachingtype: false,
|
||||||
|
code_notice: false,
|
||||||
|
checked_notice: false,
|
||||||
|
submitapplicationssum: sum,
|
||||||
|
submitapplications: true,
|
||||||
|
submitapplicationsvalue: value,
|
||||||
|
submitapplicationsvaluedata: data,
|
||||||
|
RadioGroupvalue: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeRadioGroup = (e) => {
|
||||||
|
this.setState({
|
||||||
|
RadioGroupvalue: e.target.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
submitsubmitapplications = () => {
|
||||||
|
let {
|
||||||
|
submitapplicationssum,
|
||||||
|
submitapplicationsvaluedata
|
||||||
|
} = this.state;
|
||||||
|
this.setState({
|
||||||
|
submitapplications: false,
|
||||||
|
RadioGroupvalue: undefined
|
||||||
|
})
|
||||||
|
if (submitapplicationssum === 0) {
|
||||||
|
if (submitapplicationsvaluedata !== undefined) {
|
||||||
|
window.location.href = "/courses/" + submitapplicationsvaluedata;
|
||||||
|
}
|
||||||
|
} else if (submitapplicationssum === 1) {
|
||||||
|
if (submitapplicationsvaluedata !== undefined) {
|
||||||
|
window.location.href = "/projects/" + submitapplicationsvaluedata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hidesubmitapplications = () => {
|
||||||
|
this.setState({
|
||||||
|
Addcoursestypes: false,
|
||||||
|
tojoinitemtype: false,
|
||||||
|
tojoinclasstitle: undefined,
|
||||||
|
rolearr: ["", ""],
|
||||||
|
Checkboxteacherchecked: false,
|
||||||
|
Checkboxstudentchecked: false,
|
||||||
|
Checkboxteachingchecked: false,
|
||||||
|
Checkboxteachertype: false,
|
||||||
|
Checkboxteachingtype: false,
|
||||||
|
code_notice: false,
|
||||||
|
checked_notice: false,
|
||||||
|
submitapplications: false,
|
||||||
|
RadioGroupvalue: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
educoderlogin = () => {
|
educoderlogin = () => {
|
||||||
//登录账号
|
//登录账号
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -120,6 +306,7 @@ class NewHeader extends Component {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
HideAddcoursestypess = (i) => {
|
HideAddcoursestypess = (i) => {
|
||||||
|
console.log("调用了");
|
||||||
this.setState({
|
this.setState({
|
||||||
Addcoursestypes: false,
|
Addcoursestypes: false,
|
||||||
mydisplay: true,
|
mydisplay: true,
|
||||||
|
@ -132,11 +319,30 @@ class NewHeader extends Component {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
hidetojoinclass = () => {
|
||||||
|
this.setState({
|
||||||
|
tojoinclasstype: false,
|
||||||
|
tojoinitemtype: false,
|
||||||
|
tojoinclasstitle: undefined,
|
||||||
|
rolearr: ["", ""],
|
||||||
|
Checkboxteacherchecked: false,
|
||||||
|
Checkboxstudentchecked: false,
|
||||||
|
Checkboxteachingchecked: false,
|
||||||
|
Checkboxteachertype: false,
|
||||||
|
Checkboxteachingtype: false,
|
||||||
|
code_notice: false,
|
||||||
|
checked_notice: false,
|
||||||
|
RadioGroupvalue: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 关闭
|
// 关闭
|
||||||
cancelModulationModels = () => {
|
cancelModulationModels = () => {
|
||||||
this.setState({ isRenders: false })
|
this.setState({ isRenders: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setevaluatinghides = () => {
|
setevaluatinghides = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
setevaluatinghides: true
|
setevaluatinghides: true
|
||||||
|
@ -196,13 +402,39 @@ class NewHeader extends Component {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAppdata = () => {
|
||||||
|
try {
|
||||||
|
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
|
||||||
|
var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
|
||||||
|
this.setState({
|
||||||
|
settings: chromesettingArray
|
||||||
|
});
|
||||||
|
if (chromesettingArray.tab_logo_url) {
|
||||||
|
this.gettablogourldata(chromesettingresponseArray);
|
||||||
|
} else {
|
||||||
|
this.gettablogourlnull();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.geturlsdata();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
geturlsdata = () => {
|
geturlsdata = () => {
|
||||||
let url = "/setting.json";
|
let url = "/setting.json";
|
||||||
axios.get(url).then((response) => {
|
axios.get(url).then((response) => {
|
||||||
if (response && response.data) {
|
if (response && response.data) {
|
||||||
this.setState({ settings: response.data.setting });
|
this.setState({ settings: response.data.setting });
|
||||||
localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
|
// localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
|
||||||
localStorage.setItem('chromesettingresponse', JSON.stringify(response));
|
// localStorage.setItem('chromesettingresponse', JSON.stringify(response));
|
||||||
|
try {
|
||||||
|
if (response.data.setting.tab_logo_url) {
|
||||||
|
this.gettablogourldata(response);
|
||||||
|
} else {
|
||||||
|
this.gettablogourlnull();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.gettablogourlnull();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.gettablogourlnull();
|
this.gettablogourlnull();
|
||||||
}
|
}
|
||||||
|
@ -222,13 +454,12 @@ class NewHeader extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkProfile=(url)=>{
|
|
||||||
const { showCompeleteDialog , completeProfile } = this.props;
|
// 处理弹框
|
||||||
if(!completeProfile){
|
setgoshowqqgtounp = (bool) => {
|
||||||
showCompeleteDialog && showCompeleteDialog();
|
this.setState({
|
||||||
}else{
|
goshowqqgtounp: bool
|
||||||
window.location.href(url);
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addMenu=(list)=>{
|
addMenu=(list)=>{
|
||||||
|
@ -239,56 +470,34 @@ class NewHeader extends Component {
|
||||||
{
|
{
|
||||||
list.map((item,key)=>{
|
list.map((item,key)=>{
|
||||||
return(
|
return(
|
||||||
(item.name !=="加入课堂" && item.name !=="加入开发项目") &&
|
(item.name !=="加入课堂" && item.name !=="加入开发项目") && <Menu.Item><a href={item.url}>{item.name}</a></Menu.Item>
|
||||||
<Menu.Item key={item.name+key}>
|
|
||||||
<CheckProfile {...this.props} sureFunc={()=>{window.location.href=item.url}}>{item.name}</CheckProfile>
|
|
||||||
</Menu.Item>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
<Menu.Item>
|
|
||||||
<AddProjectModal {...this.props} showNotification={this.props.showNotification}/>
|
|
||||||
</Menu.Item>
|
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMenu=(personal)=>{
|
|
||||||
const { current_user } = this.props;
|
|
||||||
return(
|
|
||||||
<Menu className="currentMenu">
|
|
||||||
<Menu.Item>
|
|
||||||
<span className="currentName" title={current_user && current_user.username}>{current_user && current_user.username}</span>
|
|
||||||
</Menu.Item>
|
|
||||||
{
|
|
||||||
personal && personal.length > 0 && personal.map((item,key)=>{
|
|
||||||
return(
|
|
||||||
<li key={key}><a href={item.url} target="_blank">{item.name}</a></li>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
{/* <li><Link to={`/settings/profile`}>设置</Link></li> */}
|
|
||||||
<Menu.Item><a onClick={() => this.educoderloginysl()}>退出</a></Menu.Item>
|
|
||||||
</Menu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleVisibleChange = visible => {
|
|
||||||
this.setState({ visible });
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { match ,resetUserInfo ,showNotification} = this.props;
|
const { match} = this.props;
|
||||||
let current_user = this.props.user;
|
let current_user = this.props.user;
|
||||||
let {
|
let { Addcoursestypes,
|
||||||
|
tojoinitemtype,
|
||||||
|
tojoinclasstitle,
|
||||||
|
code_notice,
|
||||||
|
checked_notice,
|
||||||
AccountProfiletype,
|
AccountProfiletype,
|
||||||
|
submitapplications,
|
||||||
|
submitapplicationsvalue,
|
||||||
user,
|
user,
|
||||||
isRender,
|
isRender,
|
||||||
|
showSearchOpentype,
|
||||||
headtypesonClickbool,
|
headtypesonClickbool,
|
||||||
headtypess,
|
headtypess,
|
||||||
settings,
|
settings,
|
||||||
visible,
|
goshowqqgtounp,
|
||||||
|
openSearch,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
/*用户名称 用户头像url*/
|
/*用户名称 用户头像url*/
|
||||||
let activeIndex = false;
|
let activeIndex = false;
|
||||||
|
@ -346,7 +555,7 @@ class NewHeader extends Component {
|
||||||
let shixun = "/shixuns";
|
let shixun = "/shixuns";
|
||||||
let paths = "/paths";
|
let paths = "/paths";
|
||||||
let courses = "/courses";
|
let courses = "/courses";
|
||||||
this.props.mygetHelmetapi && this.props.mygetHelmetapi.navbar && this.props.mygetHelmetapi.navbar.map((item, key) => {
|
this.props.mygetHelmetapi.navbar.map((item, key) => {
|
||||||
var reg = RegExp(item.link);
|
var reg = RegExp(item.link);
|
||||||
if (shixun.match(reg)) {
|
if (shixun.match(reg)) {
|
||||||
if (item.hidden === true) {
|
if (item.hidden === true) {
|
||||||
|
@ -367,6 +576,7 @@ class NewHeader extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
let search_url = settings && settings.common && settings.common.search;
|
let search_url = settings && settings.common && settings.common.search;
|
||||||
|
let notice_url = settings && settings.common && settings.common.notice;
|
||||||
return (
|
return (
|
||||||
<div className="newHeaders" id="nHeader">
|
<div className="newHeaders" id="nHeader">
|
||||||
<div className="headerContent">
|
<div className="headerContent">
|
||||||
|
@ -384,13 +594,18 @@ class NewHeader extends Component {
|
||||||
{...this.state}
|
{...this.state}
|
||||||
/> : ""}
|
/> : ""}
|
||||||
{
|
{
|
||||||
settings && settings.nav_logo_url ?
|
goshowqqgtounp === true ?
|
||||||
<a href={settings && settings.new_course.default_url} className={"fl mr50"} style={{minWidth:"45px"}}>
|
<GotoQQgroup {...this.state} {...this.props} setgoshowqqgtounp={(bool) => this.setgoshowqqgtounp(bool)}></GotoQQgroup>
|
||||||
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
|
:""
|
||||||
</a>
|
|
||||||
:
|
|
||||||
""
|
|
||||||
}
|
}
|
||||||
|
<a href={settings && settings.new_course.default_url} className={"fl mr30"} style={{minWidth:"45px"}}>
|
||||||
|
{
|
||||||
|
settings && settings.nav_logo_url ?
|
||||||
|
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
|
||||||
|
:
|
||||||
|
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={logo}></img>
|
||||||
|
}
|
||||||
|
</a>
|
||||||
<div className="head-nav pr" id={"head-navpre1"}>
|
<div className="head-nav pr" id={"head-navpre1"}>
|
||||||
{
|
{
|
||||||
settings && settings.navbar && settings.navbar.length > 0 ?
|
settings && settings.navbar && settings.navbar.length > 0 ?
|
||||||
|
@ -398,21 +613,21 @@ class NewHeader extends Component {
|
||||||
{
|
{
|
||||||
settings.navbar && settings.navbar.map((item, key) => {
|
settings.navbar && settings.navbar.map((item, key) => {
|
||||||
var new_link = item.link;
|
var new_link = item.link;
|
||||||
var user_login = current_user && current_user.login;
|
var user_login = this.props.user && this.props.user.login;
|
||||||
var is_hidden = item.hidden
|
var is_hidden = item.hidden
|
||||||
if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) {
|
if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) {
|
||||||
if (user_login) {
|
if (user_login) {
|
||||||
if (new_link.indexOf("courses") > -1) {
|
if (new_link.indexOf("courses") > -1) {
|
||||||
new_link = new_link.replace(/courses/g, user_login + "/courses")
|
new_link = new_link.replace(/courses/g, "users/" + user_login + "/courses")
|
||||||
} else if (new_link.indexOf("contests") > -1) {
|
} else if (new_link.indexOf("contests") > -1) {
|
||||||
new_link = new_link.replace(/contests/g, user_login + "/contests")
|
new_link = new_link.replace(/contests/g, "users/" + user_login + "/contests")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
is_hidden = true
|
is_hidden = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
|
if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
|
||||||
new_link = new_link.replace(/homes/g, user_login + "/user_activities")
|
new_link = new_link.replace(/homes/g, "users/" + user_login + "/user_activities")
|
||||||
}
|
}
|
||||||
|
|
||||||
var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) );
|
var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) );
|
||||||
|
@ -429,31 +644,51 @@ class NewHeader extends Component {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="head-right">
|
<div className="head-right">
|
||||||
{ search_url && <HeadSearch {...this.props}/>}
|
{search_url ? this.SearchInput(openSearch,search_url):""}
|
||||||
{
|
{
|
||||||
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
||||||
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
||||||
<i className="iconfont icon-tianjiafangda color-grey-6 ml30 mr15"></i>
|
<i className="iconfont icon-tianjiafangda color-grey-6 ml30"></i>
|
||||||
</Dropdown>:""
|
</Dropdown>:""
|
||||||
}
|
}
|
||||||
|
|
||||||
{ (settings && settings.common && settings.common.notice) && (current_user && current_user.login)?
|
{this.props.user && this.props.user.login && notice_url ?
|
||||||
<Popover
|
<div className="ml30 edu-menu-panel">
|
||||||
overlayClassName="notice-popover"
|
{user && user.login &&
|
||||||
placement={`bottomRight`}
|
<a href={`${notice_url}`} style={{ position: 'relative' }}>
|
||||||
content={<NoticeContent visible={visible} current_user={current_user} showNotification={showNotification} resetUserInfo={resetUserInfo}/>}
|
<i className="iconfont icon-xiaoxilingdang color-grey-6"></i>
|
||||||
visible={visible}
|
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
|
||||||
onVisibleChange={this.handleVisibleChange}
|
</span>
|
||||||
destroyTooltipOnHide
|
</a>
|
||||||
>
|
|
||||||
<Link to={"/settings/notice"} className="message-icon">
|
|
||||||
{current_user && <Badge count={current_user.message_unread_total}>
|
|
||||||
<i className="iconfont icon-xiaoxilingdang color-grey-6 ml15 mr15"></i>
|
|
||||||
</Badge>}
|
|
||||||
</Link>
|
|
||||||
</Popover>
|
|
||||||
: ""
|
|
||||||
}
|
}
|
||||||
|
</div>:""
|
||||||
|
}
|
||||||
|
<Modal
|
||||||
|
keyboard={false}
|
||||||
|
title="提示"
|
||||||
|
visible={submitapplications}
|
||||||
|
closable={false}
|
||||||
|
footer={null}
|
||||||
|
>
|
||||||
|
<div className="task_popup_con ml30">
|
||||||
|
<div className="mr15">
|
||||||
|
<ul>
|
||||||
|
<div className="task-popup-content">
|
||||||
|
<p className="task-popup-text-center font-16">
|
||||||
|
{submitapplicationsvalue}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<li className="clearfix mt10 edu-txt-center">
|
||||||
|
<a className="task-btn mr10"
|
||||||
|
onClick={this.hidesubmitapplications}>取消</a>
|
||||||
|
<a
|
||||||
|
className="task-btn task-btn-orange ml20"
|
||||||
|
onClick={this.submitsubmitapplications}>确定</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
{!user || (user && !user.login) ?
|
{!user || (user && !user.login) ?
|
||||||
<span className="font-15 ml30">
|
<span className="font-15 ml30">
|
||||||
|
@ -464,11 +699,25 @@ class NewHeader extends Component {
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
:
|
:
|
||||||
<Dropdown placement={`bottomRight`} overlay={this.renderMenu(settings && settings.personal)}>
|
<div className="ml30 edu-menu-panel" style={{ height: "70px", lineHeight: "70px" }}>
|
||||||
<a href={`/${this.props.current_user && this.props.current_user.login}`}>
|
<a href={`/users/${this.props.current_user === undefined ? "" : this.props.current_user.login}/courses`}>
|
||||||
<img alt="头像" src={getImageUrl(`/${user.image_url}`)} className="currentImg"></img>
|
<img alt="头像" className="radius" height="34" id="nh_user_logo" name="avatar_image" src={getImageUrl(`/${user.image_url}`)} width="34">
|
||||||
|
</img>
|
||||||
</a>
|
</a>
|
||||||
</Dropdown>
|
<ul className="edu-menu-list" style={{ top: '60px', textAlign: 'center' }}>
|
||||||
|
<li className="bor-bottom-greyE" style={{cursor:"default",background:"#fff"}}>{this.props.current_user.username}</li>
|
||||||
|
{
|
||||||
|
settings && settings.personal && settings.personal.length > 0 && settings.personal.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<li key={key}><a href={item.url} target="_blank">{item.name}</a></li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
<li className="bor-top-greyE">
|
||||||
|
<a onClick={() => this.educoderloginysl()}>退出</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,262 +0,0 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { Badge, Menu } from 'antd';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import axios from 'axios';
|
|
||||||
import AppPullRefresh from './AppPullRefresh';
|
|
||||||
import { noticeSourceType } from '../common/static';
|
|
||||||
import './header.scss';
|
|
||||||
import '../SecuritySetting/notice/manager/Index.scss';
|
|
||||||
import '../SecuritySetting/Index.scss';
|
|
||||||
import '../SecuritySetting/notice/myNotice/Index.scss';
|
|
||||||
|
|
||||||
|
|
||||||
function NoticeContent({ visible, showNotification, resetUserInfo, current_user: { login } }) {
|
|
||||||
const [initialize, setInitialize] = useState(true);
|
|
||||||
const [noticeType, setNoticeType] = useState("notification");
|
|
||||||
const [letterUnreadCount, setLetterUnreadCount] = useState(0);//未读私信数量
|
|
||||||
|
|
||||||
const [noticeUnreadCount, setNoticeUnreadCount] = useState(0);//未读系统通知数量
|
|
||||||
const [noticePage, setNoticePage] = useState(0);
|
|
||||||
const [noticeUnreadList, setNoticeUnreadList] = useState([]);//未读系统通知列表
|
|
||||||
|
|
||||||
const [atUnreadCount, setAtUnreadCount] = useState();//未读@我数量
|
|
||||||
const [atPage, setAtPage] = useState(0);
|
|
||||||
const [atUnreadList, setAtUnreadList] = useState([]);//未读@我列表
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
resetUserInfo();
|
|
||||||
}, [noticeUnreadCount,atUnreadCount]);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
setNoticePage(0);
|
|
||||||
setAtPage(0);
|
|
||||||
},[visible])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const params = {
|
|
||||||
type: noticeType,
|
|
||||||
limit: 10,
|
|
||||||
page: noticeType === "notification" ? noticePage : noticeType === "atme" ? atPage : "",
|
|
||||||
status: 1,
|
|
||||||
}
|
|
||||||
getMessageList(params);
|
|
||||||
}, [noticePage, atPage]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const params = {
|
|
||||||
type: noticeType,
|
|
||||||
limit: 10,
|
|
||||||
page: 0,
|
|
||||||
status: 1,
|
|
||||||
};
|
|
||||||
if (initialize) {
|
|
||||||
params.type = "atme"
|
|
||||||
}
|
|
||||||
visible && getMessageList(params);
|
|
||||||
}, [visible]);
|
|
||||||
|
|
||||||
|
|
||||||
function getMessageList(params) {
|
|
||||||
axios.get(`/users/${login}/messages.json`, {
|
|
||||||
params: params,
|
|
||||||
}).then((response) => {
|
|
||||||
if (response && response.data) {
|
|
||||||
setNoticeUnreadCount(response.data.unread_notification);
|
|
||||||
setAtUnreadCount(response.data.unread_atme);
|
|
||||||
if (params.type === "notification") {
|
|
||||||
let list = response.data.messages;
|
|
||||||
if (params.page !== 0) {
|
|
||||||
list = [...noticeUnreadList, ...list];
|
|
||||||
}
|
|
||||||
setNoticeUnreadList(list);
|
|
||||||
if (initialize) {
|
|
||||||
// 如果是第一次加载,根据数据量判断是否切换tab栏
|
|
||||||
setInitialize(false);
|
|
||||||
if (response.data.unread_notification === 0 && response.data.unread_atme !== 0) {
|
|
||||||
setNoticeType("atme");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (params.type === "atme") {
|
|
||||||
let list = response.data.messages;
|
|
||||||
if (params.page !== 0) {
|
|
||||||
list = [...atUnreadList, ...list];
|
|
||||||
}
|
|
||||||
setAtUnreadList(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function readAll() {
|
|
||||||
axios.post(`/users/${login}/messages/read.json`, {
|
|
||||||
type: noticeType,
|
|
||||||
ids: [-1]
|
|
||||||
}).then((response) => {
|
|
||||||
let data = response.data;
|
|
||||||
if (!data) return;
|
|
||||||
if (data.status === 0) {
|
|
||||||
changeReadMarkAll(noticeType);
|
|
||||||
} else {
|
|
||||||
showNotification(data.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function changeReadMarkAll(noticeType) {
|
|
||||||
if (noticeType === "notification") {
|
|
||||||
let list = noticeUnreadList.slice();
|
|
||||||
list.forEach(item => {
|
|
||||||
item.status = 2;
|
|
||||||
})
|
|
||||||
setNoticeUnreadList(list);
|
|
||||||
setNoticeUnreadCount(0);
|
|
||||||
} else if (noticeType === "atme") {
|
|
||||||
let list = atUnreadList.slice();
|
|
||||||
list.forEach(item => {
|
|
||||||
item.status = 2;
|
|
||||||
})
|
|
||||||
setAtUnreadList(list);
|
|
||||||
setAtUnreadCount(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// const [letter_unread_list, setLetter_unread_list] = useState([
|
|
||||||
// {
|
|
||||||
// id: 122,
|
|
||||||
// read: 0, //是否已读,0未读,1已读
|
|
||||||
// send_name: "蒋宇航", //消息发送人
|
|
||||||
// send_login: "jiangYuHang", //消息发送人的login,前端根据这个跳转到消息内页
|
|
||||||
// content: "私信内容", //最近一条未读消息的内容
|
|
||||||
// create_time: "2019-03-04 18:08", //发送时间
|
|
||||||
// },
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
function readItem(item) {
|
|
||||||
axios.post(`/users/${login}/messages/read.json`, {
|
|
||||||
type: noticeType,
|
|
||||||
ids: [item.id]
|
|
||||||
}).then((response) => {
|
|
||||||
let data = response.data;
|
|
||||||
if (!data) return;
|
|
||||||
if (data.status === 0) {
|
|
||||||
changeReadMark(item);
|
|
||||||
item.notification_url && window.open(item.notification_url);
|
|
||||||
} else {
|
|
||||||
showNotification(data.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function changeReadMark(item) {
|
|
||||||
if (item.type === "notification") {
|
|
||||||
let list = noticeUnreadList.slice();
|
|
||||||
let index = noticeUnreadList.indexOf(item);
|
|
||||||
list[index].status = 2;
|
|
||||||
setNoticeUnreadList(list);
|
|
||||||
if (noticeUnreadCount > 0) {
|
|
||||||
setNoticeUnreadCount(noticeUnreadCount - 1);
|
|
||||||
}
|
|
||||||
} else if (item.type === "atme") {
|
|
||||||
let list = atUnreadList.slice();
|
|
||||||
let index = atUnreadList.indexOf(item);
|
|
||||||
list[index].status = 2;
|
|
||||||
setAtUnreadList(list);
|
|
||||||
if (atUnreadCount > 0) {
|
|
||||||
setAtUnreadCount(atUnreadCount - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="messageHoverDiv notice01">
|
|
||||||
<div className="sshHead hoverNotice-head">
|
|
||||||
<Menu mode="horizontal" selectedKeys={noticeType} onClick={(e) => setNoticeType(e.key)}>
|
|
||||||
<Menu.Item key="notification"><Badge count={noticeUnreadCount}>系统通知</Badge></Menu.Item>
|
|
||||||
{/* <Menu.Item key="1" id="item-private"><Badge count={letterUnreadCount}>私信</Badge></Menu.Item> */}
|
|
||||||
<Menu.Item key="atme"><Badge count={atUnreadCount}>@我</Badge></Menu.Item>
|
|
||||||
</Menu>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 系统通知 */}
|
|
||||||
{noticeType === "notification" && <AppPullRefresh
|
|
||||||
className='hoverNotice-body' // 外部添加className加以区分
|
|
||||||
onPullRefresh={() => { setNoticePage(noticePage + 1); }} //触发加载ajax的function
|
|
||||||
// type={2} // 传送加载组件的状态
|
|
||||||
count={noticeUnreadList.length} // 数据当前的总数量
|
|
||||||
pageSize={10} //
|
|
||||||
>
|
|
||||||
{
|
|
||||||
noticeUnreadList.map(item => {
|
|
||||||
return (
|
|
||||||
<div key={item.id + Math.random()} className="noticeCont-back" onClick={() => { readItem(item) }}>
|
|
||||||
<div className={`noticeCont ${item.notification_url?'pointer':''}`}>
|
|
||||||
<span style={{ visibility: item.status === 1 ? 'visible' : 'hidden' }}>
|
|
||||||
<Badge color="#FA2020" />
|
|
||||||
</span>
|
|
||||||
<i className={"iconfont " + noticeSourceType[item.source]}></i>
|
|
||||||
<div className="noticeCont-text">
|
|
||||||
<span className="content-span notice-cont-span" dangerouslySetInnerHTML={{ __html: item.content }}></span>
|
|
||||||
<span className="timeSpan">{item.time_ago}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</AppPullRefresh>
|
|
||||||
}
|
|
||||||
|
|
||||||
{/* @我 */}
|
|
||||||
{noticeType === "atme" && <AppPullRefresh
|
|
||||||
className='hoverNotice-body' // 外部添加className加以区分
|
|
||||||
onPullRefresh={() => { setAtPage(atPage + 1); }} //触发加载ajax的function
|
|
||||||
// type={1} // 传送加载组件的状态
|
|
||||||
count={atUnreadList.length} // 数据当前的总数量
|
|
||||||
pageSize={10} //
|
|
||||||
>
|
|
||||||
{atUnreadList.map(item => {
|
|
||||||
return (
|
|
||||||
<div key={item.id + Math.random()} className="noticeCont-back" onClick={() => { readItem(item) }}>
|
|
||||||
<div className="noticeCont">
|
|
||||||
<span style={{ visibility: item.status === 1 ? 'visible' : 'hidden' }}>
|
|
||||||
<Badge color="#FA2020" />
|
|
||||||
</span>
|
|
||||||
<div className="noticeCont-text">
|
|
||||||
<span className="content-span atme-cont-span" dangerouslySetInnerHTML={{ __html: "<b>" + (item.sender ? item.sender.name : '') + "</b> " + item.content + " 中@我" }}></span>
|
|
||||||
<span className="timeSpan">{item.time_ago}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</AppPullRefresh>
|
|
||||||
}
|
|
||||||
|
|
||||||
{/* 私信 */}
|
|
||||||
{/* {noticeType === "1" ? letter_unread_list.length > 0 ? letter_unread_list.map(item => {
|
|
||||||
return (
|
|
||||||
<div className="noticeCont-back">
|
|
||||||
<div className="noticeCont" style={{ height: item.content.length >= 30 && item.content.length <= 34 ? '65px' : "" }}>
|
|
||||||
<Badge color="#FA2020" />
|
|
||||||
<div className="noticeCont-text">
|
|
||||||
<span>{item.send_name}:</span>
|
|
||||||
<span className="boldSpan" dangerouslySetInnerHTML={{ __html: item.content.length >= 50 ? item.content.substr(0, 50) + "..." : item.content }}></span>
|
|
||||||
<span className="timeSpan">{item.create_time ? timeAgo(item.create_time) : "刚刚"}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}) : "暂无数据" : ""} */}
|
|
||||||
<div className="hoverNotice-buttom">
|
|
||||||
<Link to={{pathname:"/settings/notice",query:{noticeType:noticeType}}}>全部消息</Link>
|
|
||||||
{noticeUnreadCount > 0 && noticeType === "notification" && <a onClick={readAll}>所有系统消息一键已读</a>}
|
|
||||||
{atUnreadCount > 0 && noticeType === "atme" && <a onClick={readAll}>所有@我一键已读</a>}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default NoticeContent;
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
.dropdownFlex{
|
.dropdownFlex{
|
||||||
display:flex;
|
display:flex;
|
||||||
|
padding:5px;
|
||||||
background:#fff;
|
background:#fff;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
.ant-menu-vertical > .ant-menu-item{
|
.ant-menu-vertical > .ant-menu-item{
|
||||||
|
@ -8,65 +9,11 @@
|
||||||
height: 35px;
|
height: 35px;
|
||||||
line-height: 35px;
|
line-height: 35px;
|
||||||
margin:0px;
|
margin:0px;
|
||||||
&.ant-menu-item-selected{
|
|
||||||
background-color: #fff;
|
|
||||||
a{color: rgba(0, 0, 0, 0.65)!important;}
|
|
||||||
}
|
|
||||||
&.ant-menu-item-active{
|
|
||||||
a{color: #4cacff!important;}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.ant-menu-vertical{
|
.ant-menu-vertical{
|
||||||
border:none;
|
border:none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.currentImg{
|
|
||||||
width: 34px;
|
|
||||||
height: 34px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.currentMenu{
|
|
||||||
width: 120px;
|
|
||||||
text-align: center;
|
|
||||||
padding:0px;
|
|
||||||
.currentName{
|
|
||||||
padding:0px 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
li{
|
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
padding:0px!important;
|
|
||||||
cursor: default;
|
|
||||||
&:hover{
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
&:first-child{
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
}
|
|
||||||
&:last-child{
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
a{
|
|
||||||
border-radius: 0px 0px 4px 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a{
|
|
||||||
padding:0px;
|
|
||||||
margin:0px;
|
|
||||||
display: block;
|
|
||||||
color: #666;
|
|
||||||
&:hover{
|
|
||||||
color: #fff;
|
|
||||||
background: #4CACFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newFooter {
|
.newFooter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -119,147 +66,3 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.inviteForm{
|
|
||||||
.ant-form-item{
|
|
||||||
margin-right: 0px;
|
|
||||||
}
|
|
||||||
.ant-form-item-label{
|
|
||||||
width: 110px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 右上角小铃铛单独样式
|
|
||||||
.notice-popover{
|
|
||||||
//popover小尖尖
|
|
||||||
.ant-popover-arrow{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
//popover框
|
|
||||||
.ant-popover-inner-content {
|
|
||||||
width: 386px;
|
|
||||||
height: 446px;
|
|
||||||
box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5);
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-top: -10px;
|
|
||||||
padding: 12px 1px 12px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.messageHoverDiv .ant-menu-item{
|
|
||||||
margin-right: 24px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hoverNotice-head{
|
|
||||||
margin-left: 18px;
|
|
||||||
|
|
||||||
& .ant-badge{
|
|
||||||
font-size: 14px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>.ant-menu-horizontal {
|
|
||||||
border-bottom: 1px solid #e8e8e8 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hoverNotice-body{
|
|
||||||
height: 342px;
|
|
||||||
overflow-y: scroll;
|
|
||||||
|
|
||||||
& b{
|
|
||||||
font-weight: 400;
|
|
||||||
text-shadow: 0.5px 0 0 #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.none_panels{
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-icon{
|
|
||||||
position: relative;
|
|
||||||
.ant-scroll-number{
|
|
||||||
right:12px;
|
|
||||||
padding: 0 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.hoverNotice-buttom{
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 12px 18px;
|
|
||||||
a{
|
|
||||||
color: #466AFF;
|
|
||||||
&:hover{
|
|
||||||
opacity:0.85;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.noticeCont-back{
|
|
||||||
.pointer{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
&:hover{
|
|
||||||
background: #F3F4F6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.noticeCont{
|
|
||||||
display: flex;
|
|
||||||
margin: 0 16px 0 18px;
|
|
||||||
padding: 12px 0 10px 0;
|
|
||||||
line-height: 24px;
|
|
||||||
border-bottom: 1px solid #EEEEEE;
|
|
||||||
cursor: default;
|
|
||||||
i{
|
|
||||||
font-size: 14px !important;
|
|
||||||
margin-right: 6px;
|
|
||||||
color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.boldSpan{
|
|
||||||
font-weight: 400;
|
|
||||||
text-shadow: 0.5px 0 0 #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.noticeCont-text{
|
|
||||||
display: flex;
|
|
||||||
color:#333333;
|
|
||||||
flex:auto;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
& .content-span{
|
|
||||||
word-break: break-all;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .atme-cont-span{
|
|
||||||
width: 272px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .notice-cont-span{
|
|
||||||
width: 255px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeSpan{
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.at-name{
|
|
||||||
margin-right: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-center{
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
|
@ -12,7 +12,6 @@ import Loadable from "react-loadable";
|
||||||
import Loading from "../Loading";
|
import Loading from "../Loading";
|
||||||
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
|
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
|
||||||
|
|
||||||
|
|
||||||
const ProjectNew = Loadable({
|
const ProjectNew = Loadable({
|
||||||
loader: () => import("./New/Index"),
|
loader: () => import("./New/Index"),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
|
@ -22,23 +21,17 @@ const ProjectIndex = Loadable({
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 项目详情放在用户和组织下作为二级菜单存在
|
const ProjectDetail = Loadable({
|
||||||
// const ProjectDetail = Loadable({
|
loader: () => import("./Main/Detail"),
|
||||||
// loader: () => import("./Main/Detail"),
|
loading: Loading,
|
||||||
// loading: Loading,
|
});
|
||||||
// });
|
|
||||||
|
|
||||||
|
const Infos = Loadable({
|
||||||
|
loader: () => import("./users/Infos"),
|
||||||
|
loading: Loading,
|
||||||
|
});
|
||||||
class Index extends Component {
|
class Index extends Component {
|
||||||
|
|
||||||
componentDidUpdate = () => {
|
|
||||||
this.props.history.listen(() => {
|
|
||||||
if (document.body.scrollTop || document.documentElement.scrollTop > 0) {
|
|
||||||
window.scrollTo(0, 0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="newMain clearfix">
|
<div className="newMain clearfix">
|
||||||
<Switch {...this.props}>
|
<Switch {...this.props}>
|
||||||
|
@ -55,27 +48,30 @@ class Index extends Component {
|
||||||
)}
|
)}
|
||||||
></Route>
|
></Route>
|
||||||
<Route
|
<Route
|
||||||
path="/projects/mirror/new"
|
path="/projects/new"
|
||||||
render={(props) => (
|
render={(props) => (
|
||||||
<ProjectNew {...this.props} {...props} />
|
<ProjectNew {...this.props} {...props} />
|
||||||
)}
|
)}
|
||||||
></Route>
|
></Route>
|
||||||
{/* <Route
|
<Route
|
||||||
path="/:owner/:projectsId"
|
path="/projects/:owner/:projectsId"
|
||||||
render={(props) => (
|
render={(props) => (
|
||||||
<ProjectDetail {...this.props} {...props} />
|
<ProjectDetail {...this.props} {...props} />
|
||||||
)}
|
)}
|
||||||
></Route> */}
|
></Route>
|
||||||
<Route
|
<Route
|
||||||
path="/explore"
|
path="/projects"
|
||||||
render={(props) => (
|
render={(props) => (
|
||||||
<ProjectIndex {...this.props} {...props} />
|
<ProjectIndex {...this.props} {...props} />
|
||||||
)}
|
)}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
|
exact
|
||||||
path="/"
|
path="/"
|
||||||
render={(props) => (
|
render={(props) => (
|
||||||
|
this.props.current_user && this.props.current_user.login ?
|
||||||
|
<Infos {...this.props} {...props} />
|
||||||
|
:
|
||||||
<ProjectIndex {...this.props} {...props} />
|
<ProjectIndex {...this.props} {...props} />
|
||||||
)}
|
)}
|
||||||
></Route>
|
></Route>
|
||||||
|
@ -90,10 +86,3 @@ export default withRouter(
|
||||||
parentSelector: ".newMain",
|
parentSelector: ".newMain",
|
||||||
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index))))
|
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Index))))
|
||||||
);
|
);
|
||||||
|
|
||||||
// export default withRouter(
|
|
||||||
// ImageLayerOfCommentHOC({
|
|
||||||
// imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
|
||||||
// parentSelector: ".newMain",
|
|
||||||
// })(Index)
|
|
||||||
// );
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import React , { useEffect , useState } from 'react';
|
import React , { useEffect , useState } from 'react';
|
||||||
import { WhiteBack , Box , LongWidth , ShortWidth , Gap , AlignCenter , FlexAJ } from '../Component/layout';
|
import { WhiteBack , Box , LongWidth , ShortWidth , Gap , AlignCenter , FlexAJ } from '../Component/layout';
|
||||||
import { Dropdown , Menu , Divider , Spin, Button , Typography } from 'antd';
|
import { Dropdown , Menu , Divider , Spin, Button } from 'antd';
|
||||||
import { getImageUrl } from "educoder";
|
import { getImageUrl } from "educoder";
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { truncateCommitId } from "../common/util";
|
|
||||||
import CloneAddress from '../Branch/CloneAddress';
|
import CloneAddress from '../Branch/CloneAddress';
|
||||||
|
|
||||||
import SelectBranch from '../Branch/Select';
|
import SelectBranch from '../Branch/Select';
|
||||||
|
@ -20,30 +19,12 @@ import LanguagePower from '../Component/LanguagePower';
|
||||||
import DrawerPanel from '../Component/DrawerPanel';
|
import DrawerPanel from '../Component/DrawerPanel';
|
||||||
import UpdateDescModal from './sub/UpdateDescModal';
|
import UpdateDescModal from './sub/UpdateDescModal';
|
||||||
import Nodata from '../Nodata';
|
import Nodata from '../Nodata';
|
||||||
import Invite from './sub/Invite';
|
|
||||||
import CheckProfile from '../Component/ProfileModal/Profile';
|
|
||||||
import RenderHtml from '../../components/render-html';
|
|
||||||
import Badge from "./sub/Badge";
|
|
||||||
/**
|
/**
|
||||||
* projectDetail.type:0是托管项目,1是镜像项目,2是同步镜像项目(为2时不支持在线创建、在线上传、在线修改、在线删除、创建合并请求等功能)
|
* projectDetail.type:0是托管项目,1是镜像项目,2是同步镜像项目(为2时不支持在线创建、在线上传、在线修改、在线删除、创建合并请求等功能)
|
||||||
*/
|
*/
|
||||||
const { Paragraph } = Typography;
|
|
||||||
function turnbar(str){
|
|
||||||
if(str && str.length>0 && str.indexOf("/")>-1){
|
|
||||||
return str.replaceAll('/','%2F');
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
function returnbar(str){
|
|
||||||
if(str && str.length>0 && str.indexOf("%2F")>-1){
|
|
||||||
return str.replaceAll('%2F','/');
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
function CoderDepot(props){
|
function CoderDepot(props){
|
||||||
const [ projectDetail , setProjectDetail ]= useState(undefined);
|
const [ projectDetail , setProjectDetail ]= useState(undefined);
|
||||||
const [ inviteCode , setInviteCode ] = useState(undefined);
|
|
||||||
const [ treeValue , setTreeValue ] = useState(undefined);
|
const [ treeValue , setTreeValue ] = useState(undefined);
|
||||||
const [ treeValuePath , setTreeValuePath ] = useState(undefined);
|
const [ treeValuePath , setTreeValuePath ] = useState(undefined);
|
||||||
const [ lastCommit,setLastCommit ] = useState(undefined);
|
const [ lastCommit,setLastCommit ] = useState(undefined);
|
||||||
|
@ -64,53 +45,19 @@ function CoderDepot(props){
|
||||||
const [ desc , setDesc ] = useState(undefined);
|
const [ desc , setDesc ] = useState(undefined);
|
||||||
const [ website , setWebsite ] = useState(undefined);
|
const [ website , setWebsite ] = useState(undefined);
|
||||||
const [ lesson_url , setLessonUrl ] = useState(undefined);
|
const [ lesson_url , setLessonUrl ] = useState(undefined);
|
||||||
const [ readme , setReadme ] = useState(undefined);
|
|
||||||
const [ defaultBranch , setDefaultBranch ] = useState(undefined);
|
|
||||||
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 owner = props.match.params.owner;
|
||||||
const projectsId = props.match.params.projectsId;
|
const projectsId = props.match.params.projectsId;
|
||||||
let branchName = props.match.params.branchName;
|
const branchName = props.match.params.branchName;
|
||||||
branchName = returnbar(branchName);
|
|
||||||
const details = props.projectDetail;
|
|
||||||
let pathname = props.history.location.pathname;
|
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;
|
|
||||||
|
|
||||||
|
|
||||||
// test data
|
|
||||||
const badges = {badge:[{ "login": "many_stars", "image_url": "https://www.gitlink.org.cn/system/lets/letter_avatars/2/J/236_194_58/120.png", "description": "test description1"}, {"login": "many_stars", "image_url": "https://www.gitlink.org.cn/system/lets/letter_avatars/2/X/181_166_38/120.png", "description": "test description2"}], total_count: 3}
|
|
||||||
console.log(badges.badge)
|
|
||||||
console.log(badges.total_count)
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(bannerList && bannerList.length>0){
|
if(props.projectDetail){
|
||||||
let a = bannerList.filter(i=>i.menu_name === "pulls");
|
setProjectDetail(props.projectDetail);
|
||||||
let i = bannerList.filter(i=>i.menu_name === "issues");
|
setDesc(props.projectDetail.description);
|
||||||
if(a && a.length === 0){
|
setWebsite(props.projectDetail.website);
|
||||||
setPullsFlag(false);
|
setLessonUrl(props.projectDetail.lesson_url);
|
||||||
}
|
}
|
||||||
if(i && i.length === 0){
|
},[props])
|
||||||
setIssuesFlag(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},[bannerList])
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
if(details){
|
|
||||||
setProjectDetail(details);
|
|
||||||
setDesc(details.description);
|
|
||||||
setWebsite(details.website);
|
|
||||||
setLessonUrl(details.lesson_url);
|
|
||||||
setDefaultBranch(details.default_branch);
|
|
||||||
setInviteCode(details.invite_code);
|
|
||||||
}
|
|
||||||
},[details])
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(treeValue){
|
if(treeValue){
|
||||||
|
@ -120,61 +67,23 @@ function CoderDepot(props){
|
||||||
}
|
}
|
||||||
},[treeValue])
|
},[treeValue])
|
||||||
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if (projectsId && owner && defaultBranch){
|
if (pathname && projectDetail){
|
||||||
let b = turnbar(branchName) ;
|
if(pathname.indexOf(`/projects/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${branchName}/`) > -1) {
|
||||||
if(pathname.indexOf(`/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${b}/`) > -1) {
|
let url = pathname.split(`/tree/${branchName}/`)[1];
|
||||||
let url = pathname.split(`/tree/${b}/`)[1];
|
|
||||||
setTreeValue(url);
|
setTreeValue(url);
|
||||||
getFileInfo(url,branchName);
|
getFileInfo(url,branchName);
|
||||||
setType("file");
|
|
||||||
// getReadmeInfo(url,branchName);
|
|
||||||
// setReadme(undefined);
|
|
||||||
}else{
|
}else{
|
||||||
setTreeValue(undefined);
|
setTreeValue(undefined);
|
||||||
getDirInfo(branchName || defaultBranch);
|
getDirInfo(branchName ||projectDetail.default_branch);
|
||||||
setType("dir");
|
|
||||||
// getReadmeInfo('', branchName || defaultBranch);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},[projectsId,owner,pathname,defaultBranch])
|
},[pathname,projectDetail])
|
||||||
|
|
||||||
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){
|
function getDirInfo(branch){
|
||||||
setIsSpin(true);
|
setIsSpin(true);
|
||||||
const url = `/${owner}/${projectsId}/entries.json`;
|
const url = `/${owner}/${projectsId}/entries.json`;
|
||||||
|
|
||||||
axios.get(url, {
|
axios.get(url, {
|
||||||
params: { ref: branch }
|
params: { ref: branch }
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
|
@ -189,10 +98,6 @@ function CoderDepot(props){
|
||||||
setLastCommitAuthor(c && c.committer);
|
setLastCommitAuthor(c && c.committer);
|
||||||
setMainFlag(true);
|
setMainFlag(true);
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
// setReadme(result.data.readme);
|
|
||||||
setEditReadme(false);
|
|
||||||
setHide(true);
|
|
||||||
getReadmeInfo('', branchName || defaultBranch);
|
|
||||||
}
|
}
|
||||||
setTimeout(function(){setIsSpin(false);},500);
|
setTimeout(function(){setIsSpin(false);},500);
|
||||||
}).catch(error=>{setIsSpin(false);})
|
}).catch(error=>{setIsSpin(false);})
|
||||||
|
@ -204,7 +109,7 @@ function CoderDepot(props){
|
||||||
let ele = document.getElementById("ptxt");
|
let ele = document.getElementById("ptxt");
|
||||||
if(ele){
|
if(ele){
|
||||||
let h = ele.offsetHeight;
|
let h = ele.offsetHeight;
|
||||||
if( h > 35 ) setHideBtn(true);
|
if( h > 18 ) setHideBtn(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},[projectDetail,lastCommit])
|
},[projectDetail,lastCommit])
|
||||||
|
@ -225,20 +130,16 @@ function CoderDepot(props){
|
||||||
setDirInfo(undefined);
|
setDirInfo(undefined);
|
||||||
setFileInfo(en);
|
setFileInfo(en);
|
||||||
setType(en.type);
|
setType(en.type);
|
||||||
setReadme(undefined);
|
|
||||||
}else{
|
}else{
|
||||||
setFileInfo(undefined);
|
setFileInfo(undefined);
|
||||||
setDirInfo(en);
|
setDirInfo(en);
|
||||||
setType("dir");
|
setType("dir");
|
||||||
getReadmeInfo(path, branchName || defaultBranch);
|
|
||||||
}
|
}
|
||||||
let c = result.data.last_commit
|
let c = result.data.last_commit
|
||||||
setLastCommit(c && c.commit);
|
setLastCommit(c && c.commit);
|
||||||
setLastCommitAuthor(c && c.committer);
|
setLastCommitAuthor(c && c.committer);
|
||||||
setMainFlag(false);
|
setMainFlag(false);
|
||||||
setReadOnly(true);
|
setReadOnly(true);
|
||||||
setReadOnly(!editReadme);
|
|
||||||
setHide(true);
|
|
||||||
}
|
}
|
||||||
setTimeout(function(){setIsSpin(false);},500)
|
setTimeout(function(){setIsSpin(false);},500)
|
||||||
}).catch(error=>{setIsSpin(false);})
|
}).catch(error=>{setIsSpin(false);})
|
||||||
|
@ -246,26 +147,17 @@ function CoderDepot(props){
|
||||||
|
|
||||||
// 切换分支或者标签
|
// 切换分支或者标签
|
||||||
function changeBranch(value){
|
function changeBranch(value){
|
||||||
let checkvalue = turnbar(value);
|
let url = `/projects/${owner}/${projectsId}${value && `/tree/${value}`}${treeValue ? `/${treeValue}`:""}`;
|
||||||
let url = `/${owner}/${projectsId}${value && `/tree/${checkvalue}`}${treeValue ? `/${treeValue}`:""}`;
|
|
||||||
props.history.push(url);
|
props.history.push(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件相关的下拉项
|
// 文件相关的下拉项
|
||||||
function fileMenu(){
|
const fileMenu =(
|
||||||
let b = branchName || defaultBranch;
|
<Menu>
|
||||||
let checkvalue = turnbar(b);
|
<Menu.Item><a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/${branchName || (projectDetail && projectDetail.default_branch)}/uploadfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>上传文件</a></Menu.Item>
|
||||||
return (
|
<Menu.Item><a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/${branchName || (projectDetail && projectDetail.default_branch)}/newfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>新建文件</a></Menu.Item>
|
||||||
<Menu className="fileMenu">
|
|
||||||
<Menu.Item>
|
|
||||||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/${checkvalue}/uploadfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>上传文件</CheckProfile>
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Item>
|
|
||||||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/${checkvalue}/newfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>新建文件</CheckProfile>
|
|
||||||
</Menu.Item>
|
|
||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
function getPathUrl(array,index){
|
function getPathUrl(array,index){
|
||||||
if(array && array.length>0 && index){
|
if(array && array.length>0 && index){
|
||||||
|
@ -279,36 +171,27 @@ function CoderDepot(props){
|
||||||
// 页面地址返回到主目录
|
// 页面地址返回到主目录
|
||||||
function returnMain(){
|
function returnMain(){
|
||||||
setTreeValue(undefined);
|
setTreeValue(undefined);
|
||||||
let branch = branchName || defaultBranch;
|
let branch = branchName || (projectDetail && projectDetail.default_branch);
|
||||||
let checkvalue = turnbar(branch);
|
props.history.push(`/projects/${owner}/${projectsId}/tree/${branch}`);
|
||||||
props.history.push(`/${owner}/${projectsId}/tree/${checkvalue}`);
|
|
||||||
};
|
};
|
||||||
// 子目录路径返回链接
|
// 子目录路径返回链接
|
||||||
function returnUlr(url){
|
function returnUlr(url){
|
||||||
let enBranch = turnbar(branchName);
|
props.history.push(`/projects/${owner}/${projectsId}/tree${branchName?`/${branchName}`:""}/${url}`);
|
||||||
props.history.push(`/${owner}/${projectsId}/tree${enBranch?`/${enBranch}`:""}/${url}`);
|
|
||||||
}
|
}
|
||||||
// 点击跳转到子目录
|
// 点击跳转到子目录
|
||||||
function goToSubRoot(path,type,filename){
|
function goToSubRoot(path,type,filename){
|
||||||
if(type!=="submodule"){
|
|
||||||
let enBranch = branchName || defaultBranch;
|
|
||||||
let checkvalue = turnbar(enBranch);
|
|
||||||
setType(type);
|
setType(type);
|
||||||
props.history.push(`/${owner}/${projectsId}${`/tree/${checkvalue}`}${path?`/${path}`:""}`);
|
props.history.push(`/projects/${owner}/${projectsId}${`/tree/${branchName || (projectDetail && projectDetail.default_branch)}`}${path?`/${path}`:""}`);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEdit(readOnly){
|
function onEdit(readOnly){
|
||||||
setReadOnly(readOnly);
|
setReadOnly(readOnly);
|
||||||
setEditReadme(false);
|
|
||||||
}
|
}
|
||||||
function ChangeFile(path, readOnly){
|
function ChangeFile(path, readOnly){
|
||||||
//点击直接跳转页面 加载一次路由
|
//点击直接跳转页面 加载一次路由
|
||||||
let enBranch = branchName || defaultBranch;
|
props.history.push(`/projects/${owner}/${projectsId}/tree/${branchName || (projectDetail && projectDetail.default_branch)}/${path}`);
|
||||||
let checkvalue = turnbar(enBranch);
|
|
||||||
props.history.push(`/${owner}/${projectsId}/tree/${checkvalue}/${path}`);
|
|
||||||
setType("file");
|
setType("file");
|
||||||
setEditReadme(true);
|
setReadOnly(readOnly);
|
||||||
};
|
};
|
||||||
|
|
||||||
function changeHide(hide){
|
function changeHide(hide){
|
||||||
|
@ -324,12 +207,17 @@ function CoderDepot(props){
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadMenu = (
|
const downloadMenu = (
|
||||||
|
<div className="downMenu">
|
||||||
|
<div style={{padding:"20px",borderBottom:"1px solid #eee"}}>
|
||||||
<CloneAddress
|
<CloneAddress
|
||||||
http_url={projectDetail && projectDetail.clone_url}
|
http_url={projectDetail && projectDetail.clone_url}
|
||||||
ssh_url = {projectDetail && projectDetail.ssh_url}
|
|
||||||
zip_url={zip_url}
|
|
||||||
tar_url={tar_url}
|
|
||||||
showNotification={props.showNotification}/>
|
showNotification={props.showNotification}/>
|
||||||
|
</div>
|
||||||
|
<Menu className="edu-txt-center">
|
||||||
|
<Menu.Item><a href={zip_url}>下载 ZIP</a></Menu.Item>
|
||||||
|
<Menu.Item><a href={tar_url}>下载 TAR.GZ</a></Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
// 确认修改简介、website、实践课程链接
|
// 确认修改简介、website、实践课程链接
|
||||||
function okUpdate(d,w,l){
|
function okUpdate(d,w,l){
|
||||||
|
@ -344,16 +232,11 @@ function CoderDepot(props){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let n = fileInfo && fileInfo.name;
|
let n = fileInfo && fileInfo.name;
|
||||||
const mdFlag = n && n.substring(n.length-3,n.length) === ".md";
|
const mdFlag = n && n.substring(n.length-3,n.length) === ".md";
|
||||||
|
|
||||||
const { current_user } = props;
|
|
||||||
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(
|
return(
|
||||||
|
|
||||||
<WhiteBack>
|
<WhiteBack>
|
||||||
<UpdateDescModal desc={desc} website={website} lesson_url={lesson_url} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
|
<UpdateDescModal desc={desc} website={website} lesson_url={lesson_url} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
|
||||||
<Spin spinning={isSpin}>
|
<Spin spinning={isSpin}>
|
||||||
|
@ -365,44 +248,90 @@ function CoderDepot(props){
|
||||||
owner={owner}
|
owner={owner}
|
||||||
projectsId={projectsId}
|
projectsId={projectsId}
|
||||||
name={projectDetail && projectDetail.name}
|
name={projectDetail && projectDetail.name}
|
||||||
branch={branchName || defaultBranch}
|
branch={branchName || (projectDetail && projectDetail.default_branch)}
|
||||||
visible={visible}
|
visible={visible}
|
||||||
onClose={()=>setVisible(false)}
|
onClose={()=>setVisible(false)}
|
||||||
list = {mainFlag ? dirInfo : undefined}
|
list = {mainFlag ? dirInfo : undefined}
|
||||||
/>
|
/>
|
||||||
<div className="drawerBtn" onClick={()=>setVisible(true)}>
|
<div className="drawerBtn" onClick={()=>setVisible(true)}>
|
||||||
<i className="iconfont icon-zuohuaicon font-14"></i>
|
<i className="iconfont icon-youjiantou font-16"></i>
|
||||||
<span>目录</span>
|
<span>目录</span>
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
<div style={{minHeight:"500px"}}>
|
<div style={{minHeight:"500px"}}>
|
||||||
{
|
{
|
||||||
|
|
||||||
projectDetail &&
|
projectDetail &&
|
||||||
<Box className="Panels">
|
<Box className="Panels">
|
||||||
<LongWidth>
|
<LongWidth>
|
||||||
<div className="panelmenu">
|
<div className="panelmenu">
|
||||||
<FlexAJ>
|
<FlexAJ>
|
||||||
<AlignCenter>
|
<AlignCenter>
|
||||||
<div className="mr30">
|
<div className="mr20">
|
||||||
{
|
{
|
||||||
props && props.platform ?
|
props && props.platform ?
|
||||||
<SelectBranch
|
<SelectBranch
|
||||||
repo_id={projectDetail && projectDetail.repo_id}
|
repo_id={projectDetail && projectDetail.repo_id}
|
||||||
projectsId={projectsId}
|
projectsId={projectsId}
|
||||||
branch={branchName || defaultBranch}
|
branch={branchName || (projectDetail && projectDetail.default_branch)}
|
||||||
changeBranch={changeBranch}
|
changeBranch={changeBranch}
|
||||||
owner={owner}
|
owner={owner}
|
||||||
history={props.history}
|
history={props.history}
|
||||||
branchList={projectDetail && projectDetail.branches && projectDetail.branches.list}
|
branchList={projectDetail && projectDetail.branches && projectDetail.branches.list}
|
||||||
></SelectBranch>
|
></SelectBranch>
|
||||||
:
|
:
|
||||||
<span>分支:<span className="color-grey-6">{branchName || defaultBranch}</span></span>
|
<span>分支:<span className="color-grey-6">{branchName || (projectDetail && projectDetail.default_branch)}</span></span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
<AlignCenter className="mr20">
|
||||||
|
<Link to={`/projects/${owner}/${projectsId}/branchs`} className="color-grey-9">
|
||||||
|
<i className="iconfont icon-fenzhi2 font-18 color-grey-9 mr3"></i>
|
||||||
|
<span className="color-grey-6 mr3">{projectDetail && projectDetail.branches && projectDetail.branches.total_count}个</span>分支
|
||||||
|
</Link>
|
||||||
|
</AlignCenter>
|
||||||
|
<AlignCenter className="mr20">
|
||||||
|
<Link to={`/projects/${owner}/${projectsId}/tag`} className="color-grey-9">
|
||||||
|
<i className="iconfont icon-biaoqian3 font-16 color-grey-9 mr3"></i>
|
||||||
|
<span className="color-grey-6 mr3">{projectDetail && projectDetail.tags && projectDetail.tags.total_count}个</span>标签
|
||||||
|
</Link>
|
||||||
|
</AlignCenter>
|
||||||
|
</AlignCenter>
|
||||||
|
<AlignCenter>
|
||||||
|
<div className="mr20 addOptionBtn">
|
||||||
{
|
{
|
||||||
treeValuePath && treeValuePath.length > 0 ?
|
projectDetail.type !== 2 &&
|
||||||
|
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/pulls/new`)} >+ 合并请求</a>
|
||||||
|
}
|
||||||
|
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/issues/new`)} >+ 任务</a>
|
||||||
|
</div>
|
||||||
|
{ type === "dir" && projectDetail.type !== 2 &&
|
||||||
|
<Dropdown overlay={fileMenu} className="mr20" trigger={['click']}>
|
||||||
|
<Button type="default">文件 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-grey-9"></i></Button>
|
||||||
|
</Dropdown>
|
||||||
|
}
|
||||||
|
|
||||||
|
<Dropdown overlay={downloadMenu} placement="bottomRight" trigger={['click']}>
|
||||||
|
<Button type={'primary'}>下载 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-white"></i></Button>
|
||||||
|
</Dropdown>
|
||||||
|
</AlignCenter>
|
||||||
|
</FlexAJ>
|
||||||
|
{
|
||||||
|
dirInfo || fileInfo ?
|
||||||
|
<div className="listtable">
|
||||||
|
{
|
||||||
|
lastCommit &&
|
||||||
|
<div className="listtablehead">
|
||||||
|
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} id={lastCommitAuthor && lastCommitAuthor.id} login={lastCommitAuthor && lastCommitAuthor.login}/>
|
||||||
|
<div className={hideBtn && hide ? "ellipsistxt hide" :"ellipsistxt"}><pre id="ptxt">{lastCommit && lastCommit.message}</pre></div>
|
||||||
|
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
|
||||||
|
|
||||||
|
<span className="ml12 color-grey-9 mt3">{lastCommit && lastCommit.time_from_now}</span>
|
||||||
|
{ commitCount ? <Link to={`/projects/${owner}/${projectsId}/commits`} className="ml12 color-grey-9"><i className="iconfont icon-tijiao mr3 font-17 color-grey-9"></i>{commitCount}次提交</Link>:"" }
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<ul className="listtablebody">
|
||||||
|
{
|
||||||
|
treeValuePath && treeValuePath.length > 0 &&
|
||||||
<Path
|
<Path
|
||||||
identifier={projectDetail && projectDetail.identifier}
|
identifier={projectDetail && projectDetail.identifier}
|
||||||
treeValuePath={treeValuePath}
|
treeValuePath={treeValuePath}
|
||||||
|
@ -410,77 +339,7 @@ function CoderDepot(props){
|
||||||
returnMain={returnMain}
|
returnMain={returnMain}
|
||||||
getPathUrl={getPathUrl}
|
getPathUrl={getPathUrl}
|
||||||
/>
|
/>
|
||||||
:
|
|
||||||
<React.Fragment>
|
|
||||||
<AlignCenter className="mr20">
|
|
||||||
<Link to={`/${owner}/${projectsId}/branches`} className="iconBtn">
|
|
||||||
<i className="iconfont icon-master_icon font-16"></i>
|
|
||||||
<span>分支</span>
|
|
||||||
<span>{projectDetail && projectDetail.branches_count}</span>
|
|
||||||
</Link>
|
|
||||||
</AlignCenter>
|
|
||||||
<AlignCenter className="mr20">
|
|
||||||
<Link to={`/${owner}/${projectsId}/tags`} className="iconBtn">
|
|
||||||
<i className="iconfont icon-biaoqianicon font-16"></i>
|
|
||||||
<span>标签</span>
|
|
||||||
<span>{projectDetail && projectDetail.tags_count}</span>
|
|
||||||
</Link>
|
|
||||||
</AlignCenter>
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
}
|
||||||
</AlignCenter>
|
|
||||||
<AlignCenter className="depotBtn">
|
|
||||||
{
|
|
||||||
(baseOperate || baseOper) &&
|
|
||||||
<div className="addOptionBtn">
|
|
||||||
{
|
|
||||||
baseOperate &&
|
|
||||||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/compare/master...${branchName || defaultBranch}`)} >+ 合并请求</CheckProfile>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
baseOper &&
|
|
||||||
<CheckProfile {...props} sureFunc={()=>urlLink(`/${owner}/${projectsId}/issues/new`)} >+ 易修</CheckProfile>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{ fileOperate &&
|
|
||||||
<Dropdown
|
|
||||||
overlay={fileMenu()}
|
|
||||||
className="mr10"
|
|
||||||
trigger={['click']}
|
|
||||||
getPopupContainer={document.parentNode}
|
|
||||||
>
|
|
||||||
<a>文件 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-grey-6 mr-5"></i></a>
|
|
||||||
</Dropdown>
|
|
||||||
}
|
|
||||||
|
|
||||||
<Dropdown overlay={downloadMenu} placement="bottomRight" trigger={['click']}>
|
|
||||||
<Button type={'primary'}>下载 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-white mr-3"></i></Button>
|
|
||||||
</Dropdown>
|
|
||||||
</AlignCenter>
|
|
||||||
</FlexAJ>
|
|
||||||
{
|
|
||||||
(dirInfo && dirInfo.length>0) || fileInfo ?
|
|
||||||
<div className="listtable">
|
|
||||||
{
|
|
||||||
lastCommit &&
|
|
||||||
<div className="listtablehead">
|
|
||||||
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} id={lastCommitAuthor && lastCommitAuthor.id} login={lastCommitAuthor && lastCommitAuthor.login}/>
|
|
||||||
<div className={hideBtn && hide ? "ellipsistxt hidetxt" :"ellipsistxt"}>
|
|
||||||
<pre id="ptxt"><Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(lastCommit.sha)}`}><RenderHtml value={lastCommit.message}/></Link></pre>
|
|
||||||
</div>
|
|
||||||
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
|
|
||||||
|
|
||||||
<span className="ml20 color-grey-6 font-12 mt3">{lastCommit.time_from_now}</span>
|
|
||||||
{
|
|
||||||
commitCount ?
|
|
||||||
<Link to={`/${owner}/${projectsId}/commits/branch/${turnbar(branchName || defaultBranch)}`} className="ml20 color-grey-3"style={{height:"28px",lineHeight:"28px"}}>
|
|
||||||
<i className="iconfont icon-tijiaoicon mr3 font-16"></i><span style={{fontWeight:"500"}}>{commitCount}次提交</span>
|
|
||||||
</Link>:""
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<ul className="listtablebody">
|
|
||||||
{
|
{
|
||||||
dirInfo && dirInfo.length > 0 &&
|
dirInfo && dirInfo.length > 0 &&
|
||||||
dirInfo.map((item,key)=>{
|
dirInfo.map((item,key)=>{
|
||||||
|
@ -502,7 +361,7 @@ function CoderDepot(props){
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
md={mdFlag}
|
md={mdFlag}
|
||||||
onEdit={onEdit}
|
onEdit={onEdit}
|
||||||
currentBranch={branchName || defaultBranch}
|
currentBranch={branchName || (projectDetail && projectDetail.default_branch)}
|
||||||
type={projectDetail.type}
|
type={projectDetail.type}
|
||||||
></CoderRootFileDetail>
|
></CoderRootFileDetail>
|
||||||
}
|
}
|
||||||
|
@ -511,93 +370,64 @@ function CoderDepot(props){
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
(dirInfo && dirInfo.length === 0) && !fileInfo ? <Nodata _html="暂未发现文件"/> :""
|
(dirInfo && dirInfo.length === 0) && (fileInfo && fileInfo.length === 0) ? <Nodata _html="暂未发现文件"/> :""
|
||||||
}
|
}
|
||||||
{/* readme文件显示(显示文件详情时不显示readme文件) */}
|
{/* readme文件显示(显示文件详情时不显示readme文件) */}
|
||||||
{ (readme && readme.content) ? <ReadMe ChangeFile={ChangeFile} readme={readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
|
{ dirInfo && (projectDetail && projectDetail.readme) ? <ReadMe ChangeFile={ChangeFile} readme={projectDetail && projectDetail.readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
|
||||||
</div>
|
</div>
|
||||||
</LongWidth>
|
</LongWidth>
|
||||||
{
|
{
|
||||||
(!(treeValuePath && treeValuePath.length > 0) && !fileInfo) &&
|
!fileInfo &&
|
||||||
<ShortWidth>
|
<ShortWidth>
|
||||||
<Gap style={{paddingLeft:"30px"}}>
|
<Gap style={{paddingLeft:"30px"}}>
|
||||||
<div className="panelmenu">
|
<div className="panelmenu">
|
||||||
<FlexAJ className="font-18 color-ooo mb20" style={{lineHeight:"28px"}}>关于
|
<FlexAJ className="font-18 color-grey-6 mb20" style={{lineHeight:"28px"}}>简介
|
||||||
{
|
{projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner") && <i onClick={()=>setOpenModal(true)} className="iconfont icon-anquanshezhi color-grey-9 font-15"></i>}
|
||||||
projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner" || projectDetail.permission==="Manager") &&
|
|
||||||
<i onClick={()=>setOpenModal(true)} className="iconfont icon-a-shezhi color-grey-9 font-15"></i>
|
|
||||||
}
|
|
||||||
</FlexAJ>
|
</FlexAJ>
|
||||||
{desc && <p className="font-14 color-grey-3 mb15 task-hide-2" style={{lineHeight:"24px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}}>{desc}</p>}
|
{desc && <p className="font-14 color-grey-9 mb15 task-hide-2" style={{lineHeight:"22px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}}>{desc}</p>}
|
||||||
{
|
{
|
||||||
website &&
|
website &&
|
||||||
<div className="color-grey-6 df pinfos mb5">
|
<p className="color-grey-6 df">
|
||||||
<i className="iconfont icon-lianjie2 font-15 mr10"></i>
|
<i className="iconfont icon-lianjie2 font-15 mr10 color-grey-9"></i>
|
||||||
<a href={website} target="_blank" style={{wordBreak:"break-all",lineHeight:"20px",marginTop:"5px",textDecoration:"underline"}}>{website}</a>
|
<a href={website} target="_blank" style={{wordBreak:"break-all",lineHeight:"20px",marginTop:"5px",textDecoration:"underline"}}>{website}</a>
|
||||||
</div>
|
</p>
|
||||||
}
|
}
|
||||||
<div className="pinfos mb5">
|
<p>
|
||||||
<i className="iconfont icon-zishuwenjian_icon font-15 mr10"></i>
|
<i className="iconfont icon-wenjian4 font-15 mr10 color-grey-9"></i>
|
||||||
<a href="#readme">README.md</a>
|
<a href="#readme" className="color-grey-6">README.md</a>
|
||||||
</div>
|
</p>
|
||||||
<div className="color-grey-6 mb5">
|
<p className="color-grey-6">
|
||||||
<i className="iconfont icon-neicunicon font-15 mr10"></i>
|
<i className="iconfont icon-dataBase font-15 mr10 color-grey-9"></i>
|
||||||
<span>{projectDetail && projectDetail.size}</span>
|
<span>{projectDetail && projectDetail.size}</span>
|
||||||
</div>
|
</p>
|
||||||
{
|
{
|
||||||
projectDetail && projectDetail.license_name &&
|
projectDetail && projectDetail.license_name &&
|
||||||
<div className="pinfos">
|
<p className="color-grey-6">
|
||||||
<i className="iconfont icon-xieyiicon font-16 mr10"></i>
|
<i className="iconfont icon-tianping font-16 mr10 color-grey-9"></i>
|
||||||
<Link to={`/${owner}/${projectsId}/tree/${branchName || defaultBranch}/LICENSE`} className="color-grey-6">{projectDetail.license_name}</Link>
|
<span>{projectDetail.license_name}</span>
|
||||||
</div>
|
</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
{
|
|
||||||
inviteCode &&
|
|
||||||
<div>
|
|
||||||
<Divider />
|
|
||||||
<Invite code={inviteCode}/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{/*{*/}
|
|
||||||
{/* inviteCode &&*/}
|
|
||||||
{/* <div>*/}
|
|
||||||
{/* <Badge code={inviteCode}/>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/*}*/}
|
|
||||||
|
|
||||||
{/* 徽章 */}
|
|
||||||
{
|
|
||||||
badges && badges.total_count >0 &&
|
|
||||||
<Badge badges={badges} owner={owner} />
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
lesson_url &&
|
lesson_url &&
|
||||||
<div>
|
<div>
|
||||||
<Divider />
|
<Divider />
|
||||||
<p className="font-16 color-ooo">实践课程</p>
|
<p className="font-16 color-grey-6">实践课程</p>
|
||||||
<a href={lesson_url} target="_blank" className="color-grey-6" style={{textDecoration:"underline",wordBreak:"break-all"}}>{lesson_url}</a>
|
<a href={lesson_url} target="_blank" className="color-grey-6" style={{textDecoration:"underline"}}>{lesson_url}</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{/* 发布 */}
|
{/* 发布 */}
|
||||||
{
|
{
|
||||||
releaseVersions &&
|
projectDetail && projectDetail.release_versions &&
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Releases
|
<Releases owner={owner} projectsId={projectsId} releaseVersions={projectDetail.release_versions} history={props.history}/>
|
||||||
owner={owner}
|
|
||||||
projectsId={projectsId}
|
|
||||||
releaseVersions={releaseVersions}
|
|
||||||
history={props.history}
|
|
||||||
distribution={distribution}
|
|
||||||
/>
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
{/* 贡献者 */}
|
{/* 贡献者 */}
|
||||||
{
|
{
|
||||||
projectDetail && projectDetail.contributors && projectDetail.contributors.total_count >0 &&
|
projectDetail && projectDetail.contributors &&
|
||||||
<Contributors contributors={projectDetail.contributors} owner={owner} projectsId={projectsId} />
|
<Contributors contributors={projectDetail && projectDetail.contributors} owner={owner} projectsId={projectsId} />
|
||||||
}
|
}
|
||||||
{/* 语言 */}
|
{/* 语言 */}
|
||||||
{ projectDetail && projectDetail.languages &&
|
{ projectDetail && projectDetail.languages &&
|
||||||
|
|
|
@ -2,26 +2,20 @@ import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { truncateCommitId } from '../common/util';
|
import { truncateCommitId } from '../common/util';
|
||||||
|
|
||||||
const typeIco = {
|
|
||||||
"submodule":"icon-file-submodule font-17",
|
|
||||||
"file":'icon-wenjian6 font-15 color-blue-file',
|
|
||||||
"dir":"icon-wenjianjia4 font-15 color-blue_4C"
|
|
||||||
}
|
|
||||||
|
|
||||||
function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId }){
|
function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId }){
|
||||||
return(
|
return(
|
||||||
<li>
|
<li>
|
||||||
<span>
|
<span>
|
||||||
<a onClick={()=>goToSubRoot(item.path,item.type,item.name)} className={item.type === "submodule" && "submoduleStyle"}>
|
<a onClick={()=>goToSubRoot(item.path,item.type,item.name)}>
|
||||||
<i className={`iconfont ${typeIco[`${item.type}`]} mr8`}></i>{item.name}
|
<i className={item.type === 'dir' ? "iconfont icon-wenjianjia1 color-green-file font-15 mr5":"iconfont icon-wenjia color-green-file font-15 mr5"}></i>{item.name}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span title="init project">
|
<span title="init project">
|
||||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.commit && item.commit.sha}`)}`} title={item.commit && item.commit.message}>
|
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.commit && item.commit.sha}`)}`} title={item.commit && item.commit.message}>
|
||||||
{item.commit && item.commit.message}
|
{item.commit && item.commit.message}
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
<span title={item.commit && item.commit.created_at}>{item.commit && item.commit.time_from_now}</span>
|
<span>{item.commit && item.commit.time_from_now}</span>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { result } from 'lodash';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,74 +1,61 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import RenderHtml from '../../components/render-html';
|
import RenderHtml from '../../components/render-html';
|
||||||
import { AlignCenter } from '../Component/layout';
|
import { Dropdown , Menu , Spin } from 'antd';
|
||||||
import { Dropdown , Anchor , Spin } from 'antd';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import ReadmeCatelogue from './sub/ReadmeCatelogue';
|
|
||||||
const $ = window.$;
|
const $ = window.$;
|
||||||
|
|
||||||
function CoderDepotReadme({ operate , history , readme , ChangeFile }){
|
function CoderDepotReadme({ operate , history , readme , ChangeFile }){
|
||||||
const [ menuList ,setMenuList ] = useState(undefined);
|
const [ menuList ,setMenuList ] = useState(undefined);
|
||||||
const [ content ,setContent ] = useState(undefined);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(readme && readme.content){
|
if(readme && readme.content){
|
||||||
setContent(readme.content);
|
|
||||||
}else{
|
|
||||||
setContent(undefined);
|
|
||||||
}
|
|
||||||
},[readme])
|
|
||||||
|
|
||||||
useEffect(()=>{
|
|
||||||
let path = history.location.pathname;
|
let path = history.location.pathname;
|
||||||
const items = $.map($("#readme").find("h1,h2,h3,h4,h5,h6"), function (el, _) {
|
const items = $.map($("#readme").find("h1,h2,h3,h4,h5,h6"), function (el, _) {
|
||||||
const anchor = el.id;
|
const anchor = el.id;
|
||||||
const level = el.tagName.replace("H", "");
|
const level = el.tagName.replace("H", "");
|
||||||
const href = `#${anchor}`;
|
const href = `#${anchor}`;
|
||||||
return { href:`${href}`,text:el.textContent , level:level }
|
return { href:`${path}${href}`,text:el.textContent , level:level }
|
||||||
});
|
});
|
||||||
setMenuList(items);
|
setMenuList(items);
|
||||||
},[content])
|
}
|
||||||
|
},[readme])
|
||||||
|
|
||||||
function menu(){
|
function menu(){
|
||||||
if(menuList && menuList.length > 0){
|
if(menuList && menuList.length > 0){
|
||||||
|
let hash = history.location.hash;
|
||||||
return(
|
return(
|
||||||
<ReadmeCatelogue menuList={menuList} hash={history.location.hash}/>
|
<Menu className="menuslist">
|
||||||
|
{
|
||||||
|
menuList.map((item,key)=>{
|
||||||
|
return(
|
||||||
|
<Menu.Item key={item.id} className={decodeURI(hash).indexOf(item.text)>-1 ?"active":""}><Link to={`${item.href}`} style={{paddingLeft:`${item.level *10}px`}} title={item.text}>{item.text}</Link></Menu.Item>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Menu>
|
||||||
)
|
)
|
||||||
}else{
|
}else{
|
||||||
return <Spin />
|
return <Spin />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="commonBox readBox" id="readme">
|
<div className="commonBox" id="readme">
|
||||||
<Anchor offsetTop={70} targetOffset={160}>
|
<div className="commonBox-title">
|
||||||
<div className="commonBox-title boxTitle">
|
<Dropdown overlay={menu()}>
|
||||||
<AlignCenter>
|
<i className="iconfont icon-zhangjie1 font-16 color-grey-3 mr10"></i>
|
||||||
<Dropdown overlay={menu()} trigger={['hover']} overlayClassName="menuslist">
|
|
||||||
<span className="catelogue">
|
|
||||||
<i className="iconfont icon-muluicon font-12 mr5"></i>
|
|
||||||
<span>目录</span>
|
|
||||||
</span>
|
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
<span className="commonBox-title-read">README.md</span>
|
||||||
<span className="commonBox-title-read"><a href="#readme ">README.md</a></span>
|
|
||||||
|
|
||||||
</AlignCenter>
|
|
||||||
{
|
{
|
||||||
operate ?
|
operate ?
|
||||||
<a className="ml20 pull-right" onClick={() =>ChangeFile(readme && readme.path, false)}>
|
<a className="ml20 pull-right" onClick={() =>ChangeFile(readme && readme.path, false)}>
|
||||||
<i className="iconfont icon-a-bianji font-17 color-grey-6"></i>
|
<i className="iconfont icon-bianji6 font-16 color-blue"></i>
|
||||||
</a>
|
</a>
|
||||||
:""
|
:""
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</Anchor>
|
|
||||||
{
|
|
||||||
content &&
|
|
||||||
<div className="commonBox-info">
|
<div className="commonBox-info">
|
||||||
<RenderHtml className="break_word_comments imageLayerParent" value={content} url={history.location}/>
|
<RenderHtml className="break_word_comments imageLayerParent" value={readme && readme.content} url={history.location}/>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,14 @@ import { Dropdown , Menu , Icon , Tooltip , Spin } from 'antd';
|
||||||
import { truncateCommitId } from '../common/util';
|
import { truncateCommitId } from '../common/util';
|
||||||
import { getBranch } from '../GetData/getData';
|
import { getBranch } from '../GetData/getData';
|
||||||
import Nodata from '../Nodata';
|
import Nodata from '../Nodata';
|
||||||
import './list.scss';
|
import './list.css';
|
||||||
|
|
||||||
function turnbar(str){
|
|
||||||
if(str && str.length>0 && str.indexOf("/")>-1){
|
|
||||||
return str.replaceAll('/','%2F');
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
export default ((props)=>{
|
export default ((props)=>{
|
||||||
const [ data , setData ] =useState(undefined);
|
const [ data , setData ] =useState(undefined);
|
||||||
const [ isSpin , setIsSpin ] =useState(true);
|
const [ isSpin , setIsSpin ] =useState(true);
|
||||||
|
|
||||||
const { projectsId , owner } = props.match.params;
|
const { projectsId , owner } = props.match.params;
|
||||||
const { isManager , isDeveloper , projectDetail } = props;
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
getBranchs(projectsId, owner);
|
getBranchs(projectsId, owner);
|
||||||
},[projectsId])
|
},[projectsId])
|
||||||
|
@ -38,18 +32,15 @@ export default ((props)=>{
|
||||||
return(
|
return(
|
||||||
<li key={key}>
|
<li key={key}>
|
||||||
<div>
|
<div>
|
||||||
<Link to={`/${owner}/${projectsId}/tree/${turnbar(item.name)}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
<Link to={`/projects/${owner}/${projectsId}/tree/${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||||
<p className="f-wrap-alignCenter mt15">
|
<p className="f-wrap-alignCenter mt15">
|
||||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.last_commit.sha}`)}`} className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</Link>
|
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.last_commit.sha}`)}`} className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</Link>
|
||||||
<span className="color-grey-3 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
<span className="color-grey-3 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
||||||
<span className="color-grey-8 ml30">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
<span className="color-grey-8 ml30">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<span>
|
<span>
|
||||||
{
|
<Link to={`/projects/${owner}/${projectsId}/pulls/new`} className="mr20 color-blue mr30">创建合并请求</Link>
|
||||||
(isManager || isDeveloper) && (projectDetail && projectDetail.type!==2) &&
|
|
||||||
<Link to={`/${owner}/${projectsId}/pulls/new/${item.name}`} className="mr20 color-blue mr30">创建合并请求</Link>
|
|
||||||
}
|
|
||||||
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="color-green-file">
|
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="color-green-file">
|
||||||
<a className="ant-dropdown-link">
|
<a className="ant-dropdown-link">
|
||||||
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
|
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
|
||||||
|
@ -73,7 +64,6 @@ export default ((props)=>{
|
||||||
<Menu.Item key={'1'}><a href={tar_url}>TAR.GZ</a></Menu.Item>
|
<Menu.Item key={'1'}><a href={tar_url}>TAR.GZ</a></Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className="main">
|
<div className="main">
|
||||||
|
|
|
@ -1,36 +1,21 @@
|
||||||
import React , { Component } from 'react';
|
import React , { Component } from 'react';
|
||||||
import { Spin , Pagination, Timeline } from 'antd';
|
import { Spin , Pagination } from 'antd';
|
||||||
import { getImageUrl } from 'educoder';
|
import { getImageUrl } from 'educoder';
|
||||||
import { truncateCommitId ,timeFormat } from '../common/util';
|
import { truncateCommitId } from '../common/util';
|
||||||
import { AlignTop } from '../Component/layout';
|
|
||||||
import SelectBranch from '../Branch/Select';
|
import SelectBranch from '../Branch/Select';
|
||||||
import Nodata from '../Nodata';
|
import Nodata from '../Nodata';
|
||||||
|
|
||||||
import User from '../Component/User';
|
|
||||||
import RenderHtml from '../../components/render-html.jsx';
|
|
||||||
import Tree from './img/tree.png';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import {Link} from "react-router-dom";
|
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){
|
|
||||||
return str.replaceAll('%2F','/');
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
//代码库--提交页面
|
|
||||||
class CoderRootCommit extends Component{
|
class CoderRootCommit extends Component{
|
||||||
constructor(props){
|
constructor(props){
|
||||||
super(props);
|
super(props)
|
||||||
this.state={
|
this.state={
|
||||||
commitDatas:undefined,
|
commitDatas:undefined,
|
||||||
dataCount:undefined,
|
dataCount:undefined,
|
||||||
limit:10,
|
limit:20,
|
||||||
page: 1,
|
page:1,
|
||||||
isSpining:false,
|
isSpining:false,
|
||||||
branchList:undefined
|
branchList:undefined
|
||||||
}
|
}
|
||||||
|
@ -58,28 +43,13 @@ class CoderRootCommit extends Component{
|
||||||
this.Init();
|
this.Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UrlParamHash(url){
|
|
||||||
const params = {};
|
|
||||||
let h;
|
|
||||||
let hash = url.slice(url.indexOf('?')+1).split('&');
|
|
||||||
for(let i = 0; i<hash.length;i++){
|
|
||||||
h = hash[i].split('=');
|
|
||||||
params[h[0]] = h[1];
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
Init =()=>{
|
Init =()=>{
|
||||||
const { branchName } = this.props.match.params;
|
const { branchName } = this.props.match.params;
|
||||||
const { limit } = this.state;
|
const { page , limit } = this.state;
|
||||||
const {search} = this.props.location;
|
|
||||||
const realPage = (search && this.UrlParamHash(search).page) ? parseInt(this.UrlParamHash(search).page) : 1;
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isSpining:true,
|
isSpining:true
|
||||||
page:realPage
|
|
||||||
})
|
})
|
||||||
this.getCommitList( branchName , realPage , limit );
|
this.getCommitList( branchName , page , limit );
|
||||||
}
|
}
|
||||||
|
|
||||||
getCommitList=(branch , page , limit)=>{
|
getCommitList=(branch , page , limit)=>{
|
||||||
|
@ -90,7 +60,7 @@ class CoderRootCommit extends Component{
|
||||||
const url = `/${owner}/${projectsId}/commits.json`;
|
const url = `/${owner}/${projectsId}/commits.json`;
|
||||||
axios.get(url,{
|
axios.get(url,{
|
||||||
params:{
|
params:{
|
||||||
sha:returnbar(branch),
|
sha:branch,
|
||||||
page,
|
page,
|
||||||
limit
|
limit
|
||||||
}
|
}
|
||||||
|
@ -108,8 +78,7 @@ class CoderRootCommit extends Component{
|
||||||
image_url:item.author && item.author.image_url,
|
image_url:item.author && item.author.image_url,
|
||||||
sha:item.sha,
|
sha:item.sha,
|
||||||
time_from_now:item.time_from_now,
|
time_from_now:item.time_from_now,
|
||||||
message:item.message,
|
message:item.message
|
||||||
timestamp:item.timestamp
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -124,18 +93,19 @@ class CoderRootCommit extends Component{
|
||||||
// 切换分支 search:tag为根据标签搜索
|
// 切换分支 search:tag为根据标签搜索
|
||||||
changeBranch=(value)=>{
|
changeBranch=(value)=>{
|
||||||
const { projectsId , owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
this.props.history.push(`/${owner}/${projectsId}/commits/branch/${value}`);
|
this.props.history.push(`/projects/${owner}/${projectsId}/commits/branch/${value}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChangePage=(page)=>{
|
ChangePage=(page)=>{
|
||||||
this.props.history.push({pathname: this.props.history.location.pathname,search: `page=${page}`})
|
const { branchName } = this.props.match.params;
|
||||||
|
const { limit } = this.state;
|
||||||
|
this.getCommitList(branchName , page , limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const { commitDatas , dataCount , limit , page , isSpining , branchList } = this.state;
|
const { commitDatas , dataCount , limit , page , isSpining , branchList } = this.state;
|
||||||
const { projectDetail, commit_class , defaultBranch } = this.props;
|
const { projectDetail, commit_class , defaultBranch } = this.props;
|
||||||
const { projectsId , owner , branchName } = this.props.match.params;
|
const { projectsId , owner , branchName } = this.props.match.params;
|
||||||
let branch = returnbar(branchName || defaultBranch);
|
let branch = branchName || defaultBranch;
|
||||||
return(
|
return(
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className={"main"}style={{padding:"0px",border:"none"}}>
|
<div className={"main"}style={{padding:"0px",border:"none"}}>
|
||||||
|
@ -151,50 +121,46 @@ class CoderRootCommit extends Component{
|
||||||
></SelectBranch>
|
></SelectBranch>
|
||||||
</div>
|
</div>
|
||||||
<Spin spinning={isSpining}>
|
<Spin spinning={isSpining}>
|
||||||
<Timeline className="commitList">
|
<div className="commonBox">
|
||||||
|
<div className="commonBox-title">
|
||||||
|
<div className="f-wrap-between" style={{alignItems:"center"}}>
|
||||||
|
<span className="font-16">{dataCount}次提交代码({branch})</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="commitList">
|
||||||
{
|
{
|
||||||
commitDatas && commitDatas.length > 0 && commitDatas.map((item,k)=>{
|
commitDatas && commitDatas.length > 0 && commitDatas.map((item,k)=>{
|
||||||
return(
|
return(
|
||||||
<Timeline.Item key={k} dot={page ===1 && k===0 ?<span className="new-conmmit">最新</span>:<i className="iconfont icon-a-yuanquan2x"></i>}>
|
<div key={k}>
|
||||||
<div className="commitList-item f-wrap-between">
|
<p className="f-wrap-alignCenter">
|
||||||
<div>
|
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</Link>
|
||||||
<AlignTop>
|
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="flex1 ml20 font-16 color-grey-3">{item.message}</Link>
|
||||||
<div className="commitDesc"><Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="font-14 color-grey-3 font-bd"><RenderHtml value={item.message}/></Link></div>
|
</p>
|
||||||
</AlignTop>
|
<p className="f-wrap-alignCenter mt15">
|
||||||
<p className="f-wrap-alignCenter mt15 pb5">
|
{
|
||||||
<User
|
item.id ?
|
||||||
id={item.id}
|
<Link to={`/users/${item.login}`} className="show-user-link">
|
||||||
url={(item.image_url && getImageUrl(`/${item.image_url}`)) || "https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"}
|
{item.image_url?<img src={getImageUrl(`/${item.image_url}`)} alt="" width="28px" height="28px" className="mr15 radius"/>:""}
|
||||||
name={item.name}
|
<label className="font-14 color-grey-6" style={{verticalAlign:'middle'}}>{item.name ?`${item.name}:`:""}提交于 {item.time_from_now}</label>
|
||||||
login={item.login}
|
</Link>:
|
||||||
/>
|
<span className="show-user-link">
|
||||||
{item.timestamp && <label className="font-14 color-grey-3 ml3">提交于 {timeFormat(item.timestamp)}</label>}
|
{item.image_url?<img src={getImageUrl(`/${item.image_url}`)} alt="" width="28px" height="28px" className="mr15 radius"/>:""}
|
||||||
|
<label className="font-14 color-grey-6" style={{verticalAlign:'middle'}}>{item.name ?`${item.name}:`:""}提交于 {item.time_from_now}</label>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<div className="treecopy">
|
|
||||||
<div>
|
|
||||||
<span className="treecopy-cont shadow">
|
|
||||||
<img src={Tree} alt="sha" width={"16px"}/>
|
|
||||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`}>{truncateCommitId(`${item.sha}`)}</Link>
|
|
||||||
<input type="text" id={`value${k}`} value={`${truncateCommitId(`${item.sha}`)}`}/>
|
|
||||||
</span>
|
|
||||||
<CopyTool beforeText="复制commit id" afterText="复制成功" inputId={`value${k}`}/>
|
|
||||||
</div>
|
|
||||||
<button className="btn-83" onClick={()=>{window.location.href=`/${owner}/${projectsId}/tree/${truncateCommitId(item.sha)}`}}>浏览文件</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Timeline.Item>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
{commitDatas && commitDatas.length === 0 && <Nodata _html="暂无数据"/>}
|
{commitDatas && commitDatas.length === 0 && <Nodata _html="暂无数据"/>}
|
||||||
</Timeline>
|
</div>
|
||||||
|
</div>
|
||||||
{
|
{
|
||||||
dataCount > limit ?
|
dataCount > limit ?
|
||||||
<div className="edu-txt-center pt30 mb30">
|
<div className="edu-txt-center pt30 mb30">
|
||||||
<Pagination simple current={page} total={dataCount} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
<Pagination simple defaultCurrent={page} total={dataCount} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||||
</div>
|
</div>
|
||||||
:""
|
:""
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { Popconfirm , Select , Dropdown , Spin , Anchor } from "antd";
|
import { Popconfirm , Select } from "antd";
|
||||||
import "./list.scss";
|
import "./list.css";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Meditor from "../Newfile/m_editor";
|
import Meditor from "../Newfile/m_editor";
|
||||||
import RenderHtml from "../../components/render-html";
|
import RenderHtml from "../../components/render-html";
|
||||||
import ReadmeCatelogue from "./sub/ReadmeCatelogue";
|
|
||||||
|
|
||||||
const $ = window.$;
|
|
||||||
function bytesToSize(bytes) {
|
function bytesToSize(bytes) {
|
||||||
if (bytes === 0) return "0 B";
|
if (bytes === 0) return "0 B";
|
||||||
let k = 1024,
|
let k = 1024,
|
||||||
|
@ -21,13 +19,11 @@ class CoderRootFileDetail extends Component {
|
||||||
value: undefined,
|
value: undefined,
|
||||||
language: undefined,
|
language: undefined,
|
||||||
languages: undefined,
|
languages: undefined,
|
||||||
description: props.detail.content,
|
description: props.detail.content
|
||||||
menuList:undefined
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount = () => {
|
componentDidMount = () => {
|
||||||
window.scrollTo(0, 0);
|
|
||||||
const { detail , mdFlag } = this.props;
|
const { detail , mdFlag } = this.props;
|
||||||
this.setState({
|
this.setState({
|
||||||
value: detail.content,
|
value: detail.content,
|
||||||
|
@ -153,7 +149,7 @@ class CoderRootFileDetail extends Component {
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.props.showNotification("删除成功!");
|
this.props.showNotification("删除成功!");
|
||||||
this.props.history.push(`/${owner}/${projectsId}`);
|
this.props.history.push(`/projects/${owner}/${projectsId}`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
@ -173,31 +169,6 @@ 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(
|
|
||||||
<ReadmeCatelogue menuList={menuList} hash={this.props.history.location.hash}/>
|
|
||||||
)
|
|
||||||
}else{
|
|
||||||
return <Spin />
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
readOnly,
|
readOnly,
|
||||||
|
@ -215,18 +186,9 @@ class CoderRootFileDetail extends Component {
|
||||||
const Option = Select.Option;
|
const Option = Select.Option;
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Anchor className="griditemAnchor" offsetTop={70}>
|
<div className="grid-item branchTitle">
|
||||||
<div className="griditemCate">
|
<div className="grid-item">
|
||||||
{
|
<span className="ml20 color-grey-6 font-16">
|
||||||
md && readOnly &&
|
|
||||||
<Dropdown overlay={this.menu()} trigger={['hover']} overlayClassName="menuslist">
|
|
||||||
<span className="catelogue mr20">
|
|
||||||
<i className="iconfont icon-muluicon font-12 mr5"></i>
|
|
||||||
<span>目录</span>
|
|
||||||
</span>
|
|
||||||
</Dropdown>
|
|
||||||
}
|
|
||||||
<span className="color-grey-6 font-16">
|
|
||||||
{bytesToSize(detail && detail.size)}
|
{bytesToSize(detail && detail.size)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -296,7 +258,7 @@ class CoderRootFileDetail extends Component {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</Anchor>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{detail.image_type ? (
|
{detail.image_type ? (
|
||||||
<div className="edu-txt-center pt20 pb20">
|
<div className="edu-txt-center pt20 pb20">
|
||||||
|
@ -310,7 +272,7 @@ class CoderRootFileDetail extends Component {
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
md && readOnly ?
|
md && readOnly ?
|
||||||
<div className="files-md" id="files-md">
|
<div className="files-md">
|
||||||
<RenderHtml className="file-md imageLayerParent" value={description} url={this.props.history.location}/>
|
<RenderHtml className="file-md imageLayerParent" value={description} url={this.props.history.location}/>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
|
@ -323,7 +285,6 @@ class CoderRootFileDetail extends Component {
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
editorType="update"
|
editorType="update"
|
||||||
currentBranch={currentBranch}
|
currentBranch={currentBranch}
|
||||||
descName={detail && `Update ${detail.name}`}
|
|
||||||
></Meditor>
|
></Meditor>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React , { Component } from 'react';
|
import React , { Component } from 'react';
|
||||||
import { Route , Switch } from 'react-router-dom';
|
import { Route , Switch } from 'react-router-dom';
|
||||||
// import Top from './DetailTop';
|
import Top from './DetailTop';
|
||||||
import Loadable from 'react-loadable';
|
import Loadable from 'react-loadable';
|
||||||
import Loading from '../../Loading';
|
import Loading from '../../Loading';
|
||||||
import './Index.scss';
|
import axios from 'axios';
|
||||||
|
|
||||||
const FileNew = Loadable({
|
const FileNew = Loadable({
|
||||||
loader: () => import('../Newfile/Index'),
|
loader: () => import('../Newfile/Index'),
|
||||||
|
@ -18,25 +18,25 @@ const CoderRootCommit = Loadable({
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const CoderRootBranch = Loadable({
|
const CoderRootBranch = Loadable({
|
||||||
loader: () => import('./tree/Index'),
|
loader: () => import('./CoderRootBranch'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const CoderRootTag = Loadable({
|
const CoderRootTag = Loadable({
|
||||||
loader: () => import('./tag/Index'),
|
loader: () => import('./CoderRootTag'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
const CoderRootVersion = Loadable({
|
const CoderRootVersion = Loadable({
|
||||||
loader: () => import('./version/Index'),
|
loader: () => import('../Version/version'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const CoderRootVersionNew = Loadable({
|
||||||
|
loader: () => import('../Version/New'),
|
||||||
|
loading: Loading,
|
||||||
|
})
|
||||||
|
const CoderRootVersionUpdate = Loadable({
|
||||||
|
loader: () => import('../Version/New'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
// const CoderRootVersionNew = Loadable({
|
|
||||||
// loader: () => import('./version/New'),
|
|
||||||
// loading: Loading,
|
|
||||||
// })
|
|
||||||
// const CoderRootVersionUpdate = Loadable({
|
|
||||||
// loader: () => import('./version/New'),
|
|
||||||
// loading: Loading,
|
|
||||||
// })
|
|
||||||
const Diff = Loadable({
|
const Diff = Loadable({
|
||||||
loader: () => import('./Diff'),
|
loader: () => import('./Diff'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
|
@ -50,94 +50,89 @@ class CoderRootIndex extends Component{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// componentDidMount=()=>{
|
componentDidMount=()=>{
|
||||||
// this.Init();
|
this.Init();
|
||||||
// }
|
}
|
||||||
// componentDidUpdate=(prevProps)=>{
|
componentDidUpdate=(prevProps)=>{
|
||||||
// const { location } = this.props;
|
const { location } = this.props;
|
||||||
// const prevlocation = prevProps && prevProps.location;
|
const prevlocation = prevProps && prevProps.location;
|
||||||
// if (location !== prevlocation) {
|
if (location !== prevlocation) {
|
||||||
// this.Init();
|
this.Init();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Init=()=>{
|
Init=()=>{
|
||||||
// const { branchName } = this.props.match.params;
|
const { branchName } = this.props.match.params;
|
||||||
// const { defaultBranch } = this.props;
|
const { defaultBranch } = this.props;
|
||||||
// this.getTopCount(branchName || defaultBranch);
|
this.getTopCount(branchName || defaultBranch);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// 获取<Top />组件里要显示的数据
|
// 获取<Top />组件里要显示的数据
|
||||||
// getTopCount=(branch)=>{
|
getTopCount=(branch)=>{
|
||||||
// const { projectsId , owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
// const url = `/${owner}/${projectsId}/top_counts.json`;
|
const url = `/${owner}/${projectsId}/top_counts.json`;
|
||||||
// axios.get(url,{params:{
|
axios.get(url,{params:{
|
||||||
// ref:branch
|
ref:branch
|
||||||
// }}).then(result=>{
|
}}).then(result=>{
|
||||||
// if(result){
|
if(result){
|
||||||
// this.setState({
|
this.setState({
|
||||||
// coderCount:result.data
|
coderCount:result.data
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
// }).catch(error=>{console.log(error);})
|
}).catch(error=>{console.log(error);})
|
||||||
// }
|
}
|
||||||
render(){
|
render(){
|
||||||
return(
|
return(
|
||||||
<div className="coderSubPage">
|
<div>
|
||||||
{/* <Top {...this.props} {...this.state}/> */}
|
<Top {...this.props} {...this.state}/>
|
||||||
<Switch {...this.props}>
|
<Switch {...this.props}>
|
||||||
{/* 新建文件 */}
|
{/* 新建文件 */}
|
||||||
<Route path="/:owner/:projectsId/:branch/newfile/:path"
|
<Route path="/projects/:owner/:projectsId/:branch/newfile/:path"
|
||||||
render={
|
render={
|
||||||
(props) => (<FileNew {...this.props} {...props} {...this.state} />)
|
(props) => (<FileNew {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/:branch/uploadfile"
|
<Route path="/projects/:owner/:projectsId/:branch/uploadfile"
|
||||||
render={
|
render={
|
||||||
(props) => (<UploadFile {...this.props} {...props} {...this.state} />)
|
(props) => (<UploadFile {...this.props} {...props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/:branch/newfile"
|
<Route path="/projects/:owner/:projectsId/:branch/newfile"
|
||||||
render={
|
render={
|
||||||
(props) => (<FileNew {...this.props} {...props} {...this.state} />)
|
(props) => (<FileNew {...this.props} {...props} {...this.state} getTopCount={this.getTopCount} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/commits/branch/:branchName"
|
<Route path="/projects/:owner/:projectsId/commits/:sha"
|
||||||
render={
|
|
||||||
() => (<CoderRootCommit {...this.props} {...this.state} commit_class="main" />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
<Route path="/:owner/:projectsId/commits/:sha"
|
|
||||||
render={
|
render={
|
||||||
(props) => (<Diff {...this.props} {...props} {...this.state}/>)
|
(props) => (<Diff {...this.props} {...props} {...this.state}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/commits"
|
<Route path="/projects/:owner/:projectsId/commits"
|
||||||
render={
|
render={
|
||||||
() => (<CoderRootCommit {...this.props} {...this.state} commit_class="main" />)
|
() => (<CoderRootCommit {...this.props} {...this.state} commit_class="main" getTopCount={this.getTopCount} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* <Route path="/:owner/:projectsId/releases/:versionId/update"
|
<Route path="/projects/:owner/:projectsId/releases/:versionId/update"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootVersionUpdate {...this.props} {...this.state} {...props} />)
|
(props) => (<CoderRootVersionUpdate {...this.props} {...this.state} {...props} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/releases/new"
|
<Route path="/projects/:owner/:projectsId/releases/new"
|
||||||
render={
|
render={
|
||||||
() => (<CoderRootVersionNew {...this.props} {...this.state} />)
|
() => (<CoderRootVersionNew {...this.props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route> */}
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/releases"
|
<Route path="/projects/:owner/:projectsId/releases"
|
||||||
render={
|
render={
|
||||||
() => (<CoderRootVersion {...this.props} {...this.state} />)
|
() => (<CoderRootVersion {...this.props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/tags"
|
<Route path="/projects/:owner/:projectsId/tag"
|
||||||
render={
|
render={
|
||||||
() => (<CoderRootTag {...this.props} {...this.state} />)
|
() => (<CoderRootTag {...this.props} {...this.state} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/branches"
|
<Route path="/projects/:owner/:projectsId/branchs"
|
||||||
render={
|
render={
|
||||||
() => (<CoderRootBranch {...this.props} {...this.state} />)
|
() => (<CoderRootBranch {...this.props} {...this.state} />)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default (( props, { projectDetail }) => {
|
||||||
}, [owner, projectsId]);
|
}, [owner, projectsId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="main" style={{padding:"0px",border:"none"}}>
|
<div className="main">
|
||||||
<Spin spinning={isSpin}>
|
<Spin spinning={isSpin}>
|
||||||
<div style={{minHeight:"400px"}}>
|
<div style={{minHeight:"400px"}}>
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ export default (( props, { projectDetail }) => {
|
||||||
<div className="div_table">
|
<div className="div_table">
|
||||||
<ul className="ul_thead">
|
<ul className="ul_thead">
|
||||||
<li>
|
<li>
|
||||||
<span className="flex1">标记名</span>
|
<span className="flex1">标签名</span>
|
||||||
<span>提交信息</span>
|
<span>提交信息</span>
|
||||||
<span className="ul_tbody_forth">下载</span>
|
<span className="ul_tbody_forth">下载</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -49,7 +49,7 @@ export default (( props, { projectDetail }) => {
|
||||||
<span className="font-16">{item.name}</span>
|
<span className="font-16">{item.name}</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="ul_tbody_third">
|
<span className="ul_tbody_third">
|
||||||
<Link to={`/${owner}/${projectsId}/commits/${truncateCommitId(`${item.id}`)}`} className="commitKey" style={{ "marginLeft": 0 }}>{truncateCommitId(`${item.id}`)}</Link>
|
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.id}`)}`} className="commitKey" style={{ "marginLeft": 0 }}>{truncateCommitId(`${item.id}`)}</Link>
|
||||||
</span>
|
</span>
|
||||||
<span className="ul_tbody_forth">
|
<span className="ul_tbody_forth">
|
||||||
<a href={item.tarball_url} style={{ color: "#4CC1DA" }} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
<a href={item.tarball_url} style={{ color: "#4CC1DA" }} className="mr30"><i className="iconfont icon-TAR font-18 mr5"></i>TAR</a>
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Spin, Tooltip } from 'antd';
|
import { Spin, Tooltip } from 'antd';
|
||||||
import { Link, Route, Switch } from 'react-router-dom';
|
import { Link, Route, Switch } from 'react-router-dom';
|
||||||
import { Content, AlignTop } from '../Component/layout';
|
import { Content } from '../Component/layout';
|
||||||
import DetailBanner from './sub/DetailBanner';
|
import DetailBanner from './sub/DetailBanner';
|
||||||
import { numFormat } from 'educoder';
|
|
||||||
import '../css/index.scss'
|
import '../css/index.scss'
|
||||||
import './list.scss';
|
import './list.css';
|
||||||
|
|
||||||
import { ImageLayerOfCommentHOC } from "../../modules/page/layers/ImageLayerOfCommentHOC";
|
|
||||||
|
|
||||||
|
|
||||||
import Loadable from 'react-loadable';
|
import Loadable from 'react-loadable';
|
||||||
import Loading from '../../Loading';
|
import Loading from '../../Loading';
|
||||||
|
@ -71,7 +67,7 @@ const MergeIndexDetail = Loadable({
|
||||||
})
|
})
|
||||||
|
|
||||||
const CreateMerge = Loadable({
|
const CreateMerge = Loadable({
|
||||||
loader: () => import('../Merge/CreateMerge'),
|
loader: () => import('../Merge/NewMerge'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -131,42 +127,30 @@ const Source = Loadable({
|
||||||
const DevIndex = Loadable({
|
const DevIndex = Loadable({
|
||||||
loader: () => import('../DevOps/Index'),
|
loader: () => import('../DevOps/Index'),
|
||||||
loading: Loading,
|
loading: Loading,
|
||||||
});
|
})
|
||||||
const Wiki = Loadable({
|
|
||||||
loader: () => import('../Wiki/Index'),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
const WikiEdit = Loadable({
|
|
||||||
loader: () => import('../Wiki/EditWiki'),
|
|
||||||
loading: Loading,
|
|
||||||
});
|
|
||||||
/**
|
/**
|
||||||
* permission:Manager:管理员,Reporter:报告人员(只有读取权限),Developer:开发人员(除不能设置仓库信息外)
|
* permission:Manager:管理员,Reporter:报告人员(只有读取权限),Developer:开发人员(除不能设置仓库信息外)
|
||||||
*/
|
*/
|
||||||
function checkPathname(projectsId, owner, pathname) {
|
function checkPathname(projectsId,owner,pathname){
|
||||||
let name = "";
|
let name = "";
|
||||||
if (pathname && pathname !== `/${owner}/${projectsId}`) {
|
if(pathname && pathname !== `/projects/${owner}/${projectsId}`){
|
||||||
let url = pathname.split(`/${owner}/${projectsId}`)[1] || "";
|
let url = pathname.split(`/projects/${owner}/${projectsId}`)[1];
|
||||||
if (url.indexOf("/about") > -1) {
|
if(url.indexOf("/about")>-1){
|
||||||
name = "about"
|
name="about"
|
||||||
} else if (url.indexOf("/issues") > -1 || url.indexOf("Milepost") > 0) {
|
}else if(url.indexOf("/issues")>-1 ||url.indexOf("Milepost") > 0){
|
||||||
name = "issues";
|
name = "issues";
|
||||||
} else if (url.indexOf("/pulls") > -1 || url.indexOf("/compare") > -1) {
|
}else if(url.indexOf("/pulls")>-1){
|
||||||
// /pulls,合并请求除新建合并请求外,
|
name="pulls"
|
||||||
// /compare,新建合并请求
|
}else if(url.indexOf("/milestones")>-1){
|
||||||
name = "pulls"
|
name="milestones"
|
||||||
} else if (url.indexOf("/milestones") > -1) {
|
}else if(url.indexOf("/activity")>-1){
|
||||||
name = "milestones"
|
name="activity"
|
||||||
} else if (url.indexOf("/activity") > -1) {
|
}else if(url.indexOf("/setting")>-1){
|
||||||
name = "activity"
|
name="setting"
|
||||||
} else if (url.indexOf("/settings") > -1) {
|
}else if(url.indexOf(`/devops`)>-1){
|
||||||
name = "settings"
|
name="devops"
|
||||||
} else if (url.indexOf(`/devops`) > -1) {
|
}else if(url.indexOf(`/source`)>-1){
|
||||||
name = "devops"
|
name="source"
|
||||||
} else if (url.indexOf(`/source`) > -1) {
|
|
||||||
name = "source"
|
|
||||||
} else if (url.indexOf(`/wiki`) > -1) {
|
|
||||||
name = "wiki"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
|
@ -189,15 +173,14 @@ class Detail extends Component {
|
||||||
branchs: undefined,
|
branchs: undefined,
|
||||||
branchList: undefined,
|
branchList: undefined,
|
||||||
project: null,
|
project: null,
|
||||||
firstSync: false,
|
firstSync:false,
|
||||||
secondSync: false,
|
secondSync:false,
|
||||||
open_devops: false,
|
open_devops:false,
|
||||||
forkSpin: false,
|
|
||||||
// 默认分支
|
// 默认分支
|
||||||
defaultBranch: undefined,
|
defaultBranch:undefined,
|
||||||
|
|
||||||
// 非本平台项目
|
// 非本平台项目
|
||||||
platform: false
|
platform:false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,38 +197,36 @@ class Detail extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
getProject = (num) => {
|
getProject = (num) => {
|
||||||
const { projectsId, owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
const url = `/${owner}/${projectsId}/simple.json`;
|
const url = `/${owner}/${projectsId}/simple.json`;
|
||||||
axios.get(url).then((result) => {
|
axios.get(url).then((result) => {
|
||||||
if (result && result.data) {
|
if (result && result.data) {
|
||||||
this.setState({
|
this.setState({
|
||||||
project: result.data,
|
project: result.data,
|
||||||
open_devops: result.data.open_devops,
|
open_devops:result.data.open_devops,
|
||||||
platform: result.data.platform && result.data.platform !== 'educoder'
|
platform:result.data.platform && result.data.platform !== 'educoder'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (result.data.type !== 0 && result.data.mirror_status === 1) {
|
if (result.data.type !== 0 && result.data.mirror_status === 1) {
|
||||||
console.log("--------start channel --------");
|
console.log("--------start channel --------");
|
||||||
// 是镜像项目,且未完成迁移
|
// 是镜像项目,且未完成迁移
|
||||||
this.canvasChannel();
|
this.canvasChannel();
|
||||||
if (num) {
|
if(num){
|
||||||
this.setState({
|
this.setState({
|
||||||
secondSync: true,
|
secondSync:true,
|
||||||
firstSync: false
|
firsrtSync:false
|
||||||
})
|
})
|
||||||
} else {
|
}else{
|
||||||
this.setState({
|
this.setState({
|
||||||
firstSync: true,
|
firstSync:true,
|
||||||
secondSync: false
|
secondSync:false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (result.data.mirror_status === 2) {
|
}else{
|
||||||
this.deleteProjectBack();
|
|
||||||
} else {
|
|
||||||
this.getDetail();
|
this.getDetail();
|
||||||
this.setState({
|
this.setState({
|
||||||
firstSync: false,
|
firsrtSync:false,
|
||||||
secondSync: false
|
secondSync:false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,23 +234,19 @@ class Detail extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 工作流激活后修改状态
|
// 工作流激活后修改状态
|
||||||
changeOpenDevops = (flag) => {
|
changeOpenDevops=(flag)=>{
|
||||||
this.setState({
|
this.setState({
|
||||||
open_devops: flag
|
open_devops:flag
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/**
|
canvasChannel = () => {
|
||||||
*
|
|
||||||
* @param {*} deleteFlag :同步镜像需要提示成功,且未成功的情况下不需要删除项目
|
|
||||||
*/
|
|
||||||
canvasChannel = (deleteFlag) => {
|
|
||||||
const name = window.location.hostname === "localhost" ? "testforgeplus.trustie.net" : window.location.hostname;
|
const name = window.location.hostname === "localhost" ? "testforgeplus.trustie.net" : window.location.hostname;
|
||||||
const actioncable = require("actioncable");
|
const actioncable = require("actioncable");
|
||||||
var project = this.state.project;
|
var project = this.state.project;
|
||||||
var cable = actioncable.createConsumer(`wss://${name}/cable`);
|
var cable = actioncable.createConsumer(`wss://${name}/cable`);
|
||||||
this.canvasChannel1 = cable.subscriptions.create({
|
this.canvasChannel1 = cable.subscriptions.create({
|
||||||
channel: `MirrorProjectChannel`,
|
channel: `MirrorProjectChannel`,
|
||||||
id: project && project.id
|
id: project && project.identifier
|
||||||
}, {
|
}, {
|
||||||
connected: () => {
|
connected: () => {
|
||||||
console.log("###### channel connected! ######");
|
console.log("###### channel connected! ######");
|
||||||
|
@ -277,53 +254,20 @@ class Detail extends Component {
|
||||||
disconnected: () => { },
|
disconnected: () => { },
|
||||||
received: data => {
|
received: data => {
|
||||||
console.log(`###### ---received data--- ######`);
|
console.log(`###### ---received data--- ######`);
|
||||||
console.log(data);
|
|
||||||
if (data) {
|
if (data) {
|
||||||
if(deleteFlag){
|
|
||||||
this.props.showNotification("镜像同步成功!");
|
|
||||||
window.location.reload();
|
|
||||||
}else{
|
|
||||||
if (data.project && data.project.mirror_status === 2) {
|
|
||||||
this.deleteProjectBack();
|
|
||||||
}
|
|
||||||
this.getDetail();
|
this.getDetail();
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
firstSync: false,
|
|
||||||
secondSync: false
|
|
||||||
});
|
|
||||||
cable.subscriptions.consumer.disconnect();
|
cable.subscriptions.consumer.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteProjectBack = () => {
|
|
||||||
const { history } = this.props;
|
|
||||||
const { projectsId, owner } = this.props.match.params;
|
|
||||||
axios.delete(`/${owner}/${projectsId}.json`).then(res => {
|
|
||||||
let hash = '/projects/mirror/new';
|
|
||||||
if (res && res.data) {
|
|
||||||
history.push({
|
|
||||||
pathname: hash,
|
|
||||||
mirror_status: 2
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
window.location.hash = hash;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getDetail = () => {
|
getDetail = () => {
|
||||||
const { projectsId, owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
this.getBanner();
|
this.getBanner();
|
||||||
const url = `/${owner}/${projectsId}/detail.json`;
|
const url = `/${owner}/${projectsId}/detail.json`;
|
||||||
axios.get(url).then((result) => {
|
axios.get(url).then((result) => {
|
||||||
if (result && result.data) {
|
if (result && result.data) {
|
||||||
if (result.data.status === 404) {
|
|
||||||
this.props.history.push('/nopage');
|
|
||||||
}
|
|
||||||
this.setState({
|
this.setState({
|
||||||
projectDetail: result.data,
|
projectDetail: result.data,
|
||||||
project_id: result.data.project_id,
|
project_id: result.data.project_id,
|
||||||
|
@ -336,29 +280,29 @@ class Detail extends Component {
|
||||||
watchers_count: result.data.watchers_count,
|
watchers_count: result.data.watchers_count,
|
||||||
praises_count: result.data.praises_count,
|
praises_count: result.data.praises_count,
|
||||||
forked_count: result.data.forked_count,
|
forked_count: result.data.forked_count,
|
||||||
defaultBranch: result.data.default_branch
|
defaultBranch:result.data.default_branch
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch((error) => { })
|
}).catch((error) => { })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取动态导航栏菜单
|
// 获取动态导航栏菜单
|
||||||
getBanner() {
|
getBanner(){
|
||||||
const { projectsId, owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
const url = `/${owner}/${projectsId}/menu_list.json`;
|
const url = `/${owner}/${projectsId}/menu_list.json`;
|
||||||
axios.get(url).then(result => {
|
axios.get(url).then(result=>{
|
||||||
if (result) {
|
if(result){
|
||||||
this.setState({
|
this.setState({
|
||||||
bannerList: result.data
|
bannerList:result.data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch(error => { })
|
}).catch(error=>{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关注和取消关注
|
// 关注和取消关注
|
||||||
focusFunc = (flag) => {
|
focusFunc = (flag) => {
|
||||||
const { platform } = this.state;
|
const { platform } = this.state;
|
||||||
if (!platform) return;
|
if(!platform)return;
|
||||||
|
|
||||||
const { project_id } = this.state;
|
const { project_id } = this.state;
|
||||||
axios({
|
axios({
|
||||||
|
@ -381,7 +325,7 @@ class Detail extends Component {
|
||||||
// 点赞和取消点赞
|
// 点赞和取消点赞
|
||||||
pariseFunc = (flag) => {
|
pariseFunc = (flag) => {
|
||||||
const { platform } = this.state;
|
const { platform } = this.state;
|
||||||
if (!platform) return;
|
if(!platform)return;
|
||||||
const { project_id } = this.state;
|
const { project_id } = this.state;
|
||||||
axios({
|
axios({
|
||||||
method: flag ? 'delete' : 'post',
|
method: flag ? 'delete' : 'post',
|
||||||
|
@ -413,40 +357,30 @@ class Detail extends Component {
|
||||||
// fork项目
|
// fork项目
|
||||||
forkFunc = () => {
|
forkFunc = () => {
|
||||||
const { platform } = this.state;
|
const { platform } = this.state;
|
||||||
if (!platform) return;
|
if(!platform)return;
|
||||||
this.setState({
|
|
||||||
forkSpin: true
|
|
||||||
})
|
|
||||||
const { current_user } = this.props
|
const { current_user } = this.props
|
||||||
const { projectsId, owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
const url = `/${owner}/${projectsId}/forks.json`;
|
const url = `/${owner}/${projectsId}/forks.json`;
|
||||||
axios.post(url).then(result => {
|
axios.post(url).then(result => {
|
||||||
if (result && result.data.status === 0) {
|
if (result && result.data.status === 0) {
|
||||||
this.props.history.push(`/${current_user && current_user.login}/${result.data.identifier}`);
|
this.props.history.push(`/projects/${current_user && current_user.login}/${result.data.identifier}`);
|
||||||
this.props.showNotification(result.data.message);
|
this.props.showNotification(result.data.message);
|
||||||
}
|
}
|
||||||
this.setState({
|
|
||||||
forkSpin: false
|
|
||||||
})
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.setState({
|
console.log(error);
|
||||||
forkSpin: false
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 同步镜像
|
// 同步镜像
|
||||||
synchronismMirror = () => {
|
synchronismMirror = () => {
|
||||||
const { platform } = this.state;
|
const { platform } = this.state;
|
||||||
if (!platform) return;
|
if(!platform)return;
|
||||||
const { projectsId, owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
const url = `/${owner}/${projectsId}/sync_mirror.json`;
|
const url = `/${owner}/${projectsId}/sync_mirror.json`;
|
||||||
axios.post(url).then(result => {
|
axios.post(url).then(result => {
|
||||||
if (result && result.data && result.data.status === 0) {
|
if (result && result.data && result.data.status === 0) {
|
||||||
this.setState({
|
this.props.showNotification("镜像同步成功!");
|
||||||
secondSync:true
|
this.getProject(2);
|
||||||
})
|
|
||||||
this.canvasChannel(true);
|
|
||||||
} else {
|
} else {
|
||||||
this.props.showNotification("镜像同步失败!");
|
this.props.showNotification("镜像同步失败!");
|
||||||
}
|
}
|
||||||
|
@ -455,139 +389,132 @@ class Detail extends Component {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
textFunc = (forked_from_project_id, fork_info) => {
|
|
||||||
let type = fork_info && fork_info.fork_project_user_type;
|
|
||||||
return forked_from_project_id && fork_info ?
|
|
||||||
<div className="color-grey-9 df">
|
|
||||||
<span>复刻自</span>
|
|
||||||
<Link to={`/${fork_info.fork_project_user_login}`} className="show-user-link color-grey-6 ml5">{fork_info.fork_project_user_name}</Link>
|
|
||||||
<span> / </span>
|
|
||||||
<Link to={`/${fork_info.fork_project_user_login}/${fork_info.fork_project_identifier}`} className="color-grey-6 task-hide flex1" style={{ maxWidth: "400px" }} title={fork_info.fork_form_name}>{fork_info.fork_form_name}</Link>
|
|
||||||
</div> : ""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { projectDetail, watchers_count, praises_count,
|
const { projectDetail, watchers_count, praises_count,
|
||||||
forked_count, firstSync, secondSync,
|
forked_count, firstSync , secondSync ,
|
||||||
isManager, watched, praised,
|
isManager, watched, praised,
|
||||||
project, open_devops, platform, defaultBranch, bannerList, forkSpin } = this.state;
|
project , open_devops , platform , defaultBranch , bannerList } = this.state;
|
||||||
const url = this.props.history.location.pathname;
|
const url = this.props.history.location.pathname;
|
||||||
const urlArr = url.split("/");
|
const urlArr = url.split("/");
|
||||||
const urlFlag = (urlArr.length === 3);
|
const urlFlag = (urlArr.length === 3);
|
||||||
|
|
||||||
const { projectsId, owner } = this.props.match.params;
|
const { projectsId , owner } = this.props.match.params;
|
||||||
const { current_user } = this.props;
|
let pathname = checkPathname(projectsId,owner,url);
|
||||||
let pathname = checkPathname(projectsId, owner, url);
|
|
||||||
|
|
||||||
const { state } = this.props.history.location;
|
const { state } = this.props.history.location;
|
||||||
|
|
||||||
|
const text = (
|
||||||
|
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||||
|
<React.Fragment>
|
||||||
|
<span>forked from </span>
|
||||||
|
<Link to={`/users/${projectDetail.fork_info.fork_project_user_login}`} className="show-user-link color-grey-ccc">{projectDetail.fork_info.fork_project_user_name}</Link>
|
||||||
|
<span> / </span>
|
||||||
|
<Link to={`/projects/${projectDetail.fork_info.fork_project_user_login}/${projectDetail.fork_info.fork_project_identifier}`} className="color-grey-ccc">{projectDetail.fork_info.fork_form_name}</Link>
|
||||||
|
</React.Fragment> : ""
|
||||||
|
);
|
||||||
|
|
||||||
const common = {
|
const common = {
|
||||||
getDetail: this.getDetail,
|
getDetail: this.getDetail,
|
||||||
changeOpenDevops: this.changeOpenDevops,
|
changeOpenDevops:this.changeOpenDevops,
|
||||||
defaultBranch
|
defaultBranch
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="detailHeader-wrapper">
|
<div className="detailHeader-wrapper">
|
||||||
<div className="normal">
|
<div className="normal">
|
||||||
<AlignTop style={{ padding: "18px 0px 10px", justifyContent: "space-between" }}>
|
<div className="f-wrap-between pb15" style={{ position: "relative" }}>
|
||||||
<div>
|
<p className="font-22 df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
|
||||||
<AlignTop>
|
|
||||||
<div className="projectallName">
|
|
||||||
{project && project.author &&
|
{project && project.author &&
|
||||||
<Link to={`/${project.author.login}`}>{project.author.name}</Link>
|
<Link to={`${project.author.type ==="Organization" ? "/organize":'/users'}/${project.author.login}`} className="show-user-link">
|
||||||
|
{project.author.name}
|
||||||
|
</Link>
|
||||||
}
|
}
|
||||||
<span className="ml5 mr5">/</span>
|
<span className="ml5 mr5">/</span>
|
||||||
<Link to={`/${owner}/${projectsId}`} className="projectN mt6">{projectDetail && projectDetail.name}</Link>
|
<span className="hide-1 flex-1 df">
|
||||||
</div>
|
<Link to={`/projects/${owner}/${projectsId}`} className="font-22">{project && project.name}</Link>
|
||||||
{projectDetail && projectDetail.private && <span className="privateTag mt6">私有</span>}
|
|
||||||
</AlignTop>
|
|
||||||
<div className="mt8">
|
|
||||||
{
|
{
|
||||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||||
this.textFunc(projectDetail.forked_from_project_id, projectDetail.fork_info)
|
<Tooltip placement={'right'} title={text}>
|
||||||
: ""
|
<Link to={`/projects/${projectDetail.fork_info.fork_project_user_login}/${projectDetail.fork_info.fork_project_identifier}`}
|
||||||
|
className="ml10" >
|
||||||
|
<i className="iconfont icon-fork font-18 fl mt6" style={{ color: "#8D90E3" }}></i>
|
||||||
|
</Link>
|
||||||
|
</Tooltip> : ""
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
|
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
|
||||||
<span className="color-grey-9">导入于 <a className="color-grey-6" target="_blank" href={projectDetail.mirror_url}>{projectDetail.mirror_url}</a></span>
|
projectDetail.type === 2 ?
|
||||||
: ""
|
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
|
||||||
|
<i className="iconfont icon-banbenku font-18 mt6" style={{ color: "#8D90E3" }}/>
|
||||||
|
</Tooltip>
|
||||||
|
:
|
||||||
|
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
|
||||||
|
<i className="iconfont icon-jingxiang font-18 color-green mt6" />
|
||||||
|
</Tooltip>
|
||||||
|
:""
|
||||||
}
|
}
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</p>
|
||||||
<div>
|
|
||||||
{
|
{
|
||||||
firstSync ? "" :
|
firstSync ? "":
|
||||||
<span className="df">
|
<span className="df mt25">
|
||||||
{
|
{
|
||||||
((current_user && current_user.admin) || isManager) && (projectDetail && projectDetail.type && projectDetail.type === 2) ?
|
projectDetail && projectDetail.type && projectDetail.type === 2 ?
|
||||||
<a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
|
<a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
|
||||||
}
|
}
|
||||||
<span className="detail_tag_btn">
|
<span className="detail_tag_btn">
|
||||||
<a className="detail_tag_btn_name" style={{ cursor: platform ? "pointer" : "default" }} onClick={() => this.focusFunc(watched)}>
|
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.focusFunc(watched)}>
|
||||||
<i className={watched ? "iconfont icon-shixing color-orange font-16 mr3" : "iconfont icon-kongxing color-grey-9 font-16 mr3"}></i>
|
<i className={watched ? "iconfont icon-shixing color-orange font-16 mr3":"iconfont icon-kongxing color-grey-9 font-16 mr3"}></i>
|
||||||
<span>{watched ? '取消关注' : '关注'}</span>
|
<span>{watched ? '取消关注' : '关注'}</span>
|
||||||
</a>
|
</a>
|
||||||
{
|
{
|
||||||
watchers_count > 0 ?
|
watchers_count > 0 ?
|
||||||
platform ?
|
platform ?
|
||||||
<Link className="detail_tag_btn_count" style={{ color: `#666` }} to={platform ? { pathname: `/${owner}/${projectsId}/following`, state } : ""}>
|
<Link className="detail_tag_btn_count" style={{color:`${watched?"#2878FF":"#666"}`}} to={platform?{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }:""}>
|
||||||
{watchers_count}
|
{watchers_count}
|
||||||
</Link>
|
</Link>
|
||||||
:
|
:
|
||||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||||
: ""
|
:""
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<span className="detail_tag_btn">
|
<span className="detail_tag_btn">
|
||||||
<a className="detail_tag_btn_name" style={{ cursor: platform ? "pointer" : "default" }} onClick={() => this.pariseFunc(praised)}>
|
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.pariseFunc(praised)}>
|
||||||
<i className={praised ? "iconfont icon-weibiaoti105 color-orange font-14 mr3" : "iconfont icon-guanzhu color-grey-9 font-14 mr3"}></i>
|
<i className={praised ? "iconfont icon-weibiaoti105 color-orange font-14 mr3":"iconfont icon-guanzhu color-grey-9 font-14 mr3"}></i>
|
||||||
<span>{praised ? '取消点赞' : '点赞'}</span>
|
<span>{praised ? '取消点赞' : '点赞'}</span>
|
||||||
</a>
|
</a>
|
||||||
{
|
{
|
||||||
praises_count > 0 ?
|
praises_count > 0 ?
|
||||||
platform ?
|
platform ?
|
||||||
<Link className="detail_tag_btn_count" style={{ color: `#666` }} to={{ pathname: `/${owner}/${projectsId}/stargazers`, state }}>
|
<Link className="detail_tag_btn_count" style={{color:`${praised?"#2878FF":"#666"}`}} to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
|
||||||
{praises_count}
|
{praises_count}
|
||||||
</Link> :
|
</Link>:
|
||||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||||
: ""
|
:""
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<span className="detail_tag_btn" loading={forkSpin}>
|
<span className="detail_tag_btn">
|
||||||
<Tooltip title="复刻是fork的中文名,即复制代码仓库" placement="bottom">
|
<Tooltip title="复刻是fork的中文名,即复制代码仓库" placement="bottom">
|
||||||
<a className="detail_tag_btn_name" style={{ cursor: platform ? "pointer" : "default" }} onClick={this.forkFunc}>
|
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={this.forkFunc}>
|
||||||
<i className="iconfont icon-fork color-grey-9 mr3 font-16"></i><span>复刻(Fork)</span>
|
<i className="iconfont icon-fork color-grey-9 mr3"></i>复刻
|
||||||
</a>
|
</a>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{
|
{
|
||||||
forked_count > 0 ?
|
forked_count > 0 ?
|
||||||
platform ?
|
platform ?
|
||||||
<Link className="detail_tag_btn_count" to={{ pathname: `/${owner}/${projectsId}/members`, state }}>
|
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
|
||||||
{forked_count}
|
{forked_count}
|
||||||
</Link>
|
</Link>
|
||||||
:
|
:
|
||||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||||
: ""
|
:""
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</AlignTop>
|
|
||||||
{/* <div className="mt6" style={{minHeight:"20px"}}>
|
|
||||||
{
|
|
||||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
|
||||||
this.textFunc(projectDetail.forked_from_project_id,projectDetail.fork_info)
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
{
|
|
||||||
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
|
|
||||||
<span className="color-grey-9">镜像自 <a className="color-blue hoverLine" target="_blank" href={projectDetail.mirror_url}>{projectDetail.mirror_url}</a></span>
|
|
||||||
:""
|
|
||||||
}
|
|
||||||
</div> */}
|
|
||||||
{
|
{
|
||||||
firstSync ? "" :
|
firstSync ? "" :
|
||||||
<DetailBanner
|
<DetailBanner
|
||||||
|
@ -615,204 +542,169 @@ class Detail extends Component {
|
||||||
<Spin spinning={secondSync} className="spinstyle" tip="正在同步镜像" size="large">
|
<Spin spinning={secondSync} className="spinstyle" tip="正在同步镜像" size="large">
|
||||||
<Switch {...this.props}>
|
<Switch {...this.props}>
|
||||||
{/* 资源 */}
|
{/* 资源 */}
|
||||||
<Route path="/:owner/:projectsId/source"
|
<Route path="/projects/:owner/:projectsId/source"
|
||||||
render={
|
render={
|
||||||
() => (<Source {...this.props} {...this.state} {...common} />)
|
() => (<Source {...this.props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 主页 */}
|
{/* 主页 */}
|
||||||
<Route path="/:owner/:projectsId/about"
|
<Route path="/projects/:owner/:projectsId/about"
|
||||||
render={
|
render={
|
||||||
() => (<DevAbout {...this.props} {...this.state} {...common} />)
|
() => (<DevAbout {...this.props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* wiki新增文件 */}
|
|
||||||
<Route path="/:owner/:projectsId/wiki/add"
|
|
||||||
render={
|
|
||||||
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* wiki编辑文件 */}
|
|
||||||
<Route path="/:owner/:projectsId/wiki/edit/:wikiName"
|
|
||||||
render={
|
|
||||||
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* wiki */}
|
|
||||||
<Route path="/:owner/:projectsId/wiki"
|
|
||||||
render={
|
|
||||||
() => (<Wiki {...this.props} {...this.state} {...common} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
{/* 工作流 */}
|
{/* 工作流 */}
|
||||||
<Route path="/:owner/:projectsId/devops"
|
<Route path="/projects/:owner/:projectsId/devops"
|
||||||
render={
|
render={
|
||||||
() => (<DevIndex {...this.props} {...this.state} {...common} />)
|
() => (<DevIndex {...this.props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 标签列表 */}
|
{/* 标签列表 */}
|
||||||
<Route path="/:owner/:projectsId/issues/tags"
|
<Route path="/projects/:owner/:projectsId/issues/tags"
|
||||||
render={
|
render={
|
||||||
(props) => (<TagList {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<TagList {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 仓库设置 */}
|
{/* 仓库设置 */}
|
||||||
<Route path="/:owner/:projectsId/settings"
|
<Route path="/projects/:owner/:projectsId/setting"
|
||||||
render={
|
render={
|
||||||
(props) => (<Setting {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<Setting {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
{/* 任务详情 */}
|
||||||
|
<Route path="/projects/:owner/:projectsId/issues/:orderId/detail"
|
||||||
|
render={
|
||||||
|
(props) => (<OrderDetail {...this.props} {...this.state} {...props} {...common} />)
|
||||||
|
}
|
||||||
|
></Route>
|
||||||
{/*修改里程碑*/}
|
{/*修改里程碑*/}
|
||||||
<Route path="/:owner/:projectsId/milestones/:meilid/edit"
|
<Route path="/projects/:owner/:projectsId/milestones/:meilid/edit"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 新建里程碑 */}
|
{/* 新建里程碑 */}
|
||||||
<Route path="/:owner/:projectsId/milestones/new"
|
<Route path="/projects/:owner/:projectsId/milestones/new"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/*里程碑详情*/}
|
{/*里程碑详情*/}
|
||||||
<Route path="/:owner/:projectsId/milestones/:meilid"
|
<Route path="/projects/:owner/:projectsId/milestones/:meilid"
|
||||||
render={
|
render={
|
||||||
(props) => (<MilepostDetail {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<MilepostDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 里程碑 */}
|
{/* 里程碑 */}
|
||||||
<Route path="/:owner/:projectsId/milestones"
|
<Route path="/projects/:owner/:projectsId/milestones"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderMilepost {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrderMilepost {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 里程碑页面新建任务 */}
|
{/* 里程碑页面新建任务 */}
|
||||||
<Route path="/:owner/:projectsId/issues/:milepostId/new"
|
<Route path="/projects/:owner/:projectsId/issues/:milepostId/new"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 新建任务 */}
|
{/* 新建任务 */}
|
||||||
<Route path="/:owner/:projectsId/issues/new"
|
<Route path="/projects/:owner/:projectsId/issues/new"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrderNew {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 修改详情 updatedetail*/}
|
{/* 修改详情 */}
|
||||||
<Route path="/:owner/:projectsId/issues/:orderId/:operateName"
|
<Route path="/projects/:owner/:projectsId/issues/:orderId/updatedetail"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 复制详情 copyetail*/}
|
{/* 复制详情 */}
|
||||||
<Route path="/:owner/:projectsId/issues/:orderId/copyetail"
|
<Route path="/projects/:owner/:projectsId/issues/:orderId/copyetail"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrdercopyDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
|
|
||||||
{/* 任务详情 */}
|
|
||||||
<Route path="/:owner/:projectsId/issues/:orderId"
|
|
||||||
render={
|
|
||||||
(props) => (<OrderDetail {...this.props} {...this.state} {...props} {...common} />)
|
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 动态 */}
|
{/* 动态 */}
|
||||||
<Route path="/:owner/:projectsId/activity"
|
<Route path="/projects/:owner/:projectsId/activity"
|
||||||
render={
|
render={
|
||||||
(props) => (<TrendsIndex {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<TrendsIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 代码Index */}
|
{/* 代码Index */}
|
||||||
<Route path="/:owner/:projectsId/issues"
|
<Route path="/projects/:owner/:projectsId/issues"
|
||||||
render={
|
render={
|
||||||
(props) => (<OrderIndex {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<OrderIndex {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 新建合并请求 */}
|
{/* 新建合并请求 */}
|
||||||
{/* <Route path="/:owner/:projectsId/compare/:branch"
|
<Route path="/projects/:owner/:projectsId/pulls/new"
|
||||||
render={
|
|
||||||
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)
|
|
||||||
}
|
|
||||||
></Route> */}
|
|
||||||
<Route path="/:owner/:projectsId/compare"
|
|
||||||
render={
|
render={
|
||||||
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)
|
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/pulls/:mergeId/edit"
|
<Route path="/projects/:owner/:projectsId/pulls/:mergeId/UpdateMerge"
|
||||||
render={
|
render={
|
||||||
(props) => (<UpdateMerge {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<UpdateMerge {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/pulls/:mergeId"
|
<Route path="/projects/:owner/:projectsId/pulls/:mergeId/Messagecount"
|
||||||
render={
|
render={
|
||||||
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/pulls/:mergeId/commits"
|
<Route path="/projects/:owner/:projectsId/pulls/:mergeId/MergeSubmit"
|
||||||
render={
|
|
||||||
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
<Route path="/:owner/:projectsId/pulls/:mergeId/files"
|
|
||||||
render={
|
|
||||||
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
|
||||||
}
|
|
||||||
></Route>
|
|
||||||
<Route path="/:owner/:projectsId/pulls/:mergeId/MergeSubmit"
|
|
||||||
render={
|
render={
|
||||||
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<MessageCount {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
<Route path="/:owner/:projectsId/pulls"
|
<Route path="/projects/:owner/:projectsId/pulls"
|
||||||
render={
|
render={
|
||||||
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/following"
|
<Route path="/projects/:owner/:projectsId/watchers"
|
||||||
render={
|
render={
|
||||||
(props) => (<WatchUsers {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<WatchUsers {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/stargazers"
|
<Route path="/projects/:owner/:projectsId/stargazers"
|
||||||
render={
|
render={
|
||||||
(props) => (<PraiseUsers {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<PraiseUsers {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/members"
|
<Route path="/projects/:owner/:projectsId/fork_users"
|
||||||
render={
|
render={
|
||||||
(props) => (<ForkUsers {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<ForkUsers {...this.props} {...props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 贡献者列表 */}
|
{/* 贡献者列表 */}
|
||||||
<Route path="/:owner/:projectsId/contribute"
|
<Route path="/projects/:owner/:projectsId/contribute"
|
||||||
render={
|
render={
|
||||||
() => (<Contribute {...this.props} {...this.state} {...common} />)
|
() => (<Contribute {...this.props} {...this.state} {...common} />)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
|
|
||||||
{/* 代码库----详情页面 */}
|
{/* 代码库----详情页面 */}
|
||||||
<Route path="/:owner/:projectsId/commits/branch/:branchName"
|
<Route path="/projects/:owner/:projectsId/commits/branch/:branchName"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} {...common}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/tree/:branchName"
|
<Route path="/projects/:owner/:projectsId/tree/:branchName"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderDepot {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<CoderDepot {...this.props} {...props} {...this.state} {...common}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId/:subIndex"
|
<Route path="/projects/:owner/:projectsId/:subIndex"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state} {...common}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
<Route path="/:owner/:projectsId"
|
<Route path="/projects/:owner/:projectsId"
|
||||||
render={
|
render={
|
||||||
(props) => (<CoderDepot {...this.props} {...props} {...this.state} {...common} />)
|
(props) => (<CoderDepot {...this.props} {...props} {...this.state} {...common}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
@ -823,7 +715,4 @@ class Detail extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ImageLayerOfCommentHOC({
|
export default Detail;
|
||||||
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
|
||||||
parentSelector: ".newContainer",
|
|
||||||
})(Detail);
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue