Compare commits
200 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
6d14b0280a | |
|
|
14ff9e24b4 | |
|
|
5ab66792c6 | |
|
|
3d63c16131 | |
|
|
560e7051a6 | |
|
|
4ca3237ab8 | |
|
|
dc352b298c | |
|
|
673165c049 | |
|
|
3530352c8f | |
|
|
1b55988fc5 | |
|
|
f5b42a8751 | |
|
|
c0a7e18df9 | |
|
|
2e3a91b57b | |
|
|
630e32e1e0 | |
|
|
d8d3208e97 | |
|
|
18bb630e7d | |
|
|
d8d4c133b3 | |
|
|
bbf36127d6 | |
|
|
85101486e5 | |
|
|
0f884343d6 | |
|
|
cbc0c611ed | |
|
|
71c8f3da84 | |
|
|
e3f0df25d3 | |
|
|
3e54838175 | |
|
|
07ceddecc8 | |
|
|
76c7ec84d9 | |
|
|
cd5f5ed04f | |
|
|
d1214b8b6b | |
|
|
9369bdc1fc | |
|
|
9489b0dfc1 | |
|
|
35b8f31b1c | |
|
|
8276f11c87 | |
|
|
aea1d5efd6 | |
|
|
324b159111 | |
|
|
0b4c83d640 | |
|
|
d968ec9e65 | |
|
|
0502fb1317 | |
|
|
38709b1cab | |
|
|
1dcbd8fed2 | |
|
|
9081805bad | |
|
|
e03dc3e90f | |
|
|
e7175d74ec | |
|
|
8f421aac4d | |
|
|
d3ce0ed9c3 | |
|
|
243c71a03c | |
|
|
6f3d0cadff | |
|
|
351d69f77e | |
|
|
23cc7e8191 | |
|
|
be11cd0164 | |
|
|
4319067c1c | |
|
|
ec1dbe0f9b | |
|
|
5c66758a6e | |
|
|
7cca2d3e02 | |
|
|
16f7c45da9 | |
|
|
330ac9aabb | |
|
|
0172b5da48 | |
|
|
dc82e9b2f4 | |
|
|
7165b99ef3 | |
|
|
09fe5c16ef | |
|
|
e1b5834b4b | |
|
|
67b681f027 | |
|
|
d62ce9a10a | |
|
|
3ae009255e | |
|
|
bfaf37c8d1 | |
|
|
969863f5a1 | |
|
|
4f597bd257 | |
|
|
af323daa16 | |
|
|
0f659d7ffe | |
|
|
30f1a396f3 | |
|
|
14c94ce3c6 | |
|
|
ec48f4be0c | |
|
|
269a0142c3 | |
|
|
e80a9686e8 | |
|
|
ef795e9caf | |
|
|
b9a233af17 | |
|
|
fa2b68e58b | |
|
|
dce5404850 | |
|
|
e4313d30eb | |
|
|
59ac6f5c17 | |
|
|
4ea6c345e6 | |
|
|
83f2c28ae0 | |
|
|
e6b8dd6c6b | |
|
|
ee3aa25ddc | |
|
|
c1d3d5fb8b | |
|
|
8f6048f840 | |
|
|
902b078172 | |
|
|
a1da04a405 | |
|
|
57976b5646 | |
|
|
1549072286 | |
|
|
a8563e9e44 | |
|
|
1090f473ea | |
|
|
b9d7d4d6d6 | |
|
|
401c3ef3dc | |
|
|
b04649dc7c | |
|
|
0123b7810f | |
|
|
4c11feb276 | |
|
|
c62b99eb61 | |
|
|
b3cd5459e5 | |
|
|
993f662f45 | |
|
|
e991f821a5 | |
|
|
683710fed8 | |
|
|
cc35070e7b | |
|
|
748ab612d2 | |
|
|
f6dba27d8a | |
|
|
f511e85d38 | |
|
|
ac5cf6bde7 | |
|
|
1d64957e5a | |
|
|
dc00ffc34b | |
|
|
dc01557c59 | |
|
|
bc496c6d8b | |
|
|
65df8b0146 | |
|
|
aae855bda5 | |
|
|
3cfb5a0370 | |
|
|
630e2536ec | |
|
|
d65f771b6b | |
|
|
edc4bb4c40 | |
|
|
364827b63f | |
|
|
bdf61d7bbb | |
|
|
0ec824d0cb | |
|
|
bf7afa9087 | |
|
|
c76723ece0 | |
|
|
d54bdcf7a7 | |
|
|
a90a068885 | |
|
|
4706ee05bf | |
|
|
8d9946bad6 | |
|
|
adde24ccaf | |
|
|
2a1f64705d | |
|
|
2b658e59fa | |
|
|
a017c6f84d | |
|
|
636d2ee36b | |
|
|
97a9734bf7 | |
|
|
b23e8c7e53 | |
|
|
00d866e6e2 | |
|
|
b29c80fb64 | |
|
|
2299e7cefb | |
|
|
424fe4980e | |
|
|
ce0a97e0ad | |
|
|
94a0a84303 | |
|
|
cc49b02ab5 | |
|
|
f651e7d80c | |
|
|
ef229a635d | |
|
|
8cd33ee65d | |
|
|
2da3c827b2 | |
|
|
f9ce3de759 | |
|
|
f619b949f4 | |
|
|
e3bb09b530 | |
|
|
3b88cb3b67 | |
|
|
79bc855adc | |
|
|
055c4ae851 | |
|
|
22fbdcf57a | |
|
|
55008a1dec | |
|
|
dcb01851b5 | |
|
|
7a8b028aeb | |
|
|
9e4254e01f | |
|
|
5b5ac99be9 | |
|
|
ed4bd23946 | |
|
|
538c681d34 | |
|
|
99792045bc | |
|
|
529a64194e | |
|
|
415430a872 | |
|
|
ff7d20a684 | |
|
|
56ea97b8b2 | |
|
|
de722c7164 | |
|
|
2a3708289a | |
|
|
0a5991a93a | |
|
|
e7d8a4f0cc | |
|
|
843c1d14be | |
|
|
34312abc24 | |
|
|
20e32871d7 | |
|
|
17d0e3c1a2 | |
|
|
090db8e9b0 | |
|
|
e11fd89286 | |
|
|
4aa819a109 | |
|
|
78212429e5 | |
|
|
b09afec016 | |
|
|
c3f08312db | |
|
|
f87c60d2ef | |
|
|
e35c8e4cdf | |
|
|
03b058cae1 | |
|
|
1f687dd369 | |
|
|
1b89e542ff | |
|
|
559f5da65e | |
|
|
21e27bdef1 | |
|
|
acd97d0ba0 | |
|
|
5d2758b7b7 | |
|
|
de0c381197 | |
|
|
22c00f5ce3 | |
|
|
b88e41f609 | |
|
|
a16d9871a3 | |
|
|
1621380ba8 | |
|
|
8bb298f062 | |
|
|
1457bc1adc | |
|
|
44366b8a26 | |
|
|
7dbcdd7b77 | |
|
|
78ba918514 | |
|
|
bb72b3b826 | |
|
|
53d50a22f8 | |
|
|
a83b6a1013 | |
|
|
84bffef253 | |
|
|
637ce0fc9a |
|
|
@ -12,6 +12,11 @@ pids
|
|||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Ignore master key for decrypting credentials and more.
|
||||
/config/master.key
|
||||
/config/database.yml
|
||||
/.idea/*
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
|
|
@ -80,3 +85,4 @@ typings/
|
|||
.dynamodb/
|
||||
|
||||
.DS_Store
|
||||
.idea/*
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
8
add.txt
8
add.txt
|
|
@ -26,9 +26,11 @@ MainContentContainer
|
|||
|
||||
|
||||
|
||||
TODO
|
||||
待同步
|
||||
TODO
|
||||
待同步
|
||||
1、timer图标样式更换
|
||||
index.html
|
||||
WebSSHTimer.css
|
||||
WebSSHTimer.js
|
||||
WebSSHTimer.js
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ function getClientEnvironment(publicUrl) {
|
|||
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
|
||||
// This should only be used as an escape hatch. Normally you would put
|
||||
// images into the `src` and `import` them in code to get their paths.
|
||||
PUBLIC_URL: '/forgeplus-react/build/.',
|
||||
PUBLIC_URL: '/react/build/.',
|
||||
}
|
||||
);
|
||||
// Stringify all values so we can feed into Webpack DefinePlugin
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ module.exports = {
|
|||
// cdn
|
||||
// publicPath: 'https://shixun.educoder.net/react/build/', //publicPath, https://cdn.educoder.net
|
||||
// publicPath: 'https://cdn-testeduplus2.educoder.net/react/build/', //publicPath, https://cdn.educoder.net
|
||||
publicPath: '/forgeplus-react/build/', //publicPath, https://cdn.educoder.net
|
||||
publicPath: '/react/build/', //publicPath, https://cdn.educoder.net
|
||||
|
||||
// Point sourcemap entries to original disk location (format as URL on Windows)
|
||||
devtoolModuleFilenameTemplate: info =>
|
||||
|
|
|
|||
|
|
@ -893,12 +893,40 @@
|
|||
"integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "http://registry.npm.taobao.org/axios/download/axios-0.18.0.tgz",
|
||||
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
|
||||
"version": "0.18.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
|
||||
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.3.0",
|
||||
"is-buffer": "^1.1.5"
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "^2.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
}
|
||||
},
|
||||
"is-buffer": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
|
||||
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"axobject-query": {
|
||||
|
|
@ -1853,8 +1881,7 @@
|
|||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
|
||||
"resolved": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -2393,6 +2420,11 @@
|
|||
"resolved": "http://registry.npm.taobao.org/chardet/download/chardet-0.4.2.tgz",
|
||||
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
|
||||
},
|
||||
"charenc": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
|
||||
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
||||
},
|
||||
"check-types": {
|
||||
"version": "7.4.0",
|
||||
"resolved": "http://registry.npm.taobao.org/check-types/download/check-types-7.4.0.tgz",
|
||||
|
|
@ -2702,8 +2734,7 @@
|
|||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
|
||||
"resolved": ""
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "3.1.10",
|
||||
|
|
@ -3223,9 +3254,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -3296,6 +3327,11 @@
|
|||
"which": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"crypt": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
|
||||
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
|
||||
},
|
||||
"crypto-browserify": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "http://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz",
|
||||
|
|
@ -3771,9 +3807,9 @@
|
|||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -5994,9 +6030,9 @@
|
|||
"integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ="
|
||||
},
|
||||
"handlebars": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "http://registry.npm.taobao.org/handlebars/download/handlebars-4.1.1.tgz",
|
||||
"integrity": "sha1-bk5BwY6+dxmuTTjlrKPTL6PdI9M=",
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.3.tgz",
|
||||
"integrity": "sha512-SRGwSYuNfx8DwHD/6InAPzD6RgeruWLT+B8e8a7gGs8FWgHzlExpTFMEq2IA6QpAfOClpKHy6+8IqTjeBCu6Kg==",
|
||||
"requires": {
|
||||
"neo-async": "^2.6.0",
|
||||
"optimist": "^0.6.1",
|
||||
|
|
@ -7368,12 +7404,19 @@
|
|||
"integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "http://registry.npm.taobao.org/js-yaml/download/js-yaml-3.7.0.tgz",
|
||||
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^2.6.0"
|
||||
"esprima": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsbn": {
|
||||
|
|
@ -7753,9 +7796,9 @@
|
|||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -7769,9 +7812,9 @@
|
|||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "http://registry.npm.taobao.org/lodash/download/lodash-4.17.11.tgz",
|
||||
"integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40="
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
},
|
||||
"lodash-es": {
|
||||
"version": "4.17.11",
|
||||
|
|
@ -8020,6 +8063,16 @@
|
|||
"resolved": "http://registry.npm.taobao.org/math-random/download/math-random-1.0.4.tgz",
|
||||
"integrity": "sha1-XdaUPJOFSCZwFtTjTwV1gwgMUUw="
|
||||
},
|
||||
"md5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
|
||||
"integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
|
||||
"requires": {
|
||||
"charenc": "~0.0.1",
|
||||
"crypt": "~0.0.1",
|
||||
"is-buffer": "~1.1.1"
|
||||
}
|
||||
},
|
||||
"md5.js": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "http://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz",
|
||||
|
|
@ -8075,9 +8128,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -8216,9 +8269,9 @@
|
|||
}
|
||||
},
|
||||
"mixin-deep": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "http://registry.npm.taobao.org/mixin-deep/download/mixin-deep-1.3.1.tgz",
|
||||
"integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=",
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
|
||||
"integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
|
||||
"requires": {
|
||||
"for-in": "^1.0.2",
|
||||
"is-extendable": "^1.0.1"
|
||||
|
|
@ -8226,8 +8279,8 @@
|
|||
"dependencies": {
|
||||
"is-extendable": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "http://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz",
|
||||
"integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
|
||||
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4"
|
||||
}
|
||||
|
|
@ -8242,6 +8295,15 @@
|
|||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"mockjs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mockjs/-/mockjs-1.1.0.tgz",
|
||||
"integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "*"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.24.0",
|
||||
"resolved": "http://registry.npm.taobao.org/moment/download/moment-2.24.0.tgz",
|
||||
|
|
@ -8337,9 +8399,9 @@
|
|||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -13606,9 +13668,9 @@
|
|||
"integrity": "sha1-ACbjf1RU1z41bf5lZGmYZ8an8P8="
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -13667,9 +13729,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -14440,6 +14502,15 @@
|
|||
"resolved": "http://registry.npm.taobao.org/react-content-loader/download/react-content-loader-3.4.2.tgz",
|
||||
"integrity": "sha1-GH++wqo4ljXkYT+qBGcT8ZYXP0A="
|
||||
},
|
||||
"react-cookies": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-cookies/-/react-cookies-0.1.1.tgz",
|
||||
"integrity": "sha512-PP75kJ4vtoHuuTdq0TAD3RmlAv7vuDQh9fkC4oDlhntgs9vX1DmREomO0Y1mcQKR9nMZ6/zxoflaMJ3MAmF5KQ==",
|
||||
"requires": {
|
||||
"cookie": "^0.3.1",
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "http://registry.npm.taobao.org/react-dev-utils/download/react-dev-utils-5.0.3.tgz",
|
||||
|
|
@ -15104,9 +15175,9 @@
|
|||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "3.1.10",
|
||||
|
|
@ -15611,9 +15682,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.1.32",
|
||||
|
|
@ -15790,9 +15861,9 @@
|
|||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npm.taobao.org/minimist/download/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -16027,9 +16098,9 @@
|
|||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"set-value": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "http://registry.npm.taobao.org/set-value/download/set-value-2.0.0.tgz",
|
||||
"integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
|
||||
"integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-extendable": "^0.1.1",
|
||||
|
|
@ -16039,7 +16110,7 @@
|
|||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "http://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
|
|
@ -16120,6 +16191,172 @@
|
|||
"resolved": "http://registry.npm.taobao.org/shellwords/download/shellwords-0.1.1.tgz",
|
||||
"integrity": "sha1-1rkYHBpI05cyTISHHvvPxz/AZUs="
|
||||
},
|
||||
"showdown": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz",
|
||||
"integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==",
|
||||
"requires": {
|
||||
"yargs": "^14.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
|
||||
},
|
||||
"cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"requires": {
|
||||
"string-width": "^3.1.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wrap-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
|
||||
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
|
||||
"requires": {
|
||||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"requires": {
|
||||
"p-locate": "^3.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
||||
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"requires": {
|
||||
"p-limit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"requires": {
|
||||
"emoji-regex": "^7.0.1",
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^3.0.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz",
|
||||
"integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==",
|
||||
"requires": {
|
||||
"cliui": "^5.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^15.0.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "15.0.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz",
|
||||
"integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"showdown-katex": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/showdown-katex/-/showdown-katex-0.6.0.tgz",
|
||||
"integrity": "sha512-eEOipJjqMxRJ+e69WlA7XENhFZzKhNl12csey0iLd4QbLzGF61+FBxNPhEZFz9wICYTJNfyqNgLSqmm8Uj0fGA==",
|
||||
"requires": {
|
||||
"katex": "^0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"katex": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.10.2.tgz",
|
||||
"integrity": "sha512-cQOmyIRoMloCoSIOZ1+gEwsksdJZ1EW4SWm3QzxSza/QsnZr6D4U1V9S4q+B/OLm2OQ8TCBecQ8MaIfnScI7cw==",
|
||||
"requires": {
|
||||
"commander": "^2.19.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.2.tgz",
|
||||
|
|
@ -16240,8 +16477,7 @@
|
|||
},
|
||||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
|
||||
"resolved": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -16769,6 +17005,17 @@
|
|||
"mkdirp": "~0.5.1",
|
||||
"sax": "~1.2.1",
|
||||
"whet.extend": "~0.9.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"js-yaml": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
|
||||
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^2.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sw-precache": {
|
||||
|
|
@ -16930,9 +17177,9 @@
|
|||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.14.2",
|
||||
|
|
@ -17306,35 +17553,14 @@
|
|||
}
|
||||
},
|
||||
"union-value": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "http://registry.npm.taobao.org/union-value/download/union-value-1.0.0.tgz",
|
||||
"integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
||||
"integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
|
||||
"requires": {
|
||||
"arr-union": "^3.1.0",
|
||||
"get-value": "^2.0.6",
|
||||
"is-extendable": "^0.1.1",
|
||||
"set-value": "^0.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "http://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"set-value": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "http://registry.npm.taobao.org/set-value/download/set-value-0.4.3.tgz",
|
||||
"integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-extendable": "^0.1.1",
|
||||
"is-plain-object": "^2.0.1",
|
||||
"to-object-path": "^0.3.0"
|
||||
}
|
||||
}
|
||||
"set-value": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"uniq": {
|
||||
|
|
@ -17825,9 +18051,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "http://registry.npm.taobao.org/acorn/download/acorn-6.1.1.tgz",
|
||||
"integrity": "sha1-fSWuBbuK0fm2mRCOEJTs14hK3B8=",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
|
||||
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"antd": "^3.23.2",
|
||||
"array-flatten": "^2.1.2",
|
||||
"autoprefixer": "7.1.6",
|
||||
"axios": "^0.18.0",
|
||||
"axios": "^0.18.1",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-eslint": "7.2.3",
|
||||
"babel-jest": "20.0.3",
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
"jest": "20.0.4",
|
||||
"js-base64": "^2.5.1",
|
||||
"katex": "^0.11.1",
|
||||
"lodash": "^4.17.5",
|
||||
"lodash": "^4.17.15",
|
||||
"loglevel": "^1.6.1",
|
||||
"material-ui": "^1.0.0-beta.40",
|
||||
"md5": "^2.2.1",
|
||||
|
|
@ -94,9 +94,9 @@
|
|||
"rsuite": "^4.0.1",
|
||||
"sass-loader": "^7.3.1",
|
||||
"scroll-into-view": "^1.12.3",
|
||||
"source-map-support": "^0.5.16",
|
||||
"showdown": "^1.9.1",
|
||||
"showdown-katex": "^0.6.0",
|
||||
"source-map-support": "^0.5.16",
|
||||
"store": "^2.0.12",
|
||||
"style-loader": "0.19.0",
|
||||
"styled-components": "^4.1.3",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,655 +0,0 @@
|
|||
@charset "utf-8";
|
||||
body{font-size:14px; line-height:2.0;background:#ffffff!important;font-family: "微软雅黑","宋体"; color:#333;height: 100%}
|
||||
html{height:100%;}
|
||||
.newContainer{ min-height:100%; height: auto !important; height: 100%; /*IE6不识别min-height*/position: relative;}
|
||||
.newMain{ margin: 0 auto; padding-bottom: 155px; min-width:1200px }
|
||||
.newFooter{
|
||||
max-height: 110px;
|
||||
}
|
||||
.newFooter{ position: absolute; bottom: 0; width: 100%; background: #323232; clear:both; min-width: 1200px;z-index:99999;left: 0px;}
|
||||
.newHeader{background: #171616;width:100%; height: 50px; min-width: 1200px;position: fixed;top: 0px;left: 0px;z-index:99998}
|
||||
/* 重置样式 */
|
||||
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td,span{ margin:0; padding:0;}
|
||||
table,input,textarea,select,button { font-family: "微软雅黑","宋体"; font-size:14px;line-height:1.9; background:#f5f5f5; color:#333;}
|
||||
div,img,tr,td,table{ border:0;}
|
||||
table,tr,td{border:0;}
|
||||
a:link,a:visited{text-decoration:none;color:#898989; }
|
||||
a:hover {color:#FF7500;}
|
||||
a:hover.fa{color:#FF7500;}
|
||||
|
||||
input,textarea,select{ background: #fff; border:1px solid #eee;}
|
||||
textarea{resize: none;}
|
||||
/*侧滚动条*/
|
||||
::-webkit-scrollbar { width:10px; height:10px; background-color: #F5F5F5; }
|
||||
::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); background-color: #F5F5F5; }
|
||||
::-webkit-scrollbar-thumb { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); background-color: #ccc; }
|
||||
/*万能清除浮动*/
|
||||
.clearfix:after{clear:both;content:".";display:block;font-size:0;height:0;line-height:0;visibility:hidden;}
|
||||
.clearfix{clear:both;zoom:1}
|
||||
.cl{ clear: both; overflow: hidden;}
|
||||
/*通用浮动*/
|
||||
.fl{ float: left;}
|
||||
.fr{ float: right;}
|
||||
/*pre标签换行*/
|
||||
.break-word{word-break: break-all;word-wrap: break-word;}
|
||||
.break-word-firefox{white-space: pre-wrap !important;word-break: break-all;}
|
||||
/*超过隐藏*/
|
||||
.task-hide{overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
|
||||
.task-hide2{overflow:-moz-hidden-unscrollable; white-space: nowrap; text-overflow:ellipsis;}
|
||||
.hide{overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
|
||||
.hide-text {overflow:hidden; white-space:nowrap;}
|
||||
/*隐藏*/
|
||||
.none{display: none}
|
||||
.block{ display:block;}
|
||||
/*通用文字功能样式*/
|
||||
.font-bd{ font-weight: bold;}
|
||||
.color-red-light{color: #F00!important;}
|
||||
.color-red{ color:#d2322d!important;}
|
||||
.u-color-light-red{color: #FF6666}
|
||||
.color-black{color:#333!important;}
|
||||
.color-green{color:#51a74f!important;}
|
||||
.color-light-green{color:#29bd8b!important;}
|
||||
.color-blue{color:#3498db!important;}
|
||||
.color-orange{color:#ee4a1f!important;}
|
||||
.color-orange02{color:#f79f88!important;}
|
||||
.color-orange03{color:#ff7500!important;}
|
||||
.color-orange04{color: #ee4a20!important;}/*温馨提示公用颜色*/
|
||||
.color-orange05{color: #FF9e6a!important;}
|
||||
.color-orange06{color: #ff6530!important;}
|
||||
a.color-orange05:hover,i.color-orange05:hover{color:#ff7500!important;}
|
||||
.color-orange06{color:#FF6610!important;}
|
||||
.color-yellow{color:#f0ad4e!important;}
|
||||
.color-yellow2{color:#ff9933!important;}
|
||||
.color-yellow3{color:#FFC828;}/*新版学员统计---通关排行榜 2018/01/22*/
|
||||
|
||||
.color-light-grey{color:#afafaf!important;}
|
||||
.color-grey-7f{color: #7f7f7f!important;}
|
||||
.color-grey-no-a{color:#888!important;}
|
||||
.color-grey{color:#888!important;}
|
||||
.color-grey9{color:#999!important;}
|
||||
a.color-grey:hover{color: #FF7500!important;}/*a标签,移入变橙色*/
|
||||
.color-dark-grey{color:#666!important;}
|
||||
.color-grey3{color:#333!important;}
|
||||
a.color-grey3:hover{color: #ff7500!important;}
|
||||
.u-color-light-grey{color: #CCCCCC}
|
||||
.color-light-grey-C{color: #CCCCCC!important;}
|
||||
.color-light-grey-E{color: #EEEEEE}
|
||||
.color-grey-bf{color:#bfbfbf!important;}
|
||||
.color-grey-b{color:#bbbbbb!important;}
|
||||
|
||||
.-text-danger{ color:#FF6545 }
|
||||
.color_white{ color:#fff!important;}
|
||||
.color_Purple_grey{color: #8291a3!important;}/*TPI评论里右侧点赞的icon颜色*/
|
||||
.color-grey-c{color: #cccccc!important;}
|
||||
a.link-color-grey{color:#888!important;}
|
||||
a:hover.link-color-grey{color:#29bd8b!important;}
|
||||
a.link-color-green{color:#29bd8b!important;}
|
||||
a.link-color-blue{color:#6a8abe!important;}
|
||||
a.link-color-grey02{color:#888!important;}
|
||||
a:hover.link-color-grey02{ color:red!important;}
|
||||
a.link-color-grey03{color:#888!important;}
|
||||
a:hover.link-color-grey03{color:#3498db!important;}
|
||||
.edu-color-grey{ color:#666;}
|
||||
.edu-color-grey:hover{color:#ff7500;}
|
||||
/*通用背景颜色*/
|
||||
.back-color-orange{background-color: #FF7500}
|
||||
|
||||
|
||||
/*通用文字大小样式*/
|
||||
.font-12{ font-size: 12px!important;}
|
||||
.font-13{ font-size: 13px!important;}
|
||||
.font-14{ font-size: 14px!important;}
|
||||
.font-15{ font-size: 15px!important;}
|
||||
.font-16{ font-size: 16px!important;}
|
||||
.font-17{ font-size: 17px!important;}
|
||||
.font-18{ font-size: 18px!important;}
|
||||
.font-20{ font-size: 20px!important;}
|
||||
.font-22{ font-size: 22px!important;}
|
||||
.font-25{ font-size: 25px!important;}
|
||||
.font-24{ font-size: 24px!important;}
|
||||
.font-28{ font-size: 28px!important;}
|
||||
.font-30{ font-size: 30px!important;}
|
||||
.font-50{ font-size: 50px!important;}
|
||||
.font-60{ font-size: 60px!important;}
|
||||
.font-70{ font-size: 70px!important;}
|
||||
/*通用内外边距*/
|
||||
.mt-10{ margin-top:-10px;}.mt1{ margin-top:1px;}.mt2{ margin-top:2px;}.mt3{ margin-top:3px;}.mt4{ margin-top:4px;}.mt5{ margin-top:5px!important;}.mt6{ margin-top:6px;}.mt7{ margin-top:7px!important;}.mt8{ margin-top:8px;}.mt10{ margin-top:10px;}.mt12{ margin-top:12px;}.mt13{ margin-top:13px;}.mt15{ margin-top:15px;}.mt17{ margin-top:17px;}.mt20{ margin-top:20px!important;}.mt25{ margin-top:25px;}.mt30{ margin-top:30px!important;}.mt36{ margin-top:36px!important;}.mt40{ margin-top:40px;}.mt50{ margin-top:50px;}.mt70{ margin-top:70px;}.mt95{ margin-top:95px;}.mt100{ margin-top:100px;}
|
||||
.mb5{ margin-bottom: 5px;}.mb7{ margin-bottom: 7px;}.mb10{ margin-bottom: 10px;}.mb11{ margin-bottom: 11px;}.mb15{ margin-bottom: 15px;}.mb20{ margin-bottom: 20px;}.mb25{ margin-bottom: 25px;}.mb30{ margin-bottom: 30px!important;}.mb40{ margin-bottom: 40px!important;}.mb50{ margin-bottom: 50px!important;}.mb60{ margin-bottom: 60px!important;}.mb70{ margin-bottom: 70px!important;}.mb80{ margin-bottom: 80px!important;}.mb90{ margin-bottom: 90px!important;}.mb100{ margin-bottom: 100px!important;}.mb110{ margin-bottom: 110px;}
|
||||
.ml-3{ margin-left: -3px;}.ml1{margin-left: 1px;}.ml2{margin-left: 2px;}.ml3{margin-left: 3px;}.ml4{margin-left: 4px;}.ml5{ margin-left: 5px;}.ml6{ margin-left: 6px;}.ml10{ margin-left: 10px;}.ml12{ margin-left:12px!important;}.ml15{ margin-left: 15px;}.ml18{ margin-left: 18px;}.ml20{ margin-left: 20px;}.ml25{ margin-left: 25px;}.ml30{ margin-left: 30px;}.ml33{ margin-left: 33px;}.ml35{ margin-left:35px;}.ml40{margin-left:40px;}.ml42{margin-left:42px;}.ml45{ margin-left: 45px;}.ml50{ margin-left: 50px;}.ml55{ margin-left: 55px;}.ml60{ margin-left: 60px;}.ml75{ margin-left: 75px;}.ml80{ margin-left: 80px;}.ml85{margin-left:85px;}.ml95{ margin-left: 95px;}.ml115{margin-left: 115px}.ml123{ margin-left: 123px;}.ml150{ margin-left: 150px;}.ml180{ margin-left: 180px;}.ml230{ margin-left: 230px;}.ml240{margin-left: 240px;}.ml250{ margin-left: 250px;}.ml290{ margin-left: 290px;}
|
||||
.mr3{margin-right: 3px}.mr4{margin-right: 4px}.mr5{ margin-right: 5px;}.mr8{ margin-right: 8px;}.mr10{ margin-right: 10px;}.mr12{ margin-right:12px!important;}.mr15{ margin-right: 15px;}.mr18{ margin-right: 18px;}.mr20{ margin-right: 20px;}.mr25{ margin-right: 25px;}.mr30{ margin-right:30px;}.mr35{margin-right:35px;}.mr40{margin-right:40px;}.mr45{margin-right:45px;}.mr50{ margin-right: 50px;}.mr60{ margin-right:60px;}.mr350{ margin-right:350px;}.pt5{ padding-top:5px;}.pt10{ padding-top:10px;}.pt15{ padding-top:15px;}.pt20{ padding-top:20px;}.pt30{ padding-top:30px;}.pt40{ padding-top:40px;}.pt47{ padding-top:47px;}.pt100{padding-top:100px;}.pt130{padding-top:130px;}
|
||||
|
||||
.pt1{ padding-top:1px;}.pt5{ padding-top:5px;}.pt10{ padding-top:10px;}.pt15{ padding-top:15px;}.pt20{ padding-top:20px;}.pt30{ padding-top:30px;}.pt40{ padding-top:40px;}
|
||||
.pb5{ padding-bottom:5px;}.pb10{ padding-bottom:10px;}.pb15{ padding-bottom:15px;}.pb20{ padding-bottom:20px;}.pb28{ padding-bottom:28px;}.pb30{ padding-bottom:30px;}.pb40{ padding-bottom:40px;}.pb47{ padding-bottom:47px;}.pb50{ padding-bottom:50px;}.pb155{ padding-bottom:155px;}
|
||||
.pl2{ padding-left:2px;}.pl5{ padding-left:5px;}.pl8{ padding-left:8px;}.pl10{ padding-left:10px;}.pl15{ padding-left:15px;}.pl20{ padding-left:20px;}.pl28{ padding-left:28px;}.pl30{ padding-left:30px;}.pl33{padding-left: 33px}.pl40{ padding-left:40px;}.pl42{ padding-left:42px;}.pl45{ padding-left:45px;}.pl50{ padding-left:50px;}.pl100{ padding-left:100px;}.pl35{ padding-left:35px;}.pl50{padding-left:50px;}.pl70{padding-left:70px;}.pl80{padding-left:80px;}.pl92{padding-left:92px;}
|
||||
.pr2{ paddding-right:2px;}.pr5{ padding-right:5px;}.pr10{ padding-right:10px;}.pr15{ padding-right:15px;}.pr20{ padding-right:20px!important;}.pr30{ padding-right:30px!important;}.pr42{ padding-right:42px;}.pr45{ padding-right:45px;}
|
||||
|
||||
.pl2{ padding-left:2px;}.pl5{ padding-left:5px;}.pl8{ padding-left:8px;}.pl10{ padding-left:10px;}.pl15{ padding-left:15px;}.pl20{ padding-left:20px;}.pl28{ padding-left:28px;}.pl30{ padding-left:30px;}.pl33{padding-left: 33px}.pl40{ padding-left:40px;}.pl42{ padding-left:42px;}.pl45{ padding-left:45px;}.pl50{ padding-left:50px;}.pl100{ padding-left:100px;}.pl35{ padding-left:35px;}.pl50{padding-left:50px;}.pl70{padding-left:70px;}.pl80{padding-left:80px;}.pl92{padding-left:92px;}
|
||||
.pr2{ paddding-right:2px;}.pr5{ padding-right:5px;}.pr10{ padding-right:10px;}.pr15{ padding-right:15px;}.pr20{ padding-right:20px!important;}.pr30{ padding-right:30px!important;}.pr42{ padding-right:42px;}.pr45{ padding-right:45px;}
|
||||
|
||||
|
||||
.padding15{ padding:15px;}
|
||||
.padding10{ padding:10px;}
|
||||
.padding10-15{ padding:10px 15px;}
|
||||
.padding15-10{ padding:15px 10px;}
|
||||
.ptl5-10{ padding:5px 10px;}
|
||||
.ptl3-10{ padding:3px 10px;}
|
||||
.ptl8-10{ padding:8px 10px;}
|
||||
|
||||
|
||||
|
||||
.wb11{width:11%!important;}.wb89{width:89%!important;}
|
||||
|
||||
.h3{ height:3px;}
|
||||
.h24{ height: 24px;}
|
||||
.h32{ height: 32px;}
|
||||
.h40{ height: 40px;}
|
||||
.h50{ height: 50px;}
|
||||
.h60{ height: 60px;}
|
||||
.h80{ height: 80px;}
|
||||
.h80{ height: 80px;}
|
||||
.h85{ height: 85px;}
|
||||
.h100{ height:100px;}
|
||||
.h140{ height:140px;}
|
||||
.h200{ height:200px;}
|
||||
/*块*/
|
||||
.col-width{ background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-10{ max-width: 100%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-9{ max-width: 90%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-8{ max-width: 80%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-7{ max-width: 70%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-6{ max-width: 60%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-5{ max-width: 50%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-4{ max-width: 40%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-3{ width: 500px; background: #fff; border:1px solid #e8e8e8;
|
||||
position:absolute;left:-510px;top:0;}
|
||||
.col-width-2{ max-width: 20%; background: #fff; border:1px solid #e8e8e8;}
|
||||
.col-width-1{ max-width: 10%; background: #fff; border:1px solid #e8e8e8;}
|
||||
/*按钮*/
|
||||
a.task-btn{cursor: pointer;display: inline-block;font-weight: bold;border: none;padding: 0 12px;color: #666;background: #e1e1e1;letter-spacing: 1px;text-align: center;font-size: 14px;height: 30px;line-height: 30px;border-radius: 3px; }
|
||||
a.task-btn-green{background: #29bd8b; color: #fff!important;}
|
||||
a:hover.task-btn-green{background: #19b17e;}
|
||||
a.task-btn-orange{background: #FF7500; color:#fff!important;}
|
||||
a:hover.task-btn-orange{ background:#ff7500;}
|
||||
a.task-newbtn-grey{background-color: #e1e1e1;color: #666666;}
|
||||
a:hover.task-newbtn-grey{color: #333}
|
||||
a.task-btn-blue{background: #199ed8; color:#fff!important;}
|
||||
a:hover.task-btn-blue{background: #199ed8;color:#fff;}
|
||||
a.task-btn-grey{background-color: #d4d6d8; color: #4d555d!important;}
|
||||
a:hover.task-btn-grey{background-color: #d4d6d8; color: #4d555d;}
|
||||
a.task-btn-grey-white{background-color: #c2c4c6; color: #fff;}
|
||||
a:hover.task-btn-grey-white{background-color: #a9abad;}
|
||||
a.new-btn{display: inline-block;border:none; padding:0 10px;color: #666;background: #e1e1e1; text-align:center;font-size: 12px; height: 30px;border-radius: 3px; line-height: 30px;}
|
||||
a.new-btn:hover{background: #c3c3c3; color: #333;}
|
||||
a.new-btn-green{background: #29bd8b; color: #fff;}
|
||||
a.new-btn-green:hover{background:#19b17e; }
|
||||
a.new-btn-blue{background: #6a8abe; color: #fff!important;}
|
||||
a.new-btn-blue:hover{background:#5f7cab; }
|
||||
a.new-bigbtn{display: inline-block;border:none; padding:2px 30px;color: #666;background: #e1e1e1; text-align:center;font-size: 14px; height: 30px;line-height: 30px; border-radius: 3px;}
|
||||
a:hover.new-bigbtn{background: #c3c3c3; color: #333;}
|
||||
a.new-bigbtn-green{background: #3b94d6; color: #fff;}
|
||||
a.new-bigbtn-green:hover{background: #2384cd; color: #fff;}
|
||||
a.task-btn-ver{ height:45px; line-height: 45px; background: #FF7500; color: #fff !important; border-radius:5px; font-size:12px; padding:0 10px;}
|
||||
a.rest-btn-ver{ cursor: not-allowed; background: #ccc;}
|
||||
a.task-btn-ver-line{height:43px; line-height: 43px; border-radius:5px; font-size:12px; padding:0 10px; border:1px solid #ccc;}
|
||||
a:hover.task-btn-ver-line{ border:1px solid #29bd8b;}
|
||||
a:hover.rest-btn-ver{ cursor: not-allowed; background: #ccc;}
|
||||
.new_login_submit_disable{ width:265px; height:40px; line-height: 40px; background:#ccc; color:#fff; font-size:14px; border-radius:5px; border:none; text-align:center; cursor:pointer; vertical-align: middle;}
|
||||
.new_login_submit,a.new_login_submit{ display: block; text-decoration: none !important; width:100%; height:45px; line-height: 45px; background:#29bd8b; color:#fff !important; font-size:14px; border-radius:5px; border:none; text-align:center; cursor:pointer; vertical-align: middle;}
|
||||
.new_login_submit a{ color:#fff !important; text-decoration: none;}
|
||||
.new_login_submit:hover{background: #19b17e;}
|
||||
a.task-btn-email{display: inline-block;font-weight: bold;border: none; width:185px;color: #666;background: #e1e1e1;letter-spacing: 1px;text-align: center;font-size: 14px;height: 40px;line-height: 40px;border-radius: 3px;}
|
||||
a:hover.task-btn-email {background: #c3c3c3; color: #666;}
|
||||
.white-btn{text-align:center;cursor: pointer;display: inline-block;padding: 0px 8px;border: 1px solid #ccc;color: #666;letter-spacing: 1px;font-size: 14px;height: 26px;line-height: 26px;border-radius: 3px;}
|
||||
.white-btn-h40{text-align:center;cursor: pointer;display: inline-block;padding: 5px 10px;border: 1px solid #ccc;color: #666;letter-spacing: 1px;font-size: 14px;height: 26px;line-height: 26px;border-radius: 3px;}
|
||||
a.white-btn.green-btn{color:#29bd8b;border:1px solid #29bd8b; }
|
||||
a.white-btn.gery-btn{color: #aaa;border: 1px solid #aaa}
|
||||
a.white-btn.gery-btn:hover{color: #FFFFFF;border: 1px solid #aaa;background: #aaa}
|
||||
a.white-btn.orange-btn,a.white-btn-h40.orange-btn{color: #FF7500;border: 1px solid #FF7500}
|
||||
a.white-btn.orange-btn:hover,a.white-btn-h40.orange-btn:hover{color: #FFFFFF;border: 1px solid #FF7500;background: #ff7500}
|
||||
a.white-btn.orange-bg-btn,a.white-btn-h40.orange-bg-btn{color: #FFFFFF;border: 1px solid #FF7500;background: #ff7500}
|
||||
a.grey-btn{padding: 0px 8px;height: 30px;line-height: 30px;background-color: #eaeaea;color: #7f7f7f;font-size: 14px;border-radius: 3px;}
|
||||
|
||||
.invite-btn{display: block;padding: 1px 10px;background: #fff;color: #333;border-radius: 4px;}
|
||||
a.decoration{text-decoration: underline!important;}
|
||||
/*07-11 新添加的公用样式 cs*/
|
||||
a.course-btn{cursor: pointer;font-weight: bold;border-radius: 4px;display: inline-block;width: auto;padding: 0px 12px;background-color: #FFFFFF;color: #44bfa3;letter-spacing: 1px;height: 30px;line-height: 30px;}
|
||||
.bc-grey{background-color: #CCCCCC!important;}
|
||||
.bc-white{background-color: #ffffff!important;}
|
||||
a.course-bth-blue{cursor: pointer;background-color:#199ed8 ;color: #ffffff !important;display: inline-block;font-weight: bold;border: none;padding: 0 12px;letter-spacing: 1px;text-align: center;font-size: 14px;height: 30px;line-height: 30px;border-radius: 3px;}
|
||||
a.course-bth-orange{cursor: pointer;background-color:#ff6530 ;color: #ffffff !important;display: inline-block;font-weight: bold;border: none;padding: 0 12px;letter-spacing: 1px;text-align: center;font-size: 14px;height: 30px;line-height: 30px;border-radius: 3px;}
|
||||
.topic-hover a:hover{background:#ff7500;color:#fff;}
|
||||
/*.topic-hover li a:hover{color:#fff;}*/
|
||||
/*提示条*/
|
||||
.alert{ padding:10px;border: 1px solid transparent; text-align: center;}
|
||||
.alert-blue{ background-color: #d9edf7;border-color: #bce8f1; color: #3a87ad;}
|
||||
.alert-orange{ background-color: #fff9e9;border-color: #f6d0b1; color:#ee4a20;}
|
||||
.alert-green{ background-color: #dff0d8;border-color: #d6e9c6; color:#3c763d;}
|
||||
.task-close{padding: 0;cursor: pointer; background: transparent; border: 0; -webkit-appearance: none; font-size: 21px; font-weight: bold;line-height: 1; color: #000000; text-shadow: 0 1px 0 #ffffff; opacity: 0.3;}
|
||||
.taskclose:hover{opacity: 0.5;}
|
||||
.alert-red{background-color: #f2dede;border-color: #eed3d7; color: #d14f4d; text-align: left!important;}
|
||||
/*tag*/
|
||||
.task-tag{ padding:0 10px; text-align: center; display:inline-block; height:30px; line-height: 30px;}
|
||||
.tag-blue{ background-color: #d9edf7; color: #3a87ad;}
|
||||
.tag-grey{ background-color: #f3f5f7; color: #4d555d;}
|
||||
.tag-border-grey{ background-color: #fff;border-color: #e2e2e2; color: #888;}
|
||||
.cir-orange{background: #ff6530;color: #fff; border-radius: 15px; padding: 0 5px; display: inline-block; font-size: 12px; height: 16px;line-height: 16px; }
|
||||
.cir-red{background: red;color: #fff; border-radius: 15px; padding: 0 5px; display: inline-block; font-size: 12px; height: 16px;line-height: 16px; }
|
||||
.red-cir-btn{ background:#e74c3c; padding:1px 5px; -moz-border-radius:2px; -webkit-border-radius:2px; border-radius:2px; color:#fff; font-weight:normal;font-size:12px;}
|
||||
/****************************/
|
||||
/* 页面结构*/
|
||||
.task-pm-content{ width: 1000px; margin: 0 auto; }
|
||||
.task-pm-box{ width: 100%; background: #fff; border: 1px solid #e8e8e8;}
|
||||
.task-paner-con{ padding:15px; color:#666; line-height:2.0;}
|
||||
.task-text-center{ text-align: center;}
|
||||
.flow_hidden{ width:300px;overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
|
||||
/*pre标签换行*/
|
||||
.break_word{word-break: break-all;word-wrap: break-word;}
|
||||
.break_word_firefox{white-space: pre-wrap !important;word-break: break-all;}
|
||||
.pre_word{white-space: pre-wrap;word-wrap: break-word;word-break: normal;}
|
||||
.pr {position:relative;}
|
||||
.df {display:flex;display: -webkit-flex;display: -ms-flex;}
|
||||
.df-js-ac{ justify-content:space-around;-webkit-justify-content: space-around;-webkit-align-items:center;-ms-flex-align:center; align-items: center;}
|
||||
|
||||
.w28 {width: 28px;}
|
||||
.w40{ width: 40px;}
|
||||
.w50{width: 50px;}.edu-txt-w50{ width:50px;}
|
||||
.w60{width: 60px;}
|
||||
.w70{width: 70px;}
|
||||
.w80 {width: 80px;}
|
||||
.w100{width: 100px;}
|
||||
.w120{width: 120px;}
|
||||
.w150{width: 150px;}
|
||||
.w200{width: 200px;}
|
||||
.w300{width: 300px;}
|
||||
.w320{width: 320px;}
|
||||
.edu-w245{ width: 245px; }.w266{width: 266px;}
|
||||
.w780{width: 780px;}
|
||||
.w850{width: 850px;}
|
||||
.w900{width: 900px;}
|
||||
|
||||
|
||||
|
||||
.with10{ width: 10%;}.with15{ width: 15%;}
|
||||
.with20{ width: 20%;}.with25{ width: 25%;}
|
||||
.with30{ width: 30%;}.with35{ width: 35%;}
|
||||
.with40{ width: 40%;}.with45{ width: 45%;}.with49{ width: 49%;}
|
||||
.with50{ width: 50%;}.with55{ width: 55%;}
|
||||
.with52{ width: 52%;}.with48{ width: 48%;}
|
||||
.with60{ width: 60%;}.with65{ width: 65%;}
|
||||
.with70{ width: 70%;}.with73{ width: 73%;}.with75{ width: 75%;}
|
||||
.with70{ width: 70%;}.with73{ width: 73%;}.with75{ width: 75%;}
|
||||
.with80{ width: 80%;}.with85{ width: 85%;}
|
||||
.with87{ width: 87%;}.with90{ width: 90%;}.with95{ width: 95%;}
|
||||
.with100{ width: 100%;}
|
||||
.edu-bg{ background:#fff!important;}
|
||||
.disabled-bg{ background:#eee !important;}
|
||||
.disabled-grey-bg{ background: #a4a4a4 !important;}
|
||||
/* 课程共用 后期再添加至公共样式 bylinda*/
|
||||
a.link-name-dark{ color:#666; max-width:140px; display: block; }
|
||||
a:hover.link-name-dark{ color:#ff7500;}
|
||||
/* 超过宽度省略 */
|
||||
.edu-name-dark{ max-width:100px; display: block; }
|
||||
.edu-info-dark{ max-width:345px; display: block; }
|
||||
.edu-max-h200{ height:200px; overflow: auto;}
|
||||
.edu-h260{ height:260px;}
|
||||
.edu-position{ position: relative;}
|
||||
.edu-h200-auto{ max-height:200px; overflow:auto;}
|
||||
.edu-h300-auto{ max-height:300px; overflow:auto;}
|
||||
.edu-h350-auto{ max-height:350px; overflow:auto;}
|
||||
.edu-txt-w240{ width:240px; display: block;}
|
||||
.edu-txt-w280{ width:280px; display: block;}
|
||||
.edu-txt-w320{ width:320px; display: block;}
|
||||
.edu-txt-w200{ width:200px; display: block;}
|
||||
a.edu-txt-w280,.edu-txt-w280{ width:280px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w190,.edu-txt-w190{ width:190px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w160,.edu-txt-w160{ width:160px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w140,.edu-txt-w140{ width:141px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w130,.edu-txt-w130{ width:130px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w120,.edu-txt-w120{ width:120px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w100,.edu-txt-w100{ width:100px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w90,.edu-txt-w90{ width:90px; display: inline-block;text-align: center}
|
||||
a.edu-txt-w80,.edu-txt-w80{ width:80px; display: inline-block;text-align: center}
|
||||
.overellipsis{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
|
||||
/* 筛选按钮 */
|
||||
.edu-btn-search{ position: absolute; top:0; right:15px;}
|
||||
.edu-bg-light-blue{ background:#f7f9fd; padding:5px;}
|
||||
.edu-con-top{ padding:10px 0; background:#fff; border-bottom:1px solid #eee;font-size:16px; }
|
||||
.edu-con-top h2{ font-size:16px;}
|
||||
.edu-form-label{display: inline-block; width:60px;text-align: right; line-height: 40px; font-weight: normal;}
|
||||
.edu-form-border{ border:1px solid #ddd;}
|
||||
.edu-form-notice-border{ border:1px solid #f27d61 !important;}
|
||||
.edu-form-noborder,input.edu-form-noborder{ border:none; outline:none;}
|
||||
a.edu-btn{display: inline-block;border:none; padding:0 12px;color: #666!important;border:1px solid #ccc; text-align:center;font-size: 14px; height: 29px;line-height: 29px; border-radius:3px; font-weight: bold;letter-spacing:1px;}
|
||||
a:hover.edu-btn{ border:1px solid #5faee3; color: #5faee3!important;}
|
||||
.edu-cir-grey{ display: inline-block; padding:0px 5px; color:#666; background:#f3f3f3; text-align: center; border-radius:15px; font-size:12px; line-height:20px!important;}
|
||||
.edu-cir-grey1{ display: inline-block; padding:0px 5px; margin-left: 5px; color:#666; background:#ccc; text-align: center; border-radius:15px; font-size:12px; line-height:20px!important;}
|
||||
.edu-cir-grey-q{ display: inline-block; padding:0px 7px; color:#666; background:#f3f3f3; text-align: center; border-radius:15px; font-size:12px; line-height:20px!important;}
|
||||
.edu-cir-orange{ display: inline-block; padding:0px 7px; color:#fff; background:#FF7500; text-align: center; border-radius:15px; font-size:12px; line-height:20px!important;}
|
||||
|
||||
/*a.edu-filter-cir-grey{display: inline-block; padding:0px 15px; color:#666; border:1px solid #ddd; text-align: center; border-radius:3px; font-size:12px; height:25px; line-height:25px;}
|
||||
a:hover.edu-filter-cir-grey,a.edu-filter-cir-grey.active{ border:1px solid #3498db; color:#3498db; }*/
|
||||
|
||||
.edu-filter-btn{display: inline-block; padding:0px 3px; color:#666; background:#fff; text-align: center; border-radius:3px; font-size:12px; height:20px; line-height:20px;}
|
||||
.edu-filter-btn-blue{border:1px solid #3498db; color:#3498db;}
|
||||
.edu-filter-btn-orange{border:1px solid #ff5055; color:#ff5055;}
|
||||
.edu-filter-btn-red{border:1px solid #d72e36; color:#d72e36;}
|
||||
.edu-filter-btn-green{border:1px solid #6fbb9d; color:#6fbb9d;}
|
||||
.edu-filter-btn-yellow{border:1px solid #ef9324; color:#ef9324;}
|
||||
.edu-filter-btn-danger{background:#d72e36; color:#fff;}
|
||||
.edu-filter-btn-late{border:1px solid #3fbcff; color: #3fbcff;}
|
||||
.edu-filter-btn-no-late{border:1px solid #8c8c8c;color: #8c8c8c;}
|
||||
.edu-filter-btn-end{border: 1px solid #b6b6b6;color: #b6b6b6;}
|
||||
.eud-pointer{ cursor:pointer;}
|
||||
.edu-bg-grey{ background:#f6f6f6; width:90%; min-width:700px; color:#666;}
|
||||
/* table-1底部边框 */
|
||||
.edu-pop-table{ width: 100%; border:1px solid #eee; border-bottom:none; background:#fff; color:#888;cursor: default}
|
||||
.edu-pop-table tr{ height:40px; }
|
||||
.edu-pop-table tr.edu-bg-grey{ background:#f5f5f5;}
|
||||
.edu-txt-center{ text-align: center;}.edu-txt-left{ text-align: left;}.edu-txt-right{ text-align: right;}
|
||||
.edu-pop-table tr th{ color:#333;border-bottom:1px solid #eee; }
|
||||
.edu-pop-table tr td{border-bottom:1px solid #eee;}
|
||||
.edu-pop-table.table-line tr td,.edu-pop-table.table-line tr th{ border-right:1px solid #eee;}
|
||||
.edu-pop-table.table-line tr td:last-child,.edu-pop-table.table-line tr th:last-child{border-right:none;}
|
||||
.edu-pop-table tr td .alink-name{color: #333!important;}
|
||||
.edu-pop-table tr td .alink-name:hover{color: #FF7500!important;}
|
||||
.edu-pop-table tr td .alink-operate{color: #cccccc!important;}
|
||||
.edu-pop-table tr td .alink-operate:hover{color: #FF7500!important;}
|
||||
/*th行有背景颜色且table无边框*/
|
||||
.edu-pop-table.head-color thead tr{background: #fafbfb}
|
||||
.edu-pop-table.head-color{border: none}
|
||||
.edu-pop-table.head-color tr:last-child td {border: none}
|
||||
/*--表格行间隔背景颜色-*/
|
||||
.edu-pop-table.interval-td thead tr{background: #fafbfb}
|
||||
.edu-pop-table.interval-td tbody tr:nth-child(even){background: #fafbfb}
|
||||
.edu-pop-table.interval-td tbody tr td{border: none}
|
||||
/*--表格行间隔背景颜色(th也没有边框)-*/
|
||||
.edu-pop-table.interval-all{border:none}
|
||||
.edu-pop-table.interval-all thead th{border: none}
|
||||
.edu-pop-table.interval-all thead tr{background: #fafbfb}
|
||||
.edu-pop-table.interval-all tbody tr:nth-child(even){background: #fafbfb}
|
||||
.edu-pop-table.interval-all tbody tr td{border: none;padding:5px 0px}
|
||||
/*--表格行移入背景颜色-*/
|
||||
.edu-pop-table.hover-td tbody tr:hover{background: #EFF9FD}/*悬浮颜色为天蓝色*/
|
||||
.edu-pop-table.hover-td_1 tbody tr:hover{background:#FCF2EC}/*悬浮颜色为浅橙色*/
|
||||
/* table-2全边框 */
|
||||
.edu-pop-table-all{ width: 100%; border:1px solid #eee; background:#fff; color:#888;border-collapse: collapse}
|
||||
.edu-pop-table-all tr{ height:30px; }
|
||||
.edu-pop-table-all tr.edu-bg-grey{ background:#f5f5f5;}
|
||||
.edu-pop-table-all tr th{ color:#333;border:1px solid #eee; }
|
||||
.edu-pop-table-all tr td{border:1px solid #eee;padding: 5px}
|
||||
|
||||
|
||||
|
||||
.edu-line{ border-bottom:1px solid #eee;}
|
||||
table.table-th-grey th{ background:#f5f5f5;}
|
||||
table.table-pa5 th,table.table-pa5 td{ padding:0 5px;}
|
||||
.panel-comment_item .orig_cont-red{ border:solid 2px #cc0000; border-radius:10px; padding:4px;color:#999;margin-top:-1px; }
|
||||
/***** loading ******/
|
||||
/***** Ajax indicator ******/
|
||||
#ajax-indicator {
|
||||
position: absolute; /* fixed not supported by IE*/
|
||||
background-color:#eee;
|
||||
border: 1px solid #bbb;
|
||||
top:35%;
|
||||
left:40%;
|
||||
width:20%;
|
||||
/*height:5%;*/
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
padding:0.6em;
|
||||
z-index:100000;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
html>body #ajax-indicator { position: fixed; }
|
||||
|
||||
#ajax-indicator span{
|
||||
color:#fff;
|
||||
color: #333333;
|
||||
background-position: 0% 40%;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url(/images/loading.gif);
|
||||
padding-left: 26px;
|
||||
vertical-align: bottom;
|
||||
z-index:100000;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------列表结构*/
|
||||
.forum_table .forum_table_item:nth-child(odd){background: #fafbfb}
|
||||
.forum_table_item{padding: 20px 15px;display: flex;}
|
||||
.forum_table_item .item_name{color: #333}
|
||||
.forum_table_item .item_name:hover{color: #FF7500}
|
||||
|
||||
|
||||
.edu-bg{ background:#fff;}
|
||||
/*---------tab切换-----*/
|
||||
.task-tab{width:10%;height:42px;line-height:42px;text-align:center;color:#666;
|
||||
position:relative;cursor:pointer;}
|
||||
.task-tab.sheet{border-bottom:3px solid #5faee3;color:#5faee3;}
|
||||
.task-tab.bold{border-bottom:3px solid #5faee3;font-weight:bold;}
|
||||
.task-tab i{position:absolute;bottom:-9px;left:45%;color:#5faee3 !important;}
|
||||
|
||||
.undis {display: none}
|
||||
.edu-change .panel-form-label{ line-height:1.9;}
|
||||
|
||||
.title_type { line-height: 40px;height: 40px;border-bottom: 1px solid #eee;color: #666;padding-left: 15px; }
|
||||
.teacher_banner {border-bottom: 1px solid #eee}
|
||||
.zbg { background: url("/images/edu_user/richEditer.png") -195px -2px no-repeat; height: 18px; cursor: pointer}
|
||||
.zbg_latex { background: url("/images/edu_user/richEditer.png") -315px -3px no-repeat;height: 18px;cursor: pointer;}
|
||||
.latex{position:relative;top: 4px;}
|
||||
|
||||
.white_bg {background: #fff}
|
||||
.user_tab_type {background: #FF6610}
|
||||
|
||||
/*首页----------筛选切换(有数字)*/
|
||||
.user_course_filtrate{width: auto;text-align: center;line-height: 26px;}
|
||||
.user_filtrate_span1_bg{color: #FF7500}
|
||||
.user_filtrate_span2{width: auto;padding: 0px 6px;border-radius: 8px;background: #ccc;font-size: 12px;display: block;line-height: 15px;float: right;color: #FFFFFF; margin-top: 6px;}
|
||||
.user_filtrate_span2_bg{background: #FF7500!important;}
|
||||
.user_course_filtrate:hover .user_filtrate_span1{color: #FF7500!important;}
|
||||
.user_course_filtrate:hover .user_filtrate_span2{background: #FF7500!important;}
|
||||
/*课堂----------筛选切换(没有数字,默认白色背景)*/
|
||||
.course_filtrate{width: auto;padding:0px 10px;text-align: center;background: #eeeeee;border-radius: 10px;margin-right: 20px;line-height: 26px;}
|
||||
.course_filtrate:hover{background: #FF7500; color: #ffffff; }
|
||||
.course_filtrate_bg{background: #FF7500; color: #ffffff!important; }
|
||||
/*我的课堂----------筛选切换(没有数字,默认灰色背景)*/
|
||||
.edu-filter-cir-grey{color: #666!important;width: auto;padding:0px 15px;text-align: center;background: #f3f3f3;border-radius: 10px;display: block; height:25px; line-height:25px;}
|
||||
.edu-filter-cir-grey:hover{background: #FF7500; color: #ffffff!important;}
|
||||
.edu-filter-cir-grey.active{background: #FF7500; color: #ffffff!important;}
|
||||
|
||||
.edu-find .edu-find-input{border-bottom: 1px solid #EEEEEE;}
|
||||
.edu-find .edu-find-input input{border: none;outline: none}
|
||||
.edu-find .edu-close{position: absolute;top: -1px;right: 7px;font-size: 18px;cursor: pointer;}
|
||||
.edu-find .edu-open{position: absolute;top: 1px;right: -18px}
|
||||
|
||||
|
||||
/*最新和最热导航条的公用样式*/
|
||||
.nav_check_item{margin-bottom:13px;border-bottom: 2px solid #FC7033;}
|
||||
.nav_check_item li{width:auto;width: 80px;text-align: center;cursor: pointer;height: 38px;line-height: 38px;border-top-right-radius:5px;border-top-left-radius:5px;}
|
||||
.nav_check_item li a{display: block;width: 100%;}
|
||||
|
||||
.check_nav{background: #FC7033;color: #ffffff;}
|
||||
.check_nav a{color: #ffffff !important;}
|
||||
.check_on{background:#FF7500;color: #ffffff!important;border-radius: 4px;}
|
||||
|
||||
/*实训列表块里面的遮罩效果*/
|
||||
.black-half{position: absolute;left: 0;top:0px;width: 100%;height: 100%;background: rgba(0,0,0,0.4);z-index: 3;display: none;}
|
||||
.black-half-lock{width: 65px;height: 65px;border-radius: 50%;background:#8291a3;vertical-align: middle;text-align: center;margin:25% auto 0px;}
|
||||
.black-half-lock i{margin-top: 7px;}
|
||||
.black-half-info{width: 100%;text-align: center;color: #FFFFFF;margin-top:10px}
|
||||
.show-black{display: block;animation: black-down 1s linear 1;}
|
||||
@-webkit-keyframes black-down {
|
||||
25% {-webkit-transform: translateY(0);}
|
||||
50%, 100% {-webkit-transform: translateY(0);}
|
||||
}
|
||||
|
||||
@keyframes black-down {
|
||||
25% {transform: translateY(0);}
|
||||
50%, 100% {transform: translateY(0);}
|
||||
}
|
||||
|
||||
/*去掉IE input框输入时自带的清除按钮*/
|
||||
input::-ms-clear{display:none;}
|
||||
|
||||
|
||||
/*最小高度*/
|
||||
.mh750{min-height: 750px}
|
||||
.mh650{min-height: 650px}
|
||||
.mh580{min-height: 580px}
|
||||
.mh550{min-height: 550px}
|
||||
.mh510{min-height: 510px}
|
||||
.mh440{min-height: 440px}
|
||||
.mh400{min-height: 400px}
|
||||
.mh390{min-height: 390px}
|
||||
.mh360{min-height: 360px}
|
||||
.mh350{min-height: 350px}
|
||||
.mh320{min-height: 320px}
|
||||
.mh240{min-height: 240px}
|
||||
.mh200{min-height: 200px}
|
||||
|
||||
/*---------------操作部分虚线边框-----------------*/
|
||||
.border-dash-orange{border: 1px dashed #ffbfaa}
|
||||
/*错误、危险、失败提示边框*/
|
||||
.border-error-result{border:1px dashed #ff5252}
|
||||
|
||||
.border-dash-ccc{border-top:1px dashed #ccc;border-bottom:1px dashed #ccc;}
|
||||
|
||||
.login-error{border:1px solid #ff5252!important;}/*登录时,输入的手机号码或者密码错误,边框变红*/
|
||||
.error-red{border: 1px solid #DB6666;background: #FFE6E5;border-radius: 3px;padding: 2px 10px;}
|
||||
.error-red i{color: #FF6666}
|
||||
|
||||
|
||||
/*---------------tab公用背景颜色-----------------*/
|
||||
.background-blue{background:#5ECFBA!important;}
|
||||
.background-orange{background: #FC7033!important;}
|
||||
.back-orange-main{background: #FC7500!important;color:#FFFFff!important;}/*主流橙色*/
|
||||
.back-orange-01{background: #FF9e6a!important;}/*带背景标题、带色彩分割线和操作入口*/
|
||||
.back-f6-grey{background: #F6F6F6;}
|
||||
.background-blue a{color:#ffffff!important;}
|
||||
.background-orange a{color: #ffffff!important;}
|
||||
/*---------------tab公用边框-----------------*/
|
||||
.border-bottom-orange{border-bottom: 2px solid #FC7033!important;}
|
||||
.bor-bottom-orange{border-bottom: 1px solid #FF9e6a!important;}
|
||||
.bor-bottom-greyE{border-bottom: 1px solid #EEEEEE!important;}
|
||||
.bor-top-greyE{border-top: 1px solid #EEEEEE!important;}
|
||||
/*---------------边框-----------------*/
|
||||
.bor-gray-c{border:1px solid #ccc;}
|
||||
.bor-grey-e{border:1px solid #eee;}
|
||||
.bor-grey-d{border:1px solid #ddd;}
|
||||
.bor-grey01{border:1px solid #E6EAEB;}
|
||||
.bor-blue{border:1px solid #5faee3;}
|
||||
.bor-red{border:1px solid #db0505 !important;}
|
||||
.bor-none{border:none;}
|
||||
.bor-outnone{outline:none; border:0px;}
|
||||
/*延时*/
|
||||
.delay{border:1px solid #db0505;padding: 0px 10px;height: 23px;line-height: 23px;border-radius: 12px;display: block;float: left;color:#db0505 }
|
||||
/*
|
||||
tip公共样式的设置:
|
||||
|
||||
*/
|
||||
.-task-title{opacity:0;position:absolute;left:0;top:0;display:none;z-index:100000;} /*1*/
|
||||
.data-tip-down,.data-tip-left,.data-tip-right,.data-tip-top{ position:relative; box-shadow:0px 0px 8px #000; background:#000; color:#fff; max-width:300px;/*2*/
|
||||
word-wrap: break-word; text-align:center; border-radius:4px; padding:0 10px; border:1px solid #000; display:none; }/*3*/
|
||||
.data-tip-down:after,.data-tip-down:before,.data-tip-left:before,.data-tip-right:before,.data-tip-left:after,.data-tip-right:after,.data-tip-top:after,.data-tip-top:before{/*4*/
|
||||
position: absolute;content:''; width:0; height:0;}/*5*/
|
||||
.data-tip-down:after,.data-tip-down:before{left: 45%;top:-10px;/*6*/
|
||||
border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 10px solid #000; }/*7*/
|
||||
.data-tip-down:before{top:-11px;border-bottom:10px solid #000;}/*8*/
|
||||
.data-tip-left:after,.data-tip-left:before{left: -10px;top:50%; margin-top:-5px;/*9*/
|
||||
border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-right: 10px solid #000; }/*10*/
|
||||
.data-tip-left:before{ left: -12px;border-right: 10px solid #000; }/*11*/
|
||||
.data-tip-right:after,.data-tip-right:before{right: -10px; top:50%; margin-top:-5px;/*12*/
|
||||
border-top: 5px solid transparent;border-bottom: 5px solid transparent; border-left: 10px solid #000; }/*13*/
|
||||
.data-tip-right:before{ right: -10px;border-left: 10px solid #000; }/*14*/
|
||||
.data-tip-top:after,.data-tip-top:before{left: 45%;bottom:-10px;border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;border-top: 10px solid #000;}
|
||||
.data-tip-top:before{bottom:-11px;}
|
||||
|
||||
/*-------------------------圆角-------------------------*/
|
||||
.bor-radius-upper{border-radius: 4px 4px 0px 0px;}
|
||||
.bor-radius4{border-radius: 4px;}
|
||||
.bor-radius20{border-radius: 20px;}
|
||||
.bor-radius-all{border-radius: 50%;}
|
||||
|
||||
/*-------------------------旋转-------------------------*/
|
||||
.transform90{transform: rotate(90deg);}
|
||||
/*---------------------编辑器边框------------------------*/
|
||||
.kindeditor{background: #F0F0EE;height:22px;border:1px solid #CCCCCC;border-bottom: none}
|
||||
|
||||
/*文本框只有下边框*/
|
||||
.other_input{border: none;border-bottom: 1px solid #aaa;outline: none}
|
||||
/*两端对齐*/
|
||||
.justify{text-align: justify!important;}
|
||||
|
||||
/**/
|
||||
#edu-tab-nav .edu-position-hidebox li a{font-size: 12px}
|
||||
/*在线课堂*/
|
||||
.courseRefer{float:left; max-height:120px;margin-bottom:10px;overflow:auto; overflow-x:hidden;}
|
||||
.logo {width: 295px;height: 30px;border-style:none;position: absolute;top:50%;left:39%;}
|
||||
/**/
|
||||
.task-header-info .fork{font-weight:bold;font-size:14px;color:#666;}
|
||||
|
||||
|
||||
.memos_con a{color: #3b94d6!important;}
|
||||
.memos_con ul li{ list-style-type: disc!important; }
|
||||
.memos_con ol li{ list-style-type: decimal!important; }
|
||||
.memos_con li{ margin-bottom: 0!important; }
|
||||
.memos_con pre {overflow-x: auto;}
|
||||
|
||||
/*详情a标签默认显示样式*/
|
||||
.a_default_show a{color: #136ec2!important}
|
||||
|
||||
/*消息机制右侧小三角*/
|
||||
.tiding{width: 100%;height: 50px ;position: relative}
|
||||
.triangle {position: absolute;right: -1px;top:0px;width: 0;height: 0;border-top: 35px solid #29bd8b;border-left: 60px solid transparent;z-index: 1}
|
||||
.triangle-new{position: absolute;right: 1px;top: 0px;z-index: 2;font-size: 14px;color: white;transform: rotate(30deg);}
|
||||
.news_list_item{padding: 10px 0px;}
|
||||
.news_list_item:nth-child(odd){background-color:#FAFBFB }
|
||||
.listItem_right{line-height: 45px;float: right;max-width: 100px;margin-right: 15px;color: #888888}
|
||||
.listItem_middle{max-width: 980px;}
|
||||
.news_fa{font-size: 30px;color: #888;margin: 7px 16px;}
|
||||
.tiding_logo{text-align:center;background: #f3f3f3;width: 200px;height: 100px}
|
||||
|
||||
.tr-position{position: absolute;left:54%;width: 20px;text-align: center;border: none!important;}
|
||||
|
||||
.two_lines_show{ overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;height: 60px; word-wrap: break-word;}
|
||||
.two_lines_show_my{ overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;height: 40px; word-wrap: break-word;}
|
||||
.three_lines_show{ overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 3;-webkit-box-orient: vertical;height: 66px;line-height: 22px; word-wrap: break-word;}
|
||||
|
||||
/*新版讨论区*/
|
||||
.discuss-tab a:hover{border-bottom: 2px solid #FC7033!important; color:#000;}
|
||||
.discuss-lh40{ line-height:40px;}.discuss-lh16{ line-height:16px}.discuss-lh20{ line-height:20px;}.discuss-lh20{ line-height:20px;}.discuss-lh30{ line-height:30px;}.discuss-lh50{ line-height:50px;}.discuss-lh60{line-height:60px}.discuss-lh80{line-height:80px;}.discuss-lh100{line-height:100px;}
|
||||
.discuss-bor-l{ border-left:4px solid #ff7500;}
|
||||
.page-turn:hover{background:#fff; color:#FF7500;}
|
||||
|
||||
/*实训路径/镜像类别图片*/
|
||||
.hor-ver-center{width:80px; height:80px; position:absolute; left:50%; top:50%; margin-left:-40px; margin-top:-40px;}
|
||||
.hor-ver-center100{width:100px; height:100px; position:absolute; left:50%;top:25%; margin-left:-50px; margin-top:-25px;}
|
||||
.mirror-shade{ background: rgba(0,0,0,0.4); z-index: 3; display:none;}
|
||||
|
||||
.position20{position:absolute; top:-60px; left:7%;}
|
||||
|
||||
/*--------TA的主页、关注*/
|
||||
.user_watch{width: 78px;padding: 2px 0px!important;}
|
||||
|
||||
|
||||
/*-------------主页块的背景颜色----------------*/
|
||||
.edu-index-bg-green{ background:#5bcab1;}
|
||||
.edu-index-bg-blue{ background:#75b9de;}
|
||||
.edu-index-bg-purple{ background:#8f97df;}
|
||||
.edu-index-bg-yellow{ background:#f7bb74;}
|
||||
.edu-index-bg-orange{ background:#e48a81;}
|
||||
|
||||
|
||||
/*-------------提示框颜色----------------*/
|
||||
.bor-reds{
|
||||
border:1px solid #FF0000!important;
|
||||
border-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3,11 +3,8 @@
|
|||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<!--<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- width=device-width, initial-scale=1 , shrink-to-fit=no -->
|
||||
<!-- <meta name="viewport" content=""> -->
|
||||
<meta name=”Keywords” Content=”EduCoder,信息技术实践教学,精品课程网,慕课MOOC″>
|
||||
<meta name=”Keywords” Content=”实践课程,项目实战,java实训,python实战,人工智能技术,后端开发学习,移动开发入门″>
|
||||
<meta name=”Keywords” Content=”翻转课堂,高效课堂创建,教学模式″>
|
||||
|
|
@ -18,28 +15,11 @@
|
|||
<meta name=”Description” Content=”EduCoder翻转课堂教学模式,颠覆了传统教学模式,让教师与学生的关系由“权威”变成了“伙伴”。将学习的主动权转交给学生,使学生可个性化化学,学生的学习主体得到了彰显。”>
|
||||
<meta name=”Description” Content=”EduCoder实训项目为单个知识点关卡实践训练,帮助学生巩固单一弱点,强化学习。 ”>
|
||||
<meta name=”Description” Content=”EduCoder实践教学平台,各类大赛为进一步提高各类学生综合运用高级语言程序设计能力,培养创新意识和实践探索精神,发掘优秀软件人才。 ”>
|
||||
<!-- <meta name="viewport" id="viewport" content="width=device-width, initial-scale=0.3, maximum-scale=0.3, user-scalable=no">-->
|
||||
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=0.3, maximum-scale=0.3">
|
||||
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--<meta http-equiv="cache-control" content="no-cache,no-store, must-revalidate" />-->
|
||||
<!--<meta http-equiv="pragma" content="no-cache" />-->
|
||||
<!--<meta http-equiv="Expires" content="0" />-->
|
||||
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
||||
<!-- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">-->
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<!-- <title>EduCoder</title>-->
|
||||
<!--react-ssr-head-->
|
||||
<script type="text/javascript">
|
||||
|
||||
window.__isR = true;
|
||||
|
|
@ -59,42 +39,11 @@
|
|||
document.write('<script type="text/javascript" src="/javascripts/wx/jweixin-1.3.0.js"><\/script>');
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- <link rel="stylesheet" type="text/css" href="/css/edu-common.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/edu-public.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/taskstyle.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/font-awesome.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/editormd.min.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/merge.css"> -->
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/css_min_all.css">
|
||||
|
||||
<!--<link rel="stylesheet" type="text/css" href="/css/css_min_all.css">-->
|
||||
|
||||
<!--<link rel="stylesheet" type="text/css" href="//at.alicdn.com/t/font_653600_nm6lho7nxxq.css">-->
|
||||
|
||||
<!-- <link href="/react/build/css/iconfont.css" rel="stylesheet" type="text/css"> -->
|
||||
|
||||
<!--<link href="http://47.96.87.25:48080/stylesheets/educoder/edu-all.css" rel="stylesheet" type="text/css">-->
|
||||
|
||||
<!--<link href="https://pandao.github.io/editor.md/examples/css/style.css" rel="stylesheet" type="text/css">-->
|
||||
|
||||
<!--<link href="https://pandao.github.io/editor.md/css/editormd.preview.css" rel="stylesheet" type="text/css">-->
|
||||
<!-- <link href="https://testeduplus2.educoder.net/stylesheets/css/edu-common.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<link href="https://testeduplus2.educoder.net/stylesheets/educoder/edu-main.css" rel="stylesheet" type="text/css">
|
||||
<link href="https://testeduplus2.educoder.net/stylesheets/educoder/antd.min.css" rel="stylesheet" type="text/css"> -->
|
||||
|
||||
<!-- <link rel="stylesheet" type="text/css" href="https://www.educoder.net/stylesheets/css/font-awesome.css?1510652321"> -->
|
||||
|
||||
<!--<link rel="stylesheet" type="text/css" href="http://47.96.87.25:48080/stylesheets/educoder/iconfont/iconfont.css">-->
|
||||
|
||||
<!--需要去build js配置-->
|
||||
<link rel="stylesheet" type="text/css" href="/css/iconfont.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/quill/1.3.7/quill.core.min.css">
|
||||
<style>
|
||||
/*<!--去除浏览器点击操作后有蓝色的底块-->*/
|
||||
|
|
@ -106,70 +55,19 @@
|
|||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<!--用于markdown转html -->
|
||||
<div id="md_div" style="display: none;"></div>
|
||||
<div id="root" class="page -layout-v -fit widthunit">
|
||||
<!--<div class="d2-home">-->
|
||||
<!--<div class="d2-home__main">-->
|
||||
<!--<!–<img class="d2-home__loading"–>-->
|
||||
<!--<!–src="loading-spin.svg"–>-->
|
||||
<!--<!–alt="loading">–>-->
|
||||
<!--<div class="lds-ripple"><div></div><div></div></div>-->
|
||||
<!--<div class="d2-home__title">-->
|
||||
<!--正在加载资源-->
|
||||
<!--</div>-->
|
||||
<!--<div class="d2-home__sub-title">-->
|
||||
<!--加载资源可能需要较多时间 请耐心等待-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="d2-home__footer">-->
|
||||
<!--<!–<a href="www.educoder.net"–>-->
|
||||
<!--<!–target="_blank">–>-->
|
||||
<!--<!––>-->
|
||||
<!--<!–</a>–>-->
|
||||
<!--EduCoder-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
|
||||
</div>
|
||||
<div id="picture_display" style="display: none;"></div>
|
||||
<!-- js css合并 文件优先级的问题 -->
|
||||
<script type="text/javascript" src="/js/js_min_all.js"></script>
|
||||
<!-- <script type="text/javascript" src="/js/js_min_all_2.js"></script> -->
|
||||
|
||||
<!--
|
||||
<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" src="/js/editormd/underscore.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/js/editormd/marked.min.js"></script>
|
||||
<script type="text/javascript" src="/js/editormd/prettify.min.js"></script>
|
||||
<script type="text/javascript" src="/js/editormd/raphael.min.js"></script>
|
||||
<script type="text/javascript" src="/js/editormd/sequence-diagram.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/js/editormd/flowchart.min.js"></script>
|
||||
<script type="text/javascript" src="/js/editormd/jquery.flowchart.min.js"></script>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="/js/editormd/editormd.min.js"></script>
|
||||
-->
|
||||
<!-- codemirror addon -->
|
||||
<!--
|
||||
<script type="text/javascript" src="/js/codemirror/codemirror.js"></script>
|
||||
<script type="text/javascript" src="/js/codemirror/mode/javascript.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/js/diff_match_patch.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/js/merge.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/js/edu_tpi.js"></script>
|
||||
-->
|
||||
<!-- testbdweb.trustie.net testbdweb.educoder.net -->
|
||||
|
||||
|
||||
<!-- 在tpi js里加载这3个脚本 -->
|
||||
<script>
|
||||
(function() { // Scoping function to avoid globals
|
||||
|
|
@ -199,15 +97,7 @@
|
|||
|
||||
})();
|
||||
</script>
|
||||
<!-- <script type="text/javascript" src="https://testeduplus2.educoder.net/assets/kindeditor/kindeditor.js"></script>
|
||||
<script type="text/javascript" src="/js/create_kindeditor.js"></script>
|
||||
<script type="text/javascript" src="https://testeduplus2.educoder.net/javascripts/educoder/edu_application.js"></script> -->
|
||||
<script type="text/javascript" src="https://cdn.bootcss.com/quill/1.3.7/quill.core.min.js"></script>
|
||||
|
||||
<!-- <script>-->
|
||||
<!-- document.body.addEventListener('touchmove', function (e) {-->
|
||||
<!-- e.preventDefault(); //阻止默认的处理方式(阻止下拉滑动的效果)-->
|
||||
<!-- }, {passive: false});-->
|
||||
<!-- </script>-->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ function generateNewIndexJsp() {
|
|||
// combinedStream.append(htmlContent);
|
||||
// combinedStream.pipe(fs2.createWriteStream( filePath ));
|
||||
|
||||
var outputPath = paths.appBuild + '/../../../index.html'
|
||||
var outputPath = paths.appBuild + '/index.html'
|
||||
fs2.readFile(filePath, 'utf8', function (err,data) {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
|
|
@ -197,12 +197,12 @@ function generateNewIndexJsp() {
|
|||
cdnHost = ''
|
||||
|
||||
|
||||
var mainRegex = /<script type="text\/javascript" src="\/forgeplus-react\/build\/.\/static\/js\/main.([a-zA-Z0-9]{8,}).js"><\/script>/
|
||||
var mainRegex = /<script type="text\/javascript" src="\/react\/build\/.\/static\/js\/main.([a-zA-Z0-9]{8,}).js"><\/script>/
|
||||
var matchResult = data.match(mainRegex)
|
||||
var code = `
|
||||
<script>
|
||||
(function() {
|
||||
var _host = '/forgeplus-react/build/'
|
||||
var _host = '/react/build/'
|
||||
/**/
|
||||
if (window.location.host == 'pre-newweb.educoder.net') {
|
||||
_host = 'https://testali-cdn.educoder.net/react/build/'
|
||||
|
|
|
|||
31
src/App.js
31
src/App.js
|
|
@ -1,6 +1,6 @@
|
|||
import React, {Component} from 'react';
|
||||
import './public-path';
|
||||
import logo from './logo.svg';
|
||||
// import logo from './logo.svg';
|
||||
import './App.css';
|
||||
import {ConfigProvider} from 'antd'
|
||||
import zhCN from 'antd/lib/locale-provider/zh_CN';
|
||||
|
|
@ -21,9 +21,9 @@ import Trialapplicationreview from './modules/user/Trialapplicationreview';
|
|||
import Addcourses from "./modules/courses/coursesPublic/Addcourses";
|
||||
import AccountProfile from "./modules/user/AccountProfile";
|
||||
import Accountnewprofile from './modules/user/Accountnewprofile';
|
||||
import Trialapplication from './modules/login/Trialapplication';
|
||||
// import Trialapplication from './modules/login/Trialapplication';
|
||||
import Certifiedprofessional from './modules/modals/Certifiedprofessional';
|
||||
import NotFoundPage from './NotFoundPage'
|
||||
// import NotFoundPage from './NotFoundPage'
|
||||
|
||||
import Loading from './Loading'
|
||||
|
||||
|
|
@ -481,12 +481,12 @@ class App extends Component {
|
|||
this.setState({
|
||||
mygetHelmetapi: undefined
|
||||
});
|
||||
document.title = "EduCoder";
|
||||
// document.title = "Forge";
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
link.rel = 'shortcut icon';
|
||||
link.href = "/forgeplus-react/build/./favicon.ico";
|
||||
link.href = "/react/build/./favicon.ico";
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink);
|
||||
}
|
||||
|
|
@ -573,12 +573,6 @@ class App extends Component {
|
|||
}
|
||||
}></Route>
|
||||
|
||||
<Route exact path="/"
|
||||
// component={ShixunsHome}
|
||||
render={
|
||||
(props)=>(<ProjectIndex {...this.props} {...props} {...this.state}></ProjectIndex>)
|
||||
}
|
||||
/>
|
||||
{/*题库*/}
|
||||
<Route path="/topicbank/:username/:topicstype"
|
||||
render={
|
||||
|
|
@ -778,11 +772,18 @@ class App extends Component {
|
|||
{/* (props)=>(<WXCode {...this.props} {...props} {...this.state}></WXCode>)*/}
|
||||
{/* }*/}
|
||||
{/*/>*/}
|
||||
{/*<Route exact path="/"*/}
|
||||
{/*// component={ShixunsHome}*/}
|
||||
{/*render={*/}
|
||||
{/*(props)=>(<ShixunsHome {...this.props} {...props} {...this.state}></ShixunsHome>)*/}
|
||||
{/*}*/}
|
||||
{/*/>*/}
|
||||
|
||||
<Route exact path="/"
|
||||
// component={ShixunsHome}
|
||||
render={
|
||||
(props)=>(<ShixunsHome {...this.props} {...props} {...this.state}></ShixunsHome>)
|
||||
}
|
||||
// component={ShixunsHome}
|
||||
render={
|
||||
(props)=>(<ProjectIndex {...this.props} {...props} {...this.state}></ProjectIndex>)
|
||||
}
|
||||
/>
|
||||
<Route component={Shixunnopage}/>
|
||||
|
||||
|
|
|
|||
314
src/AppConfig.js
314
src/AppConfig.js
|
|
@ -3,7 +3,7 @@ import React from "react";
|
|||
import axios from 'axios';
|
||||
import md5 from 'md5';
|
||||
import { requestProxy } from "./indexEduplus2RequestProxy";
|
||||
import { broadcastChannelOnmessage ,SetAppModel, isDev, queryString } from 'educoder';
|
||||
import { broadcastChannelOnmessage , isDev, queryString } from 'educoder';
|
||||
import { notification } from 'antd';
|
||||
import cookie from 'react-cookies';
|
||||
import './index.css';
|
||||
|
|
@ -30,7 +30,7 @@ function locationurl(list){
|
|||
|
||||
|
||||
// TODO 开发期多个身份切换
|
||||
let debugType =""
|
||||
let debugType =""
|
||||
if (isDev) {
|
||||
const _search = window.location.search;
|
||||
let parsed = {};
|
||||
|
|
@ -49,9 +49,6 @@ if (isDev) {
|
|||
//debugType="student";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function clearAllCookie() {
|
||||
cookie.remove('_educoder_session', {path: '/'});
|
||||
cookie.remove('autologin_trustie', {path: '/'});
|
||||
|
|
@ -114,36 +111,12 @@ setpostcookie();
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
initOnlineOfflineListener()
|
||||
|
||||
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
|
||||
// https://github.com/axios/axios/issues/1497
|
||||
|
||||
// TODO 读取到package.json中的配置?
|
||||
var proxy = "http://localhost:3000"
|
||||
// proxy = "http://testbdweb.trustie.net"
|
||||
// proxy = "http://testbdweb.educoder.net"
|
||||
// proxy = "https://testeduplus2.educoder.net"
|
||||
//proxy="http://47.96.87.25:48080"
|
||||
// proxy="https://pre-newweb.educoder.net"
|
||||
// proxy="https://test-newweb.educoder.net"
|
||||
// proxy="https://test-jupyterweb.educoder.net"
|
||||
// proxy="https://test-newweb.educoder.net"
|
||||
// proxy="https://test-jupyterweb.educoder.net"
|
||||
//proxy="http://192.168.2.63:3001"
|
||||
|
||||
var //proxy = "http://localhost:3000"
|
||||
// proxy="http://123.59.135.93:56666"
|
||||
proxy="http://localhost:3000"
|
||||
|
||||
// 在这里使用requestMap控制,避免用户通过双击等操作发出重复的请求;
|
||||
// 如果需要支持重复的请求,考虑config里面自定义一个allowRepeat参考来控制
|
||||
var //proxy = "http://localhost:3000"
|
||||
proxy="https://testforgeplus.trustie.net/"
|
||||
const requestMap = {};
|
||||
|
||||
window.setfalseInRequestMap = function(keyName) {
|
||||
|
|
@ -153,243 +126,110 @@ export function initAxiosInterceptors(props) {
|
|||
//响应前的设置
|
||||
axios.interceptors.request.use(
|
||||
config => {
|
||||
setpostcookie()
|
||||
clearAllCookie()
|
||||
// config.headers['Content-Type']= 'no-cache'
|
||||
// if (token) { // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
|
||||
// config.headers.Authorization = token;
|
||||
// }
|
||||
setpostcookie()
|
||||
clearAllCookie()
|
||||
if (config.url.indexOf(proxy) !== -1 || config.url.indexOf(':') !== -1) {
|
||||
return config
|
||||
}
|
||||
requestProxy(config)
|
||||
|
||||
// --------------------------------------------- 測試3007连测试服的代码
|
||||
// if (url.indexOf('file_update') != -1 || url.indexOf('game_build') != -1 || url.indexOf('game_status') != -1) {
|
||||
// proxy = 'https://testbdweb.trustie.net'
|
||||
// } else {
|
||||
// proxy = 'http://localhost:3000'
|
||||
// }
|
||||
// ---------------------------------------------
|
||||
// console.log("开始请求了");
|
||||
// console.log(config.url);
|
||||
// console.log(window.location.pathname);
|
||||
//
|
||||
let url = `/api${config.url}`;
|
||||
|
||||
// try {
|
||||
// const str =window.location.pathname;
|
||||
// if(str.indexOf("/wxcode") !== -1){
|
||||
// // console.log("开始重写cookis");
|
||||
// const _params = window.location.search;
|
||||
// // console.log("1111");
|
||||
// if (_params) {
|
||||
// // console.log("22222");
|
||||
// let _search = _params.split('?')[1];
|
||||
// var _educoder_sessionmys="";
|
||||
// var autologin_trusties="";
|
||||
// _search.split('&').forEach(item => {
|
||||
// const _arr = item.split('=');
|
||||
// if(_arr[0]==='_educoder_session'){
|
||||
// cookie.save('_educoder_session',_arr[1], { domain: '.educoder.net', path: '/'});
|
||||
// _educoder_sessionmys=_arr[1];
|
||||
// }else{
|
||||
// cookie.save('autologin_trustie',_arr[1], { domain: '.educoder.net', path: '/'});
|
||||
// autologin_trusties=_arr[1];
|
||||
// }
|
||||
// });
|
||||
// try {
|
||||
// const autlogins= `_educoder_session=${_educoder_sessionmys}; autologin_trustie=${autologin_trusties} `;
|
||||
// config.params = {'Cookie': autlogins}
|
||||
// config.headers['Cookie'] =autlogins;
|
||||
// // console.log("设置了cookis");
|
||||
// } catch (e) {
|
||||
//
|
||||
// }
|
||||
// try {
|
||||
// const autloginysls= `_educoder_session=${_educoder_sessionmys}; autologin_trustie=${autologin_trusties} `;
|
||||
// config.params = {'autloginysls': autloginysls}
|
||||
// config.headers['Cookie'] =autloginysls;
|
||||
// // console.log("设置了cookis");
|
||||
// }catch (e) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }catch (e) {
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
if (config.url.indexOf(proxy) != -1 || config.url.indexOf(':') != -1) {
|
||||
return config
|
||||
//qq登录去掉api
|
||||
if(config.params&&config.params.redirect_uri!=undefined){
|
||||
if(config.params.redirect_uri.indexOf('otherloginqq')!=-1){
|
||||
url = `${config.url}`;
|
||||
}
|
||||
requestProxy(config)
|
||||
|
||||
let url = `/api${config.url}`;
|
||||
|
||||
//qq登录去掉api
|
||||
if(config.params&&config.params.redirect_uri!=undefined){
|
||||
if(config.params.redirect_uri.indexOf('otherloginqq')!=-1){
|
||||
url = `${config.url}`;
|
||||
}
|
||||
}
|
||||
if(`${config[0]}`!=`true`){
|
||||
let timestamp = Date.parse(new Date())/1000;
|
||||
if (window.location.port === "3007") {
|
||||
// let timestamp=railsgettimes(proxy);
|
||||
// console.log(timestamp)
|
||||
// `https://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp`
|
||||
railsgettimes( `${proxy}/api/main/first_stamp.json`);
|
||||
let newopens=md5(opens+timestamp)
|
||||
config.url = `${proxy}${url}`;
|
||||
if (config.url.indexOf('?') == -1) {
|
||||
config.url = `${config.url}?debug=${debugType}&randomcode=${timestamp}&client_key=${newopens}`;
|
||||
} else {
|
||||
config.url = `${config.url}&debug=${debugType}&randomcode=${timestamp}&client_key=${newopens}`;
|
||||
}
|
||||
}
|
||||
if(`${config[0]}`!=`true`){
|
||||
let timestamp = Date.parse(new Date())/1000;
|
||||
if (window.location.port === "3007") {
|
||||
config.url = `${proxy}${url}`;
|
||||
if (config.url.indexOf('?') == -1) {
|
||||
config.url = `${config.url}?debug=${debugType}`;
|
||||
} else {
|
||||
// 加api前缀
|
||||
// railsgettimes(`http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp`);
|
||||
|
||||
railsgettimes( `/api/main/first_stamp.json`);
|
||||
let newopens=md5(opens+timestamp)
|
||||
config.url = url;
|
||||
if (config.url.indexOf('?') == -1) {
|
||||
config.url = `${config.url}?randomcode=${timestamp}&client_key=${newopens}`;
|
||||
} else {
|
||||
config.url = `${config.url}&randomcode=${timestamp}&client_key=${newopens}`;
|
||||
}
|
||||
config.url = `${config.url}&debug=${debugType}`;
|
||||
}
|
||||
setpostcookie();
|
||||
}
|
||||
//
|
||||
// console.log(config);
|
||||
} else {
|
||||
// 加api前缀
|
||||
config.url = url;
|
||||
}
|
||||
setpostcookie();
|
||||
}
|
||||
if (config.method === "post") {
|
||||
if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息
|
||||
// console.log(config);
|
||||
// console.log(JSON.parse(config));
|
||||
// console.log(config.url);
|
||||
// console.log("被阻止了是重复请求=================================");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 非file_update请求
|
||||
if (config.url.indexOf('update_file') === -1) {
|
||||
requestMap[config.url] = true;
|
||||
// 非file_update请求
|
||||
if (config.url.indexOf('update_file') === -1) {
|
||||
requestMap[config.url] = true;
|
||||
|
||||
window.setTimeout("setfalseInRequestMap('"+config.url+"')", 900)
|
||||
}
|
||||
// setTimeout("setfalseInRequestMap(" + config.url + ")", 1200)
|
||||
return config;
|
||||
window.setTimeout("setfalseInRequestMap('"+config.url+"')", 900)
|
||||
}
|
||||
// setTimeout("setfalseInRequestMap(" + config.url + ")", 1200)
|
||||
return config;
|
||||
},
|
||||
err => {
|
||||
return Promise.reject(err);
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(function (response) {
|
||||
|
||||
// console.log(".............")
|
||||
if(response===undefined){
|
||||
return
|
||||
}
|
||||
const config = response.config
|
||||
if (response.data.status === -1) {
|
||||
// console.error('error:', response.data.message)
|
||||
// throw new Error()
|
||||
|
||||
// https://github.com/axios/axios/issues?utf8=%E2%9C%93&q=cancel+request+in+response+interceptors+
|
||||
// https://github.com/axios/axios/issues/583
|
||||
// message.info(response.data.message || '服务端返回status -1,请联系管理员。');
|
||||
// props.showSnackbar( response.data.message || '服务器异常,请联系管理员。' )
|
||||
if (window.location.pathname.startsWith('/tasks/')) {
|
||||
props.showSnackbar( response.data.message || '服务器异常,请联系管理员。' )
|
||||
} else {
|
||||
notification.open({
|
||||
message:"提示",
|
||||
description: response.data.message || '服务器异常,请联系管理员。',
|
||||
style: {
|
||||
zIndex: 99999999
|
||||
},
|
||||
});
|
||||
// notification['error']({
|
||||
// message:"提示",
|
||||
// description: response.data.message || '服务器异常,请联系管理员。',
|
||||
// });
|
||||
}
|
||||
|
||||
throw new axios.Cancel('Operation canceled by the user.');
|
||||
if (window.location.pathname.startsWith('/tasks/')) {
|
||||
props.showSnackbar( response.data.message || '服务器异常,请联系管理员。' )
|
||||
} else {
|
||||
// hash跳转
|
||||
// var hash = window.location.hash;
|
||||
// if (hash) {
|
||||
// hashTimeout && window.clearTimeout(hashTimeout)
|
||||
// hashTimeout = setTimeout(() => {
|
||||
// var element = document.querySelector(hash);
|
||||
// if (element) {
|
||||
// element.scrollIntoView();
|
||||
// }
|
||||
// }, 400)
|
||||
// }
|
||||
}
|
||||
// if(response.data.status === 401){
|
||||
// console.log("401401401")
|
||||
// }
|
||||
if (response.data.status === 403||response.data.status === "403") {
|
||||
|
||||
locationurl('/403');
|
||||
}
|
||||
|
||||
if (response.data.status === 404) {
|
||||
locationurl('/nopage');
|
||||
}
|
||||
|
||||
if (response.data.status === 500) {
|
||||
locationurl('/500');
|
||||
}
|
||||
|
||||
if (response.data.status === 501) {
|
||||
if(message501===false){
|
||||
message501=true
|
||||
notification.open({
|
||||
message:"提示",
|
||||
description:response.data.message || '访问异常,请求不合理',
|
||||
style: {
|
||||
message:"提示",
|
||||
description: response.data.message || '服务器异常,请联系管理员。',
|
||||
style: {
|
||||
zIndex: 99999999
|
||||
}
|
||||
})
|
||||
}
|
||||
window.setTimeout(function () {
|
||||
message501=false
|
||||
}, 2000);
|
||||
},
|
||||
});
|
||||
// notification['error']({
|
||||
// message:"提示",
|
||||
// description: response.data.message || '服务器异常,请联系管理员。',
|
||||
// });
|
||||
}
|
||||
|
||||
throw new axios.Cancel('Operation canceled by the user.');
|
||||
}
|
||||
if (response.data.status === 403||response.data.status === "403") {
|
||||
locationurl('/403');
|
||||
}
|
||||
|
||||
// if (response.data.status === 402) {
|
||||
// console.log(response.data.status);
|
||||
// console.log(response.data);
|
||||
// // locationurl(402);
|
||||
// }
|
||||
if (response.data.status === 404) {
|
||||
locationurl('/nopage');
|
||||
}
|
||||
|
||||
//
|
||||
// if (response.data.status === 401) {
|
||||
// console.log("161");
|
||||
// console.log(config);
|
||||
// return config;
|
||||
// }
|
||||
// if (response.data.status === 407) {
|
||||
// 在app js 中解决 Trialapplication
|
||||
// // </Trialapplication>
|
||||
// ///在appjs
|
||||
// notification.open({
|
||||
// message:"提示",
|
||||
// description: "账号未认证",
|
||||
// });
|
||||
// throw new axios.Cancel('Operation canceled by the user.');
|
||||
// //
|
||||
// }
|
||||
if (response.data.status === 500) {
|
||||
locationurl('/500');
|
||||
}
|
||||
|
||||
requestMap[response.config.url] = false;
|
||||
setpostcookie();
|
||||
return response;
|
||||
if (response.data.status === 501) {
|
||||
if(message501===false){
|
||||
message501=true
|
||||
notification.open({
|
||||
message:"提示",
|
||||
description:response.data.message || '访问异常,请求不合理',
|
||||
style: {
|
||||
zIndex: 99999999
|
||||
}
|
||||
})
|
||||
}
|
||||
window.setTimeout(function () {
|
||||
message501=false
|
||||
}, 2000);
|
||||
}
|
||||
requestMap[response.config.url] = false;
|
||||
setpostcookie();
|
||||
return response;
|
||||
}, function (error) {
|
||||
return Promise.reject(error);
|
||||
return Promise.reject(error);
|
||||
});
|
||||
// -----------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export function SnackbarHOC(options = {}) {
|
|||
autoHideDuration={3000}
|
||||
anchorOrigin={{ vertical: this.state.snackbarVertical || 'top'
|
||||
, horizontal: this.state.snackbarHorizontal || 'center' }}
|
||||
onClose={() => this.handleSnackbarClose()}
|
||||
onClose={() => {this.handleSnackbarClose()}}
|
||||
transition={Fade}
|
||||
SnackbarContentProps={{
|
||||
'aria-describedby': 'message-id',
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ const { Search } = Input;
|
|||
|
||||
const $ = window.$;
|
||||
const isDev = window.location.port == 3007;
|
||||
export const TEST_HOST = "https://test-newweb.educoder.net"
|
||||
export const TEST_HOST = "https://testforgeplus.trustie.net"
|
||||
export function getImageUrl(path) {
|
||||
// https://www.educoder.net
|
||||
// https://testbdweb.trustie.net
|
||||
// const local = 'http://localhost:3000'
|
||||
const local = 'https://test-newweb.educoder.net'
|
||||
const local = 'https://testforgeplus.trustie.net'
|
||||
if (isDev) {
|
||||
return `${local}/${path}`
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ export function getImageUrl(path) {
|
|||
}
|
||||
|
||||
export function setImagesUrl(path){
|
||||
const local = 'https://test-newweb.educoder.net'
|
||||
const local = 'https://testforgeplus.trustie.net'
|
||||
let firstStr=path.substr(0,1);
|
||||
// console.log(firstStr);
|
||||
if(firstStr=="/"){
|
||||
|
|
@ -106,31 +106,31 @@ export function getmyUrl(geturl) {
|
|||
}
|
||||
|
||||
export function getUploadActionUrl(path, goTest) {
|
||||
Railsgettimes()
|
||||
// Railsgettimes()
|
||||
let anewopens=md5(newopens+newtimestamp);
|
||||
return `${getUrl()}/api/attachments.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`;
|
||||
}
|
||||
|
||||
export function getUploadActionUrltwo(id) {
|
||||
Railsgettimes()
|
||||
// Railsgettimes()
|
||||
let anewopens=md5(newopens+newtimestamp);
|
||||
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`
|
||||
}
|
||||
|
||||
export function getUploadActionUrlthree() {
|
||||
Railsgettimes()
|
||||
// Railsgettimes()
|
||||
let anewopens=md5(newopens+newtimestamp);
|
||||
return `${getUrlmys()}/api/jupyters/import_with_tpm.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`
|
||||
}
|
||||
|
||||
export function getUploadActionUrlOfAuth(id) {
|
||||
Railsgettimes()
|
||||
// Railsgettimes()
|
||||
let anewopens=md5(newopens+newtimestamp);
|
||||
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json${isDev ? `?debug=${window._debugType || 'admin'}&randomcode=${newtimestamp}&client_key=${anewopens}` : `?randomcode=${newtimestamp}&client_key=${anewopens}`}`
|
||||
}
|
||||
|
||||
export function getRandomNumber(type) {
|
||||
Railsgettimes()
|
||||
// Railsgettimes()
|
||||
let anewopens=md5(newopens+newtimestamp);
|
||||
return type===true?`randomcode=${newtimestamp}&client_key=${anewopens}`:`?randomcode=${newtimestamp}&client_key=${anewopens}`
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ export function getTaskUrlById(id) {
|
|||
}
|
||||
|
||||
export function getRandomcode(url) {
|
||||
Railsgettimes()
|
||||
// Railsgettimes()
|
||||
let anewopens=md5(newopens+newtimestamp);
|
||||
|
||||
if (url.indexOf('?') == -1) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Dropdown , Menu , Icon , Pagination} from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import moment from 'moment';
|
||||
import { Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
|
||||
import '../css/index.css';
|
||||
import '../Branch/branch.css';
|
||||
import './activity.css';
|
||||
import NoneData from '../Nodata';
|
||||
|
||||
|
||||
import ActivityItem from './ActivityItem';
|
||||
import axios from 'axios';
|
||||
|
|
@ -27,23 +27,28 @@ const ARRAY = [
|
|||
name:'1个月'
|
||||
}
|
||||
]
|
||||
const dataformat="YYYY-MM-DD HH:mm";
|
||||
// const dataformat="YYYY-MM-DD HH:mm";
|
||||
|
||||
class Activity extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
time:'1',
|
||||
time:'30',
|
||||
type:undefined,
|
||||
state:undefined,
|
||||
page:1,
|
||||
|
||||
data:undefined,
|
||||
project_trends:undefined
|
||||
project_trends:undefined,
|
||||
|
||||
isSpin:false
|
||||
}
|
||||
}
|
||||
componentDidMount=()=>{
|
||||
const { time,type,status,page } = this.state;
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.getInfo(time,type,status,page);
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +63,8 @@ class Activity extends Component{
|
|||
if(result){
|
||||
this.setState({
|
||||
data:result.data,
|
||||
project_trends:result.data.project_trends
|
||||
project_trends:result.data.project_trends,
|
||||
isSpin:false
|
||||
})
|
||||
}
|
||||
}).catch(error=>{
|
||||
|
|
@ -69,7 +75,8 @@ class Activity extends Component{
|
|||
// 切换周期
|
||||
changeTime=(e)=>{
|
||||
this.setState({
|
||||
time:e.key
|
||||
time:e.key,
|
||||
isSpin:true
|
||||
})
|
||||
const { type,status,page } = this.state;
|
||||
this.getInfo(e.key,type,status,page);
|
||||
|
|
@ -91,7 +98,7 @@ class Activity extends Component{
|
|||
this.getInfo(time,type,status,page);
|
||||
}
|
||||
render(){
|
||||
const { time , data , page , project_trends } = this.state;
|
||||
const { time , data , page , project_trends , isSpin } = this.state;
|
||||
|
||||
const menu = (
|
||||
<Menu>
|
||||
|
|
@ -105,6 +112,9 @@ class Activity extends Component{
|
|||
</Menu>
|
||||
);
|
||||
|
||||
let name = time && ARRAY.filter(item=>item.id === parseInt(time)) ;
|
||||
// console.log(name);
|
||||
|
||||
|
||||
const second_per = (parseInt(data && data.close_issues_count)/parseInt(data && data.issues_count)*100)+'%';
|
||||
|
||||
|
|
@ -128,47 +138,54 @@ class Activity extends Component{
|
|||
<p className="percent_red" style={{width:`${third_per}`}}></p>
|
||||
<p className="percent_green" style={{width:`${fourth_per}`}}></p>
|
||||
</div>
|
||||
<span>{data && data.issues_count}工单</span>
|
||||
<span>{data && data.issues_count}任务</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="percentBox">
|
||||
<li>
|
||||
<span className="purple">{data && data.pr_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","close")}>已合并请求</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","close")}>已处理的合并请求</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="green">{data && data.new_pr_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","create")}>新合并请求</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("PullRequest","create")}>未处理的合并请求</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="red">{data && data.close_issues_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("Issue","close")}>已关闭工单</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("Issue","close")}>已关闭的任务</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className="green">{data && data.open_issues_count}</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("Issue","create")}>创建的工单</span>
|
||||
<span className="change" onClick={()=>this.changeTrends("Issue","create")}>未处理的任务</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="df trendsTop mt20">
|
||||
<div className="branchDropdown f-wrap-alignCenter">
|
||||
<span className="color-grey-9 mr3">周期:</span>
|
||||
<Dropdown overlay={menu} trigger={['click']} placement="bottomLeft">
|
||||
<a className="ant-dropdown-link">
|
||||
{time} <Icon type="down" />
|
||||
<span className="color-grey-9 mr3">周期:</span>
|
||||
{name && name.length>0 && name[0].name} <Icon type="down" />
|
||||
</a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div className="activity_list">
|
||||
<Spin spinning={isSpin}>
|
||||
{
|
||||
project_trends && project_trends.map((item,key)=>{
|
||||
return(
|
||||
<ActivityItem item={item} {...this.props} ></ActivityItem>
|
||||
)
|
||||
})
|
||||
project_trends && project_trends.length > 0 ?
|
||||
<div className="activity_list">
|
||||
{
|
||||
project_trends && project_trends.map((item,key)=>{
|
||||
return(
|
||||
<ActivityItem item={item} {...this.props} ></ActivityItem>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
:
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
{
|
||||
data && data.project_trends_size > 0 && data.project_trends_size > LIMIT &&
|
||||
<div className="pageDIV">
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class ActivityItem extends Component{
|
|||
<span className="activity_type">{item.trend_type}</span>
|
||||
</p >
|
||||
:
|
||||
// 如果是工单
|
||||
// 如果是任务
|
||||
item.trend_type==="Issue"?
|
||||
<p className="itemLine">
|
||||
<Link to={`/projects/${projectsId}/orders/${item.trend_id}/detail`} className="color-blue font-16">{item.name}</Link>
|
||||
|
|
@ -32,8 +32,11 @@ class ActivityItem extends Component{
|
|||
</p >
|
||||
}
|
||||
<p className="itemLine mt15">
|
||||
<img alt="" src={getImageUrl(`images/${item.user_avatar}`)} className="createImage"/>
|
||||
<span className="mr20">{item.user_name}</span>
|
||||
<Link to={`/users/${item && item.login}/projects`} className="show-user-link">
|
||||
<img alt="" src={getImageUrl(`images/${item.user_avatar}`)} className="createImage"/>
|
||||
<span className="mr20">{item.user_name}</span>
|
||||
</Link>
|
||||
|
||||
{ item.created_at && <span className="color-grey-9">创建于<span className="ml2 color-grey-6">{item.created_at}</span></span>}
|
||||
</p >
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,34 +1,49 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Dropdown , Icon , Menu } from 'antd';
|
||||
|
||||
import "./branch.css"
|
||||
import { Dropdown , Icon , Tooltip } from 'antd';
|
||||
import "./branch.css";
|
||||
|
||||
class CloneAddress extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
}
|
||||
// 点击按钮复制功能
|
||||
jsCopy=()=>{
|
||||
var e = document.getElementById("copy_rep_content");
|
||||
e.select();
|
||||
document.execCommand("Copy");
|
||||
this.props.showNotification('复制成功');
|
||||
// this.props.showNotification('复制成功');
|
||||
}
|
||||
|
||||
render(){
|
||||
const { http_url , downloadUrl } = this.props;
|
||||
return(
|
||||
<div className="gitAddressClone">
|
||||
<span className={"addressType active"} onClick={()=>this.changeAddress("http")}>HTTP</span>
|
||||
{/* onClick={()=>this.changeAddress("http")} */}
|
||||
{
|
||||
http_url && <span>HTTP</span>
|
||||
}
|
||||
{/* <span className={address ==="ssh" ? "addressType active":"addressType"} onClick={()=>this.changeAddress("ssh")}>SSH</span> */}
|
||||
<input type="text" id="copy_rep_content" value={ http_url }/>
|
||||
<span onClick={()=>this.jsCopy()}><i className="iconfont icon-fuzhi"></i></span>
|
||||
<span>
|
||||
<Dropdown overlay={downloadUrl} trigger={['click']} placement="bottomRight">
|
||||
<a className="ant-dropdown-link">
|
||||
<Icon type="cloud-download" className="font-18 fl"/>
|
||||
</a>
|
||||
</Dropdown></span>
|
||||
<Tooltip title="复制链接">
|
||||
<span onClick={()=>this.jsCopy()}><i className="iconfont icon-fuzhi"></i></span>
|
||||
</Tooltip>
|
||||
{
|
||||
downloadUrl &&
|
||||
<span>
|
||||
<Dropdown overlay={downloadUrl} trigger={['click']} placement="bottomRight">
|
||||
<a className="ant-dropdown-link">
|
||||
<Icon type="cloud-download" className="font-18 fl"/>
|
||||
</a>
|
||||
</Dropdown>
|
||||
</span>
|
||||
}
|
||||
{/*<span>*/}
|
||||
{/*{*/}
|
||||
{/*!downloadUrl &&*/}
|
||||
{/*<Dropdown overlay={downloadUrl} trigger={['click']} placement="bottomRight">*/}
|
||||
{/*<a className="ant-dropdown-link">*/}
|
||||
{/*<Icon type="cloud-download" className="font-18 fl"/>*/}
|
||||
{/*</a>*/}
|
||||
{/*</Dropdown>*/}
|
||||
{/*}*/}
|
||||
{/*</span>*/}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,89 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Dropdown , Icon , Menu } from 'antd';
|
||||
import { Dropdown , Icon , Input } from 'antd';
|
||||
|
||||
import "./branch.css"
|
||||
|
||||
const $ = window.$;
|
||||
class SelectBranch extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
visible:false,
|
||||
value:undefined
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
document.body.addEventListener('click', e => {
|
||||
if (e.target && (e.target.matches('#m-btn') || e.target.matches("#input-btn")|| e.target.matches("#ul-btn"))) {
|
||||
return;
|
||||
}
|
||||
if($(e.target)[0].className === "task-hide ulALink")return;
|
||||
this.setState({
|
||||
visible:false,
|
||||
value:undefined
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
ChangeVisible=(visible)=>{
|
||||
this.setState({
|
||||
visible:!visible
|
||||
})
|
||||
}
|
||||
|
||||
InputClick=(e)=>{
|
||||
this.stopPropagations(e);
|
||||
}
|
||||
|
||||
stopPropagations=(e)=>{
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
// 输入搜索内容
|
||||
changeValue=(e)=>{
|
||||
this.setState({
|
||||
value:e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
// 选择分支
|
||||
changeBranchs=(e,value)=>{
|
||||
e.stopPropagation();
|
||||
this.setState({
|
||||
visible:false,
|
||||
value
|
||||
})
|
||||
const { changeBranch } = this.props;
|
||||
changeBranch && changeBranch(value);
|
||||
}
|
||||
|
||||
render(){
|
||||
const { branchs , branch , changeBranch } = this.props;
|
||||
const { visible , value } = this.state;
|
||||
const { branchs , branch } = this.props;
|
||||
|
||||
let branchsFilter = value ? (branchs && branchs.length>0 && branchs.filter(item=>item.name.indexOf(value)>-1)):branchs;
|
||||
const menu = (
|
||||
<Menu>
|
||||
{
|
||||
branchs && branchs.map((item,key)=>{
|
||||
return(
|
||||
<Menu.Item key={item.index} onClick={(value)=>changeBranch(value)}>{item.name}</Menu.Item>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Menu>
|
||||
<div className="branchOptions" id="m-btn" onClick={this.stopPropagations}>
|
||||
<Input placeholder="请输入分支名称进行搜索" autocomplete="off" id="input-btn" value={value} className="OptionsInput" onChange={this.changeValue} onClick={this.InputClick}/>
|
||||
<ul className="OptionsUl" id="ul-btn">
|
||||
{
|
||||
branchsFilter && branchsFilter.map((item,key)=>{
|
||||
return(
|
||||
<li key={key}><a className="task-hide ulALink" onClick={(e)=>this.changeBranchs(e,`${item.name}`)}>{item.name}</a></li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
return(
|
||||
<div className="branchDropdown f-wrap-alignCenter">
|
||||
<span className="color-grey-9 mr3"><i className="iconfont icon-fenzhi font-20 color-grey-6 mr3"></i>分支:</span>
|
||||
<Dropdown overlay={menu} trigger={['click']} placement="bottomLeft">
|
||||
<a className="ant-dropdown-link">
|
||||
{branch} <Icon type="down" />
|
||||
</a>
|
||||
<div className="branchDropdown f-wrap-alignCenter" onClick={()=>this.ChangeVisible(visible)}>
|
||||
<Dropdown overlay={menu} trigger={['click']} placement="bottomLeft" visible={visible}>
|
||||
<span>
|
||||
<span className="color-grey-9 mr3"><i className="iconfont icon-fenzhi font-20 color-grey-6 mr3"></i>分支:</span>
|
||||
<a className="ant-dropdown-link">
|
||||
{branch} <Icon type="down" />
|
||||
</a>
|
||||
</span>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,41 @@
|
|||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding:0px 10px;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
min-width: 150px;
|
||||
}
|
||||
.branchDropdown .ant-dropdown-trigger{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding:0px 15px;
|
||||
}
|
||||
.branchOptions{
|
||||
width: 200px;
|
||||
padding:10px;
|
||||
box-shadow: 0px 0px 1px 1px rgba(134, 134, 134, 0.1);
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
max-height: 300px;
|
||||
}
|
||||
.OptionsUl{
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.OptionsUl li{
|
||||
height: 30px;
|
||||
/*line-height: 22px;*/
|
||||
cursor: pointer;
|
||||
}
|
||||
.OptionsUl li a{
|
||||
display: block;
|
||||
padding: 4px;
|
||||
/*padding-left: 2px;*/
|
||||
}
|
||||
.OptionsInput{
|
||||
height: 32px;
|
||||
padding-left: 4px;
|
||||
line-height: 32px;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1586744176993" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2609" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><defs><style type="text/css"></style></defs><path d="M926.82752 115.18464h-248.59392c-69.7472 0-130.89792 36.32384-165.1968 90.87232-34.29888-54.54848-95.44704-90.87232-165.2224-90.87232H97.19552C43.49696 115.18464-0.00256 158.1824-0.00256 211.23328v543.91296c0 53.04832 43.49952 96.04864 97.19808 96.04864h303.1424c24.59904 34.82368 65.42336 57.62304 111.67232 57.62304 46.22336 0 87.07328-22.79936 111.64672-57.62304h303.17056c53.64736 0 97.16992-43.00032 97.16992-96.04864V211.23328c0-53.04832-43.52256-96.04864-97.16992-96.04864z m38.848 639.9616c0 21.19936-17.40032 38.39744-38.848 38.39744H587.31008c-8.62464 33.14944-39.07584 57.6512-75.29984 57.6512s-66.67264-24.4992-75.32288-57.6512H97.19552c-21.44768 0-38.8736-17.19808-38.8736-38.39744V211.23328c0-21.22496 17.42592-38.4256 38.8736-38.4256h250.61888c75.1488 0 136.07168 60.20096 136.07168 134.44864v315.76832h0.09984c1.14944 14.87616 13.69856 26.57536 29.04832 26.57536 15.32416 0 27.89888-11.6992 29.04832-26.57536h0.09984V307.25376c0-74.24768 60.89984-134.44864 136.04864-134.44864h248.59392c21.44768 0 38.848 17.20064 38.848 38.4256v543.91552zM357.9904 355.02848H203.29472c-13.39904 0-24.29952 10.74944-24.29952 24s10.89792 23.9744 24.29952 23.9744h154.69568c13.42464 0 24.29952-10.74944 24.29952-23.9744 0-13.25056-10.87488-24-24.29952-24z m0 209.87136H203.29472c-13.39904 0-24.29952 10.74688-24.29952 23.97184 0 13.25056 10.89792 24 24.29952 24h154.69568c13.42464 0 24.29952-10.74944 24.29952-24 0-13.22496-10.87488-23.97184-24.29952-23.97184z m464.18688 0h-154.72128c-13.39904 0-24.27392 10.74688-24.27392 23.97184 0 13.25056 10.87488 24 24.27392 24h154.72128c13.39904 0 24.27392-10.74944 24.27392-24 0-13.22496-10.87488-23.97184-24.27392-23.97184z m0-209.87136h-154.72128c-13.39904 0-24.27392 10.74944-24.27392 24s10.87488 23.9744 24.27392 23.9744h154.72128c13.39904 0 24.27392-10.74944 24.27392-23.9744 0-13.25056-10.87488-24-24.27392-24z" p-id="2610" fill="#515151"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
|
|
@ -33,51 +33,32 @@ const ProjectDetail = Loadable({
|
|||
})
|
||||
|
||||
class Index extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
current_user:undefined,
|
||||
}
|
||||
}
|
||||
componentDidMount=()=>{
|
||||
this.getUserInfo();
|
||||
document.title="forge开源";
|
||||
}
|
||||
|
||||
getUserInfo=()=>{
|
||||
const url = `/users/me.json`;
|
||||
axios.get(url).then(result=>{
|
||||
// result && result.data.login
|
||||
if(result && result.data.login){
|
||||
this.setState({
|
||||
current_user:result.data
|
||||
})
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
const { current_user } = this.state;
|
||||
return(
|
||||
<div className="newMain clearfix">
|
||||
<Switch {...this.props}>
|
||||
<Route path="/projects/:projectsType/new"
|
||||
render={
|
||||
(props) => (<ProjectNew {...this.props} {...props} {...this.state} current_user={current_user}/>)
|
||||
(props) => (<ProjectNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId"
|
||||
render={
|
||||
(props) => (<ProjectDetail {...this.props} {...props} {...this.state} current_user={current_user}/>)
|
||||
(props) => (<ProjectDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route exact path="/projects"
|
||||
render={
|
||||
(props) => (<ProjectIndex {...this.props} {...props} {...this.state} current_user={current_user}/>)
|
||||
(props) => (<ProjectIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route exact path="/"
|
||||
// component={ShixunsHome}
|
||||
render={
|
||||
(props)=>(<ProjectIndex {...this.props} {...props} {...this.state}></ProjectIndex>)
|
||||
}
|
||||
/>
|
||||
</Switch>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link } from "react-router-dom";
|
||||
import { Dropdown , Menu , Icon , Tooltip } from 'antd';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
|
||||
import './list.css'
|
||||
import { branch } from 'recompose';
|
||||
|
|
@ -21,7 +22,7 @@ class CoderRootBranch extends Component {
|
|||
if(branchList && branchList.length>0){
|
||||
return(
|
||||
<React.Fragment>
|
||||
|
||||
|
||||
|
||||
<ul className="branchUl">
|
||||
{
|
||||
|
|
@ -29,10 +30,10 @@ class CoderRootBranch extends Component {
|
|||
return(
|
||||
<li>
|
||||
<div>
|
||||
<Link to={`/projects/${projectsId}/coder?branch=${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||
<Link to={`/projects/${projectsId}/coders?branch=${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
|
||||
{/*<span className="color-blue font-15">{item.name}</span>*/}
|
||||
<p className="f-wrap-alignCenter">
|
||||
<span className="mr5 color-blue">{item.last_commit && item.last_commit.id}</span>
|
||||
<span className="mr5 color-blue">{item.last_commit && truncateCommitId(item.last_commit.id)}</span>
|
||||
{/*<Link to="javascript:void(0)" className="mr5 color-blue" >{item.last_commit && item.last_commit.id}</Link>*/}
|
||||
<span className="color-grey-9 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
|
||||
<span className="color-grey-6 leftPoint">最后更新于{item.last_commit && item.last_commit.time_from_now}</span>
|
||||
|
|
@ -40,7 +41,7 @@ class CoderRootBranch extends Component {
|
|||
</div>
|
||||
<span>
|
||||
<Link to={`/projects/${projectsId}/merge/new`} className="mr20 operationBtn">创建合并请求</Link>
|
||||
|
||||
|
||||
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="operationBtn">
|
||||
<a className="ant-dropdown-link">
|
||||
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
|
||||
|
|
@ -75,4 +76,4 @@ class CoderRootBranch extends Component {
|
|||
|
||||
}
|
||||
|
||||
export default CoderRootBranch;
|
||||
export default CoderRootBranch;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Table , Spin } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { truncateCommitId } from '../common/util'
|
||||
import SelectBranch from '../Branch/SelectBranch';
|
||||
import Top from './DetailTop';
|
||||
|
||||
import axios from 'axios';
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
class CoderRootCommit extends Component{
|
||||
constructor(props){
|
||||
|
|
@ -28,9 +30,8 @@ class CoderRootCommit extends Component{
|
|||
}
|
||||
|
||||
getCommitList=(branch , page , limit)=>{
|
||||
const { login } = this.props.current_user;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/${login}/${projectsId}/commits.json`;
|
||||
const url = `/repositories/${projectsId}/commits.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
sha:branch,
|
||||
|
|
@ -43,6 +44,7 @@ class CoderRootCommit extends Component{
|
|||
result.data && result.data.commits.length > 0 && result.data.commits.map((item,key)=>{
|
||||
array.push({
|
||||
name:item.author && item.author.name,
|
||||
login: item.author && item.author.login,
|
||||
image_url:item.author && item.author.image_url,
|
||||
sha:item.sha,
|
||||
time_from_now:item.time_from_now,
|
||||
|
|
@ -61,7 +63,7 @@ class CoderRootCommit extends Component{
|
|||
// 切换分支
|
||||
changeBranch=(value)=>{
|
||||
const { branchList } = this.props;
|
||||
let branchLastCommit = branchList[parseInt(value.key)];
|
||||
let branchLastCommit = branchList && branchList.filter(item=>item.name === value)[0];
|
||||
|
||||
const { page , limit } = this.state;
|
||||
this.setState({
|
||||
|
|
@ -85,15 +87,18 @@ class CoderRootCommit extends Component{
|
|||
width:"10%",
|
||||
render: (text,item) => (
|
||||
<span className="f-wrap-alignCenter">
|
||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>
|
||||
<label className="hide-1" style={{maxWidth:"75px"}}>{text}</label>
|
||||
<Link to={`/users/${item.login}/projects`} className="show-user-link">
|
||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>
|
||||
<label className="hide-1" style={{maxWidth:"75px",'vertical-align':'middle'}}>{text}</label>
|
||||
</Link>
|
||||
|
||||
</span>
|
||||
),
|
||||
},{
|
||||
title:"SHA",
|
||||
dataIndex: 'sha',
|
||||
render: (text) => (
|
||||
<span className="commitKey">{text}</span>
|
||||
<span className="commitKey">{truncateCommitId(text)}</span>
|
||||
)
|
||||
},{
|
||||
title:"备注",
|
||||
|
|
@ -125,7 +130,7 @@ class CoderRootCommit extends Component{
|
|||
|
||||
const Pagination =()=> {
|
||||
if(dataCount > limit){
|
||||
return(
|
||||
return(
|
||||
<div className="edu-txt-center pt30 mb30">
|
||||
<Pagination simple defaultCurrent={page} total={dataCount} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>
|
||||
|
|
@ -154,4 +159,4 @@ class CoderRootCommit extends Component{
|
|||
)
|
||||
}
|
||||
}
|
||||
export default CoderRootCommit;
|
||||
export default CoderRootCommit;
|
||||
|
|
|
|||
|
|
@ -5,14 +5,16 @@ import { Router , Route , Link } from 'react-router-dom';
|
|||
import Top from './DetailTop';
|
||||
|
||||
import './list.css';
|
||||
|
||||
import readme_img from '../Images/book.svg';
|
||||
import SelectBranch from '../Branch/SelectBranch';
|
||||
import CloneAddress from '../Branch/CloneAddress';
|
||||
import RootTable from './RootTable';
|
||||
import CoderRootFileDetail from './CoderRootFileDetail';
|
||||
import NullData from './NullData';
|
||||
import { truncateCommitId } from '../common/util';
|
||||
|
||||
import axios from 'axios';
|
||||
import img_fork from "../Images/fork.png";
|
||||
/**
|
||||
* address:http和SSH,http_url(对应git地址)
|
||||
* branch:当前分支
|
||||
|
|
@ -20,25 +22,27 @@ import axios from 'axios';
|
|||
* subfileType:保存当前点击目录的文件类型(显示目录列表时才显示新建文件,如果点击的是文件就不显示新建文件按钮)
|
||||
* readMeContent:根目录下面的readme文件内容
|
||||
*/
|
||||
|
||||
class CoderRootDirectory extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
address:"http",
|
||||
branch:"master",
|
||||
filePath:[],
|
||||
filePath:undefined,
|
||||
http_url:undefined,
|
||||
subFileType:"",
|
||||
subFileType:undefined,
|
||||
readMeContent:undefined,
|
||||
readMeFile: undefined,
|
||||
|
||||
isSpin:true,
|
||||
|
||||
branchList:undefined,
|
||||
fileDetail:undefined,
|
||||
branchLastCommit:undefined,
|
||||
current_user:undefined,
|
||||
|
||||
rootData:undefined
|
||||
rootList:undefined,
|
||||
readOnly: true
|
||||
}
|
||||
}
|
||||
changeAddress=(address)=>{
|
||||
|
|
@ -47,26 +51,54 @@ class CoderRootDirectory extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
componentDidMount=()=>{
|
||||
this.Init();
|
||||
}
|
||||
|
||||
componentDidUpdate=(prevState)=>{
|
||||
const {location} = this.props;
|
||||
const prevlocation = prevState && prevState.location;
|
||||
if(location !== prevlocation){
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.Init();
|
||||
}
|
||||
}
|
||||
|
||||
Init=()=>{
|
||||
let { search } = this.props.history.location;
|
||||
let branchName = undefined;
|
||||
if(search && search.indexOf("branch")>-1){
|
||||
branchName = search.split("=")[1];
|
||||
if(search && search.indexOf("?branch=")>-1){
|
||||
branchName = search.split("?branch=")[1];
|
||||
this.setState({
|
||||
branch:branchName
|
||||
})
|
||||
}
|
||||
const { branch } = this.state;
|
||||
this.getProjectRoot(branchName || branch);
|
||||
if(search && search.indexOf("?url=")>-1){
|
||||
let url =search.split("?url=")[1];
|
||||
this.setState({
|
||||
filePath:url
|
||||
})
|
||||
this.getFileDetail(url);
|
||||
}else{
|
||||
const { branch } = this.state;
|
||||
this.getProjectRoot( branchName || branch);
|
||||
}
|
||||
}
|
||||
|
||||
// 页面地址返回到主目录
|
||||
returnMain=(branch)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${projectsId}/coders`);
|
||||
this.getProjectRoot(branch);
|
||||
}
|
||||
|
||||
// 获取根目录
|
||||
getProjectRoot=(branch)=>{
|
||||
const { current_user } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { state } = this.props.history.location;
|
||||
console.log(this.props);
|
||||
const url = `/${state ? state : current_user && current_user.login}/${projectsId}/entries.json`;
|
||||
const url = `/repositories/${projectsId}/entries.json`;
|
||||
axios.get((url),{
|
||||
params:{
|
||||
branch
|
||||
|
|
@ -75,25 +107,27 @@ class CoderRootDirectory extends Component{
|
|||
if(result){
|
||||
if(result && result.data && result.data.length > 0){
|
||||
this.setState({
|
||||
filePath:[],
|
||||
filePath:undefined,
|
||||
fileDetail:undefined,
|
||||
isSpin: false
|
||||
})
|
||||
this.renderData(result.data);
|
||||
}
|
||||
this.setState({
|
||||
rootData:result.data
|
||||
rootList:result.data,
|
||||
subFileType:true
|
||||
})
|
||||
}
|
||||
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
|
||||
ChangeFile=(arr,index)=>{
|
||||
this.renderUrl(arr.name,arr.path,arr.type);
|
||||
this.getFileDetail(arr);
|
||||
ChangeFile=(arr,readOnly)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
//点击直接跳转页面 加载一次路由
|
||||
this.props.history.push(`/projects/${projectsId}/coders?url=${arr.path}`);
|
||||
this.setState({
|
||||
subFileType:arr.type
|
||||
readOnly: readOnly
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +146,9 @@ class CoderRootDirectory extends Component{
|
|||
type:(filePath && filePath.length>0) ? (filePath[k] ? filePath[k].type : type) : type
|
||||
})
|
||||
})
|
||||
const { projectsId } = this.props.match.params;
|
||||
//点击直接跳转页面 加载一次路由
|
||||
this.props.history.push(`/projects/${projectsId}/coders?url=${str.substr(1)}`);
|
||||
}else{
|
||||
list.push({
|
||||
index:0,
|
||||
|
|
@ -124,30 +161,31 @@ class CoderRootDirectory extends Component{
|
|||
}
|
||||
|
||||
// 获取子目录
|
||||
getFileDetail=(arr)=>{
|
||||
const { current_user } = this.props;
|
||||
getFileDetail=(path,ref)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { branch } = this.state;
|
||||
const { state } = this.props.history.location;
|
||||
|
||||
|
||||
const url =`/${state ? state : current_user && current_user.login}/${projectsId}/sub_entries.json`;
|
||||
const url =`/repositories/${projectsId}/sub_entries.json`;
|
||||
|
||||
axios.get(url,{
|
||||
params:{
|
||||
filepath:arr.path,
|
||||
ref:branch
|
||||
filepath:path,
|
||||
ref:ref || branch
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result && result.data && result.data.length > 0){
|
||||
if(arr.type==="file"){
|
||||
// 当前返回的子目录只有一条数据,且这条数据返回的是文件类型
|
||||
if(result.data.length === 1 && result.data[0].type === "file"){
|
||||
this.setState({
|
||||
fileDetail:result.data[0],
|
||||
rootList:undefined
|
||||
fileDetail:result.data,
|
||||
rootList:undefined,
|
||||
isSpin:false,
|
||||
subFileType:false
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
fileDetail:undefined
|
||||
fileDetail:undefined,
|
||||
rootList:result.data,
|
||||
isSpin:false
|
||||
})
|
||||
this.renderData(result.data)
|
||||
}
|
||||
|
|
@ -160,6 +198,7 @@ class CoderRootDirectory extends Component{
|
|||
renderData=(data)=>{
|
||||
const rootList = [];
|
||||
const readMeContent = [];
|
||||
const readMeFile = [];
|
||||
data && data.map((item,key)=>{
|
||||
rootList.push({
|
||||
key,
|
||||
|
|
@ -167,26 +206,42 @@ class CoderRootDirectory extends Component{
|
|||
})
|
||||
if(item.name === 'README.md'){
|
||||
readMeContent.push({...item})
|
||||
readMeFile.push({...item})
|
||||
}
|
||||
})
|
||||
this.setState({
|
||||
rootList:rootList,
|
||||
readMeContent
|
||||
readMeContent,
|
||||
readMeFile
|
||||
})
|
||||
}
|
||||
|
||||
// 点击跳转到子目录
|
||||
goToSubRoot=(path)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
this.props.history.push(`/projects/${projectsId}/coders?url=${path}`);
|
||||
}
|
||||
|
||||
// readme文件内容
|
||||
renderReadMeContent=(readMeContent)=>{
|
||||
const { fileDetail } = this.state;
|
||||
renderReadMeContent=(readMeContent, permission)=>{
|
||||
const { fileDetail,readMeFile } = this.state;
|
||||
if(fileDetail){return;}
|
||||
if(readMeContent && readMeContent.length > 0){
|
||||
return(
|
||||
<div className="commonBox">
|
||||
<div className="commonBox-title">{readMeContent[0].name}</div>
|
||||
<div className="commonBox-title">
|
||||
<span className="mr5"><img src={readme_img} alt="" width="16px"/></span>
|
||||
<span className="commonBox-title-read">{readMeContent[0].name}</span>
|
||||
{
|
||||
permission ?
|
||||
<a onClick={()=>this.ChangeFile(readMeFile[0],false)} className="ml20 pull-right"><i className="iconfont icon-bianji font-15 color-grey-6"></i></a>
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
<div className="commonBox-info">
|
||||
{
|
||||
readMeContent[0].content ?
|
||||
<div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML(readMeContent[0].content).replace(/▁/g, "▁▁▁")}}></div>
|
||||
<div className={"markdown-body readme-index"} dangerouslySetInnerHTML={{__html: markdownToHTML(readMeContent[0].content).replace(/▁/g, "▁▁▁")}}></div>
|
||||
:
|
||||
<span>暂无~</span>
|
||||
}
|
||||
|
|
@ -199,28 +254,38 @@ class CoderRootDirectory extends Component{
|
|||
// 选择分支
|
||||
changeBranch=(value)=>{
|
||||
const { branchList } = this.props;
|
||||
|
||||
let branchLastCommit = branchList && branchList.length >0 && branchList[parseInt(value.key)];
|
||||
this.setState({
|
||||
branch:branchLastCommit.name,
|
||||
branchLastCommit,
|
||||
http_url:branchLastCommit.http_url,
|
||||
isSpin: true
|
||||
})
|
||||
this.getProjectRoot(branchLastCommit.name);
|
||||
|
||||
let branchLastCommit = branchList && branchList.length >0 && branchList.filter(item=>item.name === value)[0];
|
||||
if(branchLastCommit){
|
||||
this.setState({
|
||||
branch:value,
|
||||
branchLastCommit,
|
||||
http_url:branchLastCommit && branchLastCommit.http_url,
|
||||
isSpin: true
|
||||
})
|
||||
let { search } = this.props.history.location;
|
||||
if(search && search.indexOf("?url=")>-1){
|
||||
let url =search.split("?url=")[1];
|
||||
this.setState({
|
||||
filePath:url
|
||||
})
|
||||
this.getFileDetail(url, value);
|
||||
}else{
|
||||
this.getProjectRoot( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
render(){
|
||||
const { rootList , branch ,filePath , fileDetail , subFileType , readMeContent, isSpin , rootData } = this.state;
|
||||
const { rootList , branch ,filePath , fileDetail , subFileType , readMeContent, isSpin } = this.state;
|
||||
const { branchLastCommit , http_url , isManager , isDeveloper } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
width:"100%",
|
||||
render: (text,item) => (
|
||||
<a onClick={()=>this.ChangeFile(item)}>
|
||||
<a onClick={()=>this.goToSubRoot(item.path)}>
|
||||
<i className={ item.type === "file" ? "iconfont icon-zuoye font-15 color-blue mr5":"iconfont icon-wenjian font-15 color-blue mr5"}></i>{text}
|
||||
</a>
|
||||
),
|
||||
|
|
@ -233,13 +298,16 @@ class CoderRootDirectory extends Component{
|
|||
{
|
||||
branchLastCommit.author ?
|
||||
<React.Fragment>
|
||||
<img src={getImageUrl(`images/${branchLastCommit.author.image_url}`)} className="radius mr10" width="32" height="32" alt=""/>
|
||||
<span className="mr15">{branchLastCommit.author.login}</span>
|
||||
<Link to={`/users/${branchLastCommit.author.login}/projects`} className="show-user-link">
|
||||
<img src={getImageUrl(`images/${branchLastCommit.author.image_url}`)} className="radius mr10" width="32" height="32" alt=""/>
|
||||
<span className="mr15">{branchLastCommit.author.login}</span>
|
||||
</Link>
|
||||
|
||||
</React.Fragment>
|
||||
:""
|
||||
}
|
||||
<Link to={``} className="commitKey">{branchLastCommit.last_commit.id}</Link>
|
||||
<span className="color-blue flex-1 hide-1">{branchLastCommit.last_commit.message}</span>
|
||||
<span className="commitKey">{truncateCommitId(branchLastCommit.last_commit.id)}</span>
|
||||
<span>{branchLastCommit.last_commit.time_from_now}</span>
|
||||
</div>
|
||||
)
|
||||
|
|
@ -259,76 +327,68 @@ class CoderRootDirectory extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
const urlRoot = filePath && filePath.length > 0 ? `/${filePath[filePath.length - 1].path}` : "";
|
||||
const urlRoot = filePath === undefined ? '':`/${filePath}`;
|
||||
const { projectDetail } = this.props;
|
||||
let array = filePath && filePath.split("/");
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
rootData &&
|
||||
<React.Fragment>
|
||||
{
|
||||
rootData.length > 0 ?
|
||||
<div>
|
||||
<Top { ...this.props } {...this.state} />
|
||||
<div className="f-wrap-between mt20">
|
||||
<div className="f-wrap-alignCenter">
|
||||
<SelectBranch branch={branch} changeBranch={this.changeBranch} {...this.props} {...this.state}></SelectBranch>
|
||||
<Spin spinning={isSpin}>
|
||||
<div>
|
||||
<Top { ...this.props } {...this.state} />
|
||||
<div className="f-wrap-between mt20">
|
||||
<div className="f-wrap-alignCenter">
|
||||
<SelectBranch branch={branch} changeBranch={this.changeBranch} {...this.props} {...this.state}></SelectBranch>
|
||||
|
||||
{
|
||||
filePath &&
|
||||
<span className="ml20 font-16">
|
||||
<a onClick={()=>this.returnMain(branch)} className="color-blue">{ projectDetail && projectDetail.identifier }</a>
|
||||
{
|
||||
filePath && filePath.length > 0 &&
|
||||
<span className="ml20 font-16">
|
||||
<a onClick={()=>this.getProjectRoot(branch)} className="color-blue">{projectsId}</a>
|
||||
{
|
||||
filePath.map((item,key)=>{
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
key === filePath.length-1 ?
|
||||
<span className="color-grey-6 subFileName" key={key}>{item.name}</span>
|
||||
:
|
||||
<a onClick={()=>this.ChangeFile(item,key)} className="color-blue subFileName" key={key}>{item.name}</a>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
</span>
|
||||
array && array.map((item,key)=>{
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
key === array.length-1 ?
|
||||
<span className="color-grey-6 subFileName" key={key}>{item}</span>
|
||||
:
|
||||
key === 0?
|
||||
<Link to={`/projects/${projectsId}/coders?url=${item}`} className="color-blue subFileName" key={key}>{item}</Link>
|
||||
:
|
||||
<Link to={`/projects/${projectsId}/coders?url=${array[key-1]}/${item}`} className="color-blue subFileName" key={key}>{item}</Link>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
</div>
|
||||
<div className="f-wrap-alignCenter">
|
||||
{
|
||||
subFileType !== "file" && isManager && isDeveloper &&
|
||||
<p className="addFile">
|
||||
<Link to={`/projects/${projectsId}/coder/${branch}/newfile${urlRoot}`} >新建文件</Link>
|
||||
<Link to={``}>上传文件</Link>
|
||||
</p>
|
||||
}
|
||||
{
|
||||
filePath && filePath.length === 0 && <CloneAddress http_url={http_url} downloadUrl={downloadUrl} showNotification={this.props.showNotification}></CloneAddress>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
{/* 文件夹-子目录列表 */}
|
||||
{
|
||||
rootList && <RootTable columns = {columns} data={rootList} title={() => title()}></RootTable>
|
||||
}
|
||||
|
||||
{
|
||||
fileDetail &&
|
||||
<CoderRootFileDetail detail = {fileDetail} {...this.props} {...this.state}></CoderRootFileDetail>
|
||||
}
|
||||
|
||||
{/* readme.txt */}
|
||||
{ this.renderReadMeContent(readMeContent) }
|
||||
</Spin>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
:
|
||||
<NullData {...this.props} {...this.state} http_url={http_url} ></NullData>
|
||||
<div className="f-wrap-alignCenter">
|
||||
{
|
||||
subFileType && (isManager || isDeveloper) &&
|
||||
<p className="addFile mr30">
|
||||
<Link to={`/projects/${projectsId}/coders/${branch}/newfile${urlRoot}`} >新建文件</Link>
|
||||
</p>
|
||||
}
|
||||
{
|
||||
http_url && <CloneAddress http_url={http_url} downloadUrl={downloadUrl} showNotification={this.props.showNotification}></CloneAddress>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{/* 主目录列表 */}
|
||||
{
|
||||
rootList &&
|
||||
<RootTable columns = {columns} data={rootList} title={() => title()}></RootTable>
|
||||
|
||||
}
|
||||
</React.Fragment>
|
||||
}
|
||||
</React.Fragment>
|
||||
{/* 子目录列表、文件 */}
|
||||
{
|
||||
fileDetail && fileDetail.length>0 &&
|
||||
<CoderRootFileDetail detail = {fileDetail[0]} {...this.props} {...this.state} readOnly={this.state.readOnly}></CoderRootFileDetail>
|
||||
}
|
||||
{/* readme.txt (isManager || isDeveloper)*/}
|
||||
{ this.renderReadMeContent(readMeContent,(isManager || isDeveloper)) }
|
||||
</div>
|
||||
</Spin>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,333 @@
|
|||
import React , { Component } from 'react';
|
||||
import {Menu, Spin} from 'antd';
|
||||
import { getImageUrl , markdownToHTML } from 'educoder';
|
||||
import { Router , Route , Link } from 'react-router-dom';
|
||||
import Top from './DetailTop';
|
||||
|
||||
import './list.css';
|
||||
|
||||
import SelectBranch from '../Branch/SelectBranch';
|
||||
import CloneAddress from '../Branch/CloneAddress';
|
||||
import RootTable from './RootTable';
|
||||
import CoderRootFileDetail from './CoderRootFileDetail';
|
||||
import NullData from './NullData';
|
||||
|
||||
import axios from 'axios';
|
||||
/**
|
||||
* address:http和SSH,http_url(对应git地址)
|
||||
* branch:当前分支
|
||||
* filePath:点击目录时当前目录的路径
|
||||
* subfileType:保存当前点击目录的文件类型(显示目录列表时才显示新建文件,如果点击的是文件就不显示新建文件按钮)
|
||||
* readMeContent:根目录下面的readme文件内容
|
||||
*/
|
||||
class CoderRootDirectorytext extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
address:"http",
|
||||
branch:"master",
|
||||
filePath:[],
|
||||
http_url:undefined,
|
||||
subFileType:"",
|
||||
readMeContent:undefined,
|
||||
|
||||
isSpin:true,
|
||||
|
||||
branchList:undefined,
|
||||
fileDetail:undefined,
|
||||
branchLastCommit:undefined,
|
||||
|
||||
rootData:undefined
|
||||
}
|
||||
}
|
||||
changeAddress=(address)=>{
|
||||
this.setState({
|
||||
address
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
|
||||
let { search } = this.props.history.location;
|
||||
let branchName = undefined;
|
||||
if(search && search.indexOf("branch")>-1){
|
||||
branchName = search.split("=")[1];
|
||||
this.setState({
|
||||
branch:branchName
|
||||
})
|
||||
}
|
||||
const { branch } = this.state;
|
||||
this.getProjectRoot(branchName || branch);
|
||||
}
|
||||
|
||||
// 获取根目录
|
||||
getProjectRoot=(branch)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/repositories/${projectsId}/entries.json`;
|
||||
axios.get((url),{
|
||||
params:{
|
||||
branch
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
if(result && result.data && result.data.length > 0){
|
||||
this.setState({
|
||||
filePath:[],
|
||||
fileDetail:undefined,
|
||||
isSpin: false
|
||||
})
|
||||
this.renderData(result.data);
|
||||
}
|
||||
this.setState({
|
||||
rootData:result.data
|
||||
})
|
||||
}
|
||||
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
|
||||
ChangeFile=(arr,index)=>{
|
||||
this.renderUrl(arr.name,arr.path,arr.type);
|
||||
//点击直接跳转页面 加载一次路由
|
||||
this.getFileDetail(arr);
|
||||
this.setState({
|
||||
subFileType:arr.type
|
||||
})
|
||||
}
|
||||
|
||||
renderUrl=(name,path,type)=>{
|
||||
let list =[];
|
||||
const { filePath } = this.state;
|
||||
if(path.indexOf("/")){
|
||||
const array = path.split("/");
|
||||
let str = "";
|
||||
array.map((i,k)=>{
|
||||
str += '/'+i;
|
||||
return list.push({
|
||||
index:k,
|
||||
name:i,
|
||||
path:str.substr(1),
|
||||
type:(filePath && filePath.length>0) ? (filePath[k] ? filePath[k].type : type) : type
|
||||
})
|
||||
})
|
||||
}else{
|
||||
list.push({
|
||||
index:0,
|
||||
name,path,type
|
||||
})
|
||||
}
|
||||
this.setState({
|
||||
filePath:list
|
||||
})
|
||||
}
|
||||
|
||||
// 获取子目录
|
||||
getFileDetail=(arr)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { branch } = this.state;
|
||||
const url =`/repositories/${projectsId}/sub_entries.json`;
|
||||
|
||||
axios.get(url,{
|
||||
params:{
|
||||
filepath:arr.path,
|
||||
ref:branch
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result && result.data && result.data.length > 0){
|
||||
if(arr.type==="file"){
|
||||
this.setState({
|
||||
fileDetail:result.data[0],
|
||||
rootList:undefined
|
||||
})
|
||||
}else{
|
||||
if(arr.type===""){
|
||||
this.props.showNotification('该文件夹下已无文件')
|
||||
return
|
||||
}
|
||||
this.setState({
|
||||
fileDetail:undefined
|
||||
})
|
||||
this.renderData(result.data)
|
||||
}
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
renderData=(data)=>{
|
||||
const rootList = [];
|
||||
const readMeContent = [];
|
||||
data && data.map((item,key)=>{
|
||||
rootList.push({
|
||||
key,
|
||||
...item
|
||||
})
|
||||
if(item.name === 'README.md'){
|
||||
readMeContent.push({...item})
|
||||
}
|
||||
})
|
||||
this.setState({
|
||||
rootList:rootList,
|
||||
readMeContent
|
||||
})
|
||||
}
|
||||
|
||||
// readme文件内容
|
||||
renderReadMeContent=(readMeContent)=>{
|
||||
const { fileDetail } = this.state;
|
||||
if(fileDetail){return;}
|
||||
if(readMeContent && readMeContent.length > 0){
|
||||
return(
|
||||
<div className="commonBox">
|
||||
<div className="commonBox-title">{readMeContent[0].name}</div>
|
||||
<div className="commonBox-info">
|
||||
{
|
||||
readMeContent[0].content ?
|
||||
<div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML(readMeContent[0].content).replace(/▁/g, "▁▁▁")}}></div>
|
||||
:
|
||||
<span>暂无~</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 选择分支
|
||||
changeBranch=(value)=>{
|
||||
const { branchList } = this.props;
|
||||
|
||||
let branchLastCommit = branchList && branchList.length >0 && branchList.filter(item=>item.name === value)[0];
|
||||
this.setState({
|
||||
branch:branchLastCommit && branchLastCommit.name,
|
||||
branchLastCommit,
|
||||
http_url:branchLastCommit && branchLastCommit.http_url,
|
||||
isSpin: true
|
||||
})
|
||||
this.getProjectRoot(branchLastCommit.name);
|
||||
|
||||
}
|
||||
render(){
|
||||
const { rootList , branch ,filePath , fileDetail , subFileType , readMeContent, isSpin , rootData } = this.state;
|
||||
const { branchLastCommit , http_url , isManager , isDeveloper } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
width:"100%",
|
||||
render: (text,item) => (
|
||||
<a onClick={()=>this.ChangeFile(item)}>
|
||||
<i className={ item.type === "file" ? "iconfont icon-zuoye font-15 color-blue mr5":"iconfont icon-wenjian font-15 color-blue mr5"}></i>{text}
|
||||
</a>
|
||||
),
|
||||
}
|
||||
];
|
||||
const title = () =>{
|
||||
if(branchLastCommit && branchLastCommit.last_commit){
|
||||
return(
|
||||
<div className="f-wrap-alignCenter">
|
||||
{
|
||||
branchLastCommit.author ?
|
||||
<React.Fragment>
|
||||
<img src={getImageUrl(`images/${branchLastCommit.author.image_url}`)} className="radius mr10" width="32" height="32" alt=""/>
|
||||
<span className="mr15">{branchLastCommit.author.login}</span>
|
||||
</React.Fragment>
|
||||
:""
|
||||
}
|
||||
<Link to={``} className="commitKey">{branchLastCommit.last_commit.id}</Link>
|
||||
<span className="color-blue flex-1 hide-1">{branchLastCommit.last_commit.message}</span>
|
||||
<span>{branchLastCommit.last_commit.time_from_now}</span>
|
||||
</div>
|
||||
)
|
||||
}else{
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const downloadUrl = ()=>{
|
||||
if(branchLastCommit && branchLastCommit.zip_url){
|
||||
return(
|
||||
<Menu>
|
||||
<Menu.Item><a href={branchLastCommit.zip_url}>ZIP</a></Menu.Item>
|
||||
<Menu.Item><a href={branchLastCommit.tar_url}>TAR.GZ</a></Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const urlRoot = filePath && filePath.length > 0 ? `/${filePath[filePath.length - 1].path}` : "";
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
rootData &&
|
||||
<React.Fragment>
|
||||
{
|
||||
rootData.length > 0 ?
|
||||
<div>
|
||||
<Top { ...this.props } {...this.state} />
|
||||
<div className="f-wrap-between mt20">
|
||||
<div className="f-wrap-alignCenter">
|
||||
<SelectBranch branch={branch} changeBranch={this.changeBranch} {...this.props} {...this.state}></SelectBranch>
|
||||
{
|
||||
filePath && filePath.length > 0 &&
|
||||
<span className="ml20 font-16">
|
||||
<a onClick={()=>this.getProjectRoot(branch)} className="color-blue">{projectsId}</a>
|
||||
{
|
||||
filePath.map((item,key)=>{
|
||||
return(
|
||||
<React.Fragment>
|
||||
{
|
||||
key === filePath.length-1 ?
|
||||
<span className="color-grey-6 subFileName" key={key}>{item.name}</span>
|
||||
:
|
||||
<a onClick={()=>this.ChangeFile(item,key)} className="color-blue subFileName" key={key}>{item.name}</a>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
</span>
|
||||
}
|
||||
|
||||
</div>
|
||||
<div className="f-wrap-alignCenter">
|
||||
{
|
||||
subFileType !== "file" && (isManager || isDeveloper) &&
|
||||
<p className="addFile mr30">
|
||||
<Link to={`/projects/${projectsId}/coders/${branch}/newfile${urlRoot}`} >新建文件</Link>
|
||||
{/* <Link to={``}>上传文件</Link> */}
|
||||
</p>
|
||||
}
|
||||
{
|
||||
filePath && filePath.length === 0 && <CloneAddress http_url={http_url} downloadUrl={downloadUrl} showNotification={this.props.showNotification}></CloneAddress>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
{/* 文件夹-子目录列表 */}
|
||||
{
|
||||
rootList && <RootTable columns = {columns} data={rootList} title={() => title()}></RootTable>
|
||||
}
|
||||
|
||||
{
|
||||
fileDetail &&
|
||||
<CoderRootFileDetail detail = {fileDetail} {...this.props} {...this.state}></CoderRootFileDetail>
|
||||
}
|
||||
|
||||
{/* readme.txt */}
|
||||
{ this.renderReadMeContent(readMeContent) }
|
||||
</Spin>
|
||||
</div>
|
||||
:
|
||||
<NullData {...this.props} {...this.state} http_url={http_url} ></NullData>
|
||||
}
|
||||
</React.Fragment>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default CoderRootDirectorytext;
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
import React , { Component } from "react";
|
||||
import Editor from "react-monaco-editor";
|
||||
|
||||
import { Popconfirm, Result } from 'antd';
|
||||
|
||||
import { Popconfirm } from 'antd';
|
||||
import './list.css';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
import CodeMirror from 'react-codemirror';
|
||||
require('codemirror/lib/codemirror.css');
|
||||
require('codemirror/mode/javascript/javascript');
|
||||
require('codemirror/mode/xml/xml');
|
||||
require('codemirror/mode/markdown/markdown');
|
||||
|
||||
function bytesToSize(bytes) {
|
||||
if (bytes === 0) return '0 B';
|
||||
let k = 1024,
|
||||
|
|
@ -23,10 +26,11 @@ class CoderRootFileDetail extends Component{
|
|||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
const { detail } = this.props;
|
||||
const { detail, readOnly } = this.props;
|
||||
|
||||
this.setState({
|
||||
value: detail.content
|
||||
value: detail.content,
|
||||
readOnly: readOnly
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -42,21 +46,23 @@ class CoderRootFileDetail extends Component{
|
|||
}
|
||||
|
||||
// 编辑文件
|
||||
changeContent=(e)=>{
|
||||
|
||||
changeMmirror=(e,e1,value)=>{
|
||||
this.setState({
|
||||
value:e
|
||||
value
|
||||
})
|
||||
}
|
||||
|
||||
deleteFile=()=>{
|
||||
const { author , branch , detail }= this.props;
|
||||
const { branch , detail }= this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const url = `/${author.login}/${projectsId}/contents/files/delete.json`;
|
||||
const url = `/repositories/${projectsId}/delete_file.json`;
|
||||
axios.delete(url,{
|
||||
params:{
|
||||
filepath:detail.path,
|
||||
branch
|
||||
branch,
|
||||
sha:detail.sha
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
|
|
@ -76,7 +82,7 @@ class CoderRootFileDetail extends Component{
|
|||
const { author , branch , detail}= this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { value } = this.state;
|
||||
const url =`/${author.login}/${projectsId}/contents/files/update.json`;
|
||||
const url =`/repositories/${projectsId}/update_file.json`;
|
||||
axios.put(url,{
|
||||
filepath:detail.path,
|
||||
branch,
|
||||
|
|
@ -93,32 +99,48 @@ class CoderRootFileDetail extends Component{
|
|||
console.log(error);
|
||||
})
|
||||
}
|
||||
updateCode=(value)=> {
|
||||
this.setState({
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
render(){
|
||||
const { detail } = this.props;
|
||||
const { detail , current_user , isManager , isReporter , isDeveloper } = this.props;
|
||||
const { readOnly ,value } = this.state;
|
||||
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
||||
var options = {
|
||||
lineNumbers: true,
|
||||
mode: 'javascript',
|
||||
readOnly:readOnly?'nocursor':false,
|
||||
autofocus:readOnly?false:true,
|
||||
styleActiveLine:true
|
||||
};
|
||||
return(
|
||||
<div>
|
||||
<div className="branchTable">
|
||||
<p className="branchTitle f-wrap-alignCenter f-wrap-between">
|
||||
<span>{bytesToSize(detail && detail.size)}</span>
|
||||
<span>
|
||||
{
|
||||
readOnly ?
|
||||
<a onClick={this.EditFile} className="ml20"><i className="iconfont icon-bianji font-15 color-grey-6"></i></a>
|
||||
:
|
||||
<React.Fragment>
|
||||
<button type="button" className="ant-btn ant-btn-sm mr10" onClick={this.CancelEdit}><span>取 消</span>
|
||||
</button>
|
||||
<button type="button" className="ant-btn ant-btn-primary ant-btn-sm" onClick={this.UpdateFile}><span>确 定</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
}
|
||||
flag &&
|
||||
<span>
|
||||
{
|
||||
readOnly ?
|
||||
<a onClick={this.EditFile} className="ml20"><i className="iconfont icon-bianji font-15 color-grey-6"></i></a>
|
||||
:
|
||||
<React.Fragment>
|
||||
<button type="button" className="ant-btn ant-btn-sm mr10" onClick={this.CancelEdit}><span>取 消</span>
|
||||
</button>
|
||||
<button type="button" className="ant-btn ant-btn-primary ant-btn-sm" onClick={this.UpdateFile}><span>确 定</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
<Popconfirm title="确认删除这个文件?" className="ml20" okText="确定" cancelText="取消" onConfirm={this.deleteFile}>
|
||||
<a><i className="iconfont icon-shanchu font-15 color-grey-6"></i></a>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
<Popconfirm title="确认删除这个文件?" className="ml20" okText="确定" cancelText="取消" onConfirm={this.deleteFile}>
|
||||
<a><i className="iconfont icon-shanchu font-15 color-grey-6"></i></a>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
<div className="content-file">
|
||||
|
|
@ -128,13 +150,7 @@ class CoderRootFileDetail extends Component{
|
|||
<a href={detail.download_url} className="color-blue font-15">下载原始文件</a>
|
||||
</div>
|
||||
:
|
||||
<Editor
|
||||
height="300px"
|
||||
theme={"vs-dark"}
|
||||
value={value}
|
||||
onChange={this.changeContent}
|
||||
readOnly={readOnly}
|
||||
/>
|
||||
<CodeMirror ref="editor" value={detail.content} onChange={this.updateCode} options={options} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -144,4 +160,4 @@ class CoderRootFileDetail extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
export default CoderRootFileDetail;
|
||||
export default CoderRootFileDetail;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ const CoderRootBranch = Loadable({
|
|||
loader: () => import('./CoderRootBranch'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
class CoderRootIndex extends Component{
|
||||
|
||||
render(){
|
||||
|
|
@ -28,17 +29,17 @@ class CoderRootIndex extends Component{
|
|||
return(
|
||||
<div className="main">
|
||||
<Switch {...this.props}>
|
||||
<Route path="/projects/:projectsId/coder/commit"
|
||||
<Route path="/projects/:projectsId/coders/commit"
|
||||
render={
|
||||
(props) => (<CoderRootCommit {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coder/branch"
|
||||
<Route path="/projects/:projectsId/coders/branch"
|
||||
render={
|
||||
(props) => (<CoderRootBranch {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coder"
|
||||
<Route path="/projects/:projectsId/coders"
|
||||
render={
|
||||
(props) => (<CoderRootDirectory {...this.props} {...props} {...this.state} />)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link , Route , Switch } from 'react-router-dom';
|
||||
import { Spin , Tooltip } from 'antd';
|
||||
import { Link , Route , Switch,withRouter } from 'react-router-dom';
|
||||
|
||||
import '../css/index.css'
|
||||
import './list.css';
|
||||
|
|
@ -20,6 +21,7 @@ import img_focus from '../Images/focus.png';
|
|||
import img_parised from '../Images/parised.png';
|
||||
import img_focused from '../Images/focused.png';
|
||||
import img_fork from '../Images/fork.png';
|
||||
import img_milepost from '../Images/milepost.png';
|
||||
const FileNew = Loadable({
|
||||
loader: () => import('../Newfile/Index'),
|
||||
loading: Loading,
|
||||
|
|
@ -124,10 +126,12 @@ const TrendsIndex = Loadable({
|
|||
/**
|
||||
* permission:Manager:管理员,Reporter:报告人员(只有读取权限),Developer:开发人员(除不能设置仓库信息外)
|
||||
*/
|
||||
|
||||
class Detail extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
isSpin:false,
|
||||
projectDetail:undefined,
|
||||
isManager:false,
|
||||
isReporter:false,
|
||||
|
|
@ -136,47 +140,40 @@ class Detail extends Component{
|
|||
watchers_count:undefined ,
|
||||
praises_count:undefined ,
|
||||
forked_count:undefined,
|
||||
watched: false,
|
||||
praised: false,
|
||||
http_url: undefined,
|
||||
author:undefined,
|
||||
|
||||
branchs:undefined,
|
||||
branchList:undefined,
|
||||
branchLastCommit:undefined,
|
||||
}
|
||||
}
|
||||
|
||||
getUserInfo=()=>{
|
||||
const url = `/users/me.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data.login){
|
||||
this.setState({
|
||||
current_user:result.data
|
||||
})
|
||||
this.getDetail();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
componentDidMount=()=>{
|
||||
// this.getUserInfo();
|
||||
this.getDetail();
|
||||
}
|
||||
|
||||
// componentDidUpdate=(provState)=>{
|
||||
// if(provState.match.params.projectsId !== this.props.match.params.projectsId){
|
||||
// this.getDetail();
|
||||
// }
|
||||
// }
|
||||
componentDidUpdate=(prevState)=>{
|
||||
if((prevState.match.params.projectsId !== this.props.match.params.projectsId)){
|
||||
this.getDetail();
|
||||
}
|
||||
|
||||
const { search } = this.props.location;
|
||||
const search_c = prevState.location && prevState.location.search;
|
||||
if( search && search!== search_c){
|
||||
// console.log("branches",this.props.location);
|
||||
// console.log("branches_p",prevState.location);
|
||||
// console.log("111",this.props.dataquerys);
|
||||
const { projectsId } = this.props.match.params;
|
||||
this.getBranch(projectsId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getDetail=()=>{
|
||||
console.log("state",this.props)
|
||||
const { state } = this.props.history.location;
|
||||
const { current_user } = this.props
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/${state ? state : current_user && current_user.login}/${projectsId}.json`;
|
||||
const url = `/repositories/${projectsId}.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
|
|
@ -187,7 +184,8 @@ class Detail extends Component{
|
|||
isDeveloper:result.data.permission && result.data.permission === "Developer",
|
||||
http_url: result.data.clone_url,
|
||||
author:result.data.author,
|
||||
|
||||
praised: result.data.praised,
|
||||
watched: result.data.watched,
|
||||
watchers_count:result.data.watchers_count,
|
||||
praises_count:result.data.praises_count,
|
||||
forked_count:result.data.forked_count,
|
||||
|
|
@ -202,66 +200,75 @@ class Detail extends Component{
|
|||
// 关注和取消关注
|
||||
focusFunc =(flag)=>{
|
||||
const { project_id } = this.state;
|
||||
if(!flag){
|
||||
const url = `/projects/${project_id}/watchers/follow.json`;
|
||||
axios.post(url).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification('关注成功');
|
||||
this.getDetail();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}else{
|
||||
const url = `/projects/${project_id}/watchers/unfollow.json`;
|
||||
axios.delete(url).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification('取消关注成功');
|
||||
this.getDetail();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
axios({
|
||||
method: flag? 'delete' : 'post',
|
||||
url: `/projects/${project_id}/watchers/${flag? 'unfollow' : 'follow'}.json`
|
||||
})
|
||||
.then(result => {
|
||||
if(result && result.data.status === 0){
|
||||
this.setWatchersCount(result.data.watchers_count, result.data.watched);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
// 点赞和取消点赞
|
||||
pariseFunc=(flag)=>{
|
||||
const { project_id } = this.state;
|
||||
if(!flag){
|
||||
const url = `/projects/${project_id}/praise_tread/like.json`;
|
||||
axios.post(url).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification('点赞成功');
|
||||
this.getDetail();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}else{
|
||||
const url = `/projects/${project_id}/praise_tread/unlike.json`;
|
||||
axios.delete(url).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification('取消点赞成功');
|
||||
this.getDetail();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
axios({
|
||||
method: flag? 'delete' : 'post',
|
||||
url: `/projects/${project_id}/praise_tread/${flag? 'unlike' : 'like'}.json`
|
||||
})
|
||||
.then(result => {
|
||||
if(result && result.data.status === 0){
|
||||
this.setPraisesCount(result.data.praises_count, result.data.praised)
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
setWatchersCount = (count, is_watched) => {
|
||||
this.setState({
|
||||
watched: is_watched,
|
||||
watchers_count: count
|
||||
})
|
||||
}
|
||||
|
||||
setPraisesCount = (count, is_praised) => {
|
||||
this.setState({
|
||||
praised: is_praised,
|
||||
praises_count: count
|
||||
})
|
||||
}
|
||||
|
||||
// fork项目
|
||||
forkFunc=()=>{
|
||||
const { checkIfLogin } = this.props;
|
||||
if(!checkIfLogin){
|
||||
this.props.showLoginDialog();
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
const { project_id } = this.state;
|
||||
const url = `/projects/${project_id}/forks.json`;
|
||||
axios.post(url).then(result=>{
|
||||
if(result && result.data.status === 0){
|
||||
this.props.history.push(`/projects/${result.data.identifier}/coder`);
|
||||
}else{
|
||||
if (result && result.data.status === 0) {
|
||||
this.props.history.push(`/projects/${result.data.id}/coders`);
|
||||
this.props.showNotification(result.data.message);
|
||||
}
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
}).catch(error=>{
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
|
@ -281,227 +288,267 @@ class Detail extends Component{
|
|||
branchList:result.data,
|
||||
branchs,
|
||||
branchLastCommit:result.data[0],
|
||||
// http_url:result.data[0].http_url
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
const { projectDetail , watchers_count , praises_count , forked_count , project_id } = this.state;
|
||||
const { projectDetail , watchers_count , praises_count , forked_count , isSpin , isManager, watched, praised } = this.state;
|
||||
const url = this.props.history.location.pathname;
|
||||
const urlFlag = (url.split("/").length === 3);
|
||||
const { isManager , isDeveloper } = this.props;
|
||||
const urlArr= url.split("/");
|
||||
const urlFlag = (urlArr.length === 3);
|
||||
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
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}/projects`} className="show-user-link color-grey-ccc">{projectDetail.fork_info.fork_project_user_name}</Link>
|
||||
<span> / </span>
|
||||
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`} className="color-grey-ccc">{ projectDetail.fork_info.fork_form_name }</Link>
|
||||
</React.Fragment>:""
|
||||
);
|
||||
return(
|
||||
<div>
|
||||
<div className="detailHeader-wrapper">
|
||||
<div className="normal">
|
||||
<div className="f-wrap-between mb20">
|
||||
<p className="font-18 color-white df flex-1 lineH2 mt15" style={{alignItems:"center"}}>
|
||||
{projectDetail && projectDetail.author && projectDetail.author.name}
|
||||
<span className="ml5 mr5">/</span>
|
||||
<span className="hide-1 flex-1">
|
||||
<Link to={`/projects/${projectsId}/coder`} className="color-white">{ projectDetail && projectDetail.identifier }</Link>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="f-wrap-between">
|
||||
<ul className="headerMenu-wrapper">
|
||||
<li className={(url.indexOf("coder")>0 || urlFlag)? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/coder`,state}}><img alt="" src={img_1} width="18" />代码</Link></li>
|
||||
<li className={url.indexOf("orders")>0 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/orders`,state}}><img alt="" src={img_2} width="12" />工单{projectDetail&&projectDetail.issues_count===0?"":projectDetail&&projectDetail.issues_count===0?projectDetail.issues_count:""}</Link></li>
|
||||
<li className={url.indexOf("merge")>0 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/merge`,state}}><img alt="" src={img_3} width="13" />合并请求{projectDetail&&projectDetail.pull_requests_count===0?"":projectDetail&&projectDetail.pull_requests_count===0?projectDetail.pull_requests_count:""}</Link></li>
|
||||
<li className={url.indexOf("version")>0 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/version`,state}}><img alt="" src={img_4} width="16" />版本发布</Link></li>
|
||||
<li className={url.indexOf("trends")>0 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/trends`,state}}><img alt="" src={img_6} width="16" />动态</Link></li>
|
||||
{
|
||||
isManager &&
|
||||
<li className={url.indexOf("setting")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
|
||||
}
|
||||
</ul>
|
||||
<span className="df">
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={()=>this.focusFunc(projectDetail && projectDetail.watched)}>
|
||||
<img src={projectDetail && projectDetail.watched ? img_focused : img_focus} alt="" width="14px"/>
|
||||
{projectDetail && projectDetail.watched ? '取消关注':'关注'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="detailHeader-wrapper">
|
||||
<div className="normal">
|
||||
<div className="f-wrap-between mb15" style={{position:"relative"}}>
|
||||
<p className="font-18 color-white df flex-1 lineH2 mt15" style={{alignItems:"center"}}>
|
||||
|
||||
{projectDetail && projectDetail.author &&
|
||||
<Link to={`/users/${projectDetail.author.login}/projects`} className="show-user-link color-white">
|
||||
{projectDetail.author.name}
|
||||
</Link>
|
||||
}
|
||||
<span className="ml5 mr5">/</span>
|
||||
<span className="hide-1 flex-1 df">
|
||||
<Link to={`/projects/${projectsId}/coders`} className="color-white">{ projectDetail && projectDetail.name }</Link>
|
||||
{
|
||||
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
|
||||
<Tooltip placement={'right'} title={text}>
|
||||
<Link to={`/projects/${projectDetail.forked_from_project_id}/coders`}
|
||||
className="ml20" >
|
||||
<i className="iconfont icon-fork color-grey-74 font-20 fl"></i>
|
||||
</Link>
|
||||
</Tooltip>:""
|
||||
}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="f-wrap-between">
|
||||
<ul className="headerMenu-wrapper">
|
||||
<li className={(url.indexOf("coders")>-1 || urlFlag) ? "active" : ""}>
|
||||
<Link to={{pathname:`/projects/${projectsId}/coders`,state}}><img alt="" src={img_1} width="18" />代码库</Link>
|
||||
</li>
|
||||
<li className={(url.indexOf("orders")>-1 && !(url.indexOf("Milepost")>0 || url.indexOf("meilpost")>0 || url.indexOf("tags")>0))? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/orders`,state}}><img alt="" src={img_2} width="12" />任务{projectDetail&&projectDetail.issues_count===0?"":projectDetail&&projectDetail.issues_count===0?projectDetail.issues_count:""}</Link></li>
|
||||
<li className={url.indexOf("merge")>-1 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/merge`,state}}><img alt="" src={img_3} width="13" />合并请求{projectDetail&&projectDetail.pull_requests_count===0?"":projectDetail&&projectDetail.pull_requests_count===0?projectDetail.pull_requests_count:""}</Link></li>
|
||||
<li className={url.indexOf("version")>-1 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/version`,state}}><img alt="" src={img_4} width="16" />版本发布</Link></li>
|
||||
|
||||
<li className={(url.indexOf("Milepost")>-1 || url.indexOf("meilpost")>-1) ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/orders/Milepost`,state}}><img alt="" src={img_milepost} width="16" />里程碑</Link></li>
|
||||
<li className={url.indexOf("trends")>-1 ? "active" : ""}><Link to={{pathname:`/projects/${projectsId}/trends`,state}}><img alt="" src={img_6} width="16" />动态</Link></li>
|
||||
{
|
||||
isManager &&
|
||||
<li className={url.indexOf("setting")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/setting`}><img alt="" src={img_7} width="19" />仓库设置</Link></li>
|
||||
}
|
||||
|
||||
</ul>
|
||||
<span className="df">
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={()=>this.focusFunc(watched)}>
|
||||
<img src={watched ? img_focused : img_focus} alt="" width="14px"/>
|
||||
{watched ? '取消关注':'关注'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={()=>this.pariseFunc(praised)}>
|
||||
<img src={praised ? img_parised : img_parise} width="13px" alt=""/>
|
||||
{praised ? '取消点赞':'点赞'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
||||
<img src={img_fork} alt="" width="10px"/>Fork</a>
|
||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||
</span>
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={()=>this.pariseFunc(projectDetail && projectDetail.praised)}>
|
||||
<img src={projectDetail && projectDetail.praised ? img_parised : img_parise} width="13px" alt=""/>
|
||||
{projectDetail && projectDetail.praised ? '取消点赞':'点赞'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
||||
<img src={img_fork} alt="" width="10px"/>Fork</a>
|
||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Switch {...this.props}>
|
||||
{/* 新建文件 */}
|
||||
<Route path="/projects/:projectsId/coder/:branch/newfile/:path"
|
||||
render={
|
||||
(props) => (<FileNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coder/:branch/newfile"
|
||||
render={
|
||||
(props) => (<FileNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Switch {...this.props}>
|
||||
{/* 新建文件 */}
|
||||
<Route path="/projects/:projectsId/coders/:branch/newfile/:path"
|
||||
render={
|
||||
(props) => (<FileNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/:branch/newfile"
|
||||
render={
|
||||
(props) => (<FileNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* 标签列表 */}
|
||||
<Route path="/projects/:projectsId/orders/tags"
|
||||
render={
|
||||
(props) => (<TagList {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 仓库设置 */}
|
||||
<Route path="/projects/:projectsId/setting"
|
||||
render={
|
||||
(props) => (<Setting {...this.props} {...props} {...this.state} getDetail={this.getDetail}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 工单详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/detail"
|
||||
render={
|
||||
(props) => (<OrderDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 里程碑 */}
|
||||
<Route path="/projects/:projectsId/orders/Milepost"
|
||||
render={
|
||||
(props) => (<OrderMilepost {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 新建里程碑 */}
|
||||
<Route path="/projects/:projectsId/orders/meilpost"
|
||||
render={
|
||||
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/*里程碑详情*/ }
|
||||
<Route path="/projects/:projectsId/orders/:meilid/MilepostDetail"
|
||||
render={
|
||||
(props) => (<MilepostDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/*修改里程碑*/}
|
||||
<Route path="/projects/:projectsId/orders/:meilid/meilpost"
|
||||
render={
|
||||
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 标签列表 */}
|
||||
<Route path="/projects/:projectsId/orders/tags"
|
||||
render={
|
||||
(props) => (<TagList {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 仓库设置 */}
|
||||
<Route path="/projects/:projectsId/setting"
|
||||
render={
|
||||
(props) => (<Setting {...this.props} {...props} {...this.state} getDetail={this.getDetail}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 任务详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/detail"
|
||||
render={
|
||||
(props) => (<OrderDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 里程碑 */}
|
||||
<Route path="/projects/:projectsId/orders/Milepost"
|
||||
render={
|
||||
(props) => (<OrderMilepost {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 新建里程碑 */}
|
||||
<Route path="/projects/:projectsId/orders/meilpost"
|
||||
render={
|
||||
(props) => (<OrdernewMilepost {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/*里程碑详情*/ }
|
||||
<Route path="/projects/:projectsId/orders/:meilid/MilepostDetail"
|
||||
render={
|
||||
(props) => (<MilepostDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/*修改里程碑*/}
|
||||
<Route path="/projects/:projectsId/orders/:meilid/meilpost"
|
||||
render={
|
||||
(props) => (<OrderupdateMilepost {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
|
||||
{/* 新建工单 */}
|
||||
{/* 里程碑页面新建任务 */}
|
||||
<Route path="/projects/:projectsId/orders/:milepostId/new"
|
||||
render={
|
||||
(props) => (<OrderNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 新建任务 */}
|
||||
<Route path="/projects/:projectsId/orders/new"
|
||||
render={
|
||||
(props) => (<OrderNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/orders/new"
|
||||
render={
|
||||
(props) => (<OrderNew {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 修改详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/updatedetail"
|
||||
render={
|
||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* 修改详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/updatedetail"
|
||||
render={
|
||||
(props) => (<OrderupdateDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 复制详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/copyetail"
|
||||
render={
|
||||
(props) => (<OrdercopyDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* 复制详情 */}
|
||||
<Route path="/projects/:projectsId/orders/:orderId/copyetail"
|
||||
render={
|
||||
(props) => (<OrdercopyDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* 动态 */}
|
||||
<Route path="/projects/:projectsId/trends"
|
||||
render={
|
||||
(props) => (<TrendsIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 动态 */}
|
||||
<Route path="/projects/:projectsId/trends"
|
||||
render={
|
||||
(props) => (<TrendsIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
|
||||
{/* 代码Index */}
|
||||
<Route path="/projects/:projectsId/orders"
|
||||
render={
|
||||
(props) => (<OrderIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 代码Index */}
|
||||
<Route path="/projects/:projectsId/orders"
|
||||
render={
|
||||
(props) => (<OrderIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/merge/new"
|
||||
render={
|
||||
(props) => (<CreateMerge {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/new"
|
||||
render={
|
||||
(props) => (<CreateMerge {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge"
|
||||
render={
|
||||
(props) => (<UpdateMerge {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/UpdateMerge"
|
||||
render={
|
||||
(props) => (<UpdateMerge {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/Messagecount"
|
||||
render={
|
||||
(props) => (<MessageCount {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/Messagecount"
|
||||
render={
|
||||
(props) => (<MessageCount {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/MergeSubmit"
|
||||
render={
|
||||
(props) => (<MergeSubmit {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/version/new"
|
||||
render={
|
||||
(props) => (<NewVersionIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/merge/:mergeId/MergeSubmit"
|
||||
render={
|
||||
(props) => (<MessageCount {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/version/new"
|
||||
render={
|
||||
(props) => (<NewVersionIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
|
||||
<Route path="/projects/:projectsId/version/:versionId/upversion"
|
||||
render={
|
||||
(props) => (<UpVersionIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/version/:versionId/upversion"
|
||||
render={
|
||||
(props) => (<UpVersionIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
|
||||
<Route path="/projects/:projectsId/version"
|
||||
render={
|
||||
(props) => (<VersionIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/version"
|
||||
render={
|
||||
(props) => (<VersionIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
<Route path="/projects/:projectsId/merge"
|
||||
render={
|
||||
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coder"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
<Route path="/projects/:projectsId/merge"
|
||||
render={
|
||||
(props) => (<MergeIndexDetail {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders/filesurl"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/coders"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
</Spin>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Detail;
|
||||
export default withRouter(Detail);
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ class DetailTop extends Component{
|
|||
const { pathname } = this.props.location;
|
||||
return(
|
||||
<p className="branch-wrapper">
|
||||
<Link to={`/projects/${projectsId}/coder/commit`} className={ pathname.indexOf("/coder/commit") > 0 ? "active" : ""}>
|
||||
<Link to={`/projects/${projectsId}/coders/commit`} className={ pathname.indexOf("/coders/commit") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-tijiaojilu font-18 mr3"></i>
|
||||
<span className="mr3">{projectDetail && projectDetail.commits_count}</span>提交
|
||||
</Link>
|
||||
<Link to={`/projects/${projectsId}/coder/branch`} className={ pathname.indexOf("/coder/branch") > 0 ? "active" : ""}>
|
||||
<Link to={`/projects/${projectsId}/coders/branch`} className={ pathname.indexOf("/coders/branch") > 0 ? "active" : ""}>
|
||||
<i className="iconfont icon-fenzhi font-18 mr3"></i>
|
||||
<span className="mr3">{projectDetail && projectDetail.branches_count}</span>分支
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -157,7 +157,8 @@ class Index extends Component{
|
|||
page:1,
|
||||
search:value,
|
||||
isSpin:true,
|
||||
project_type:undefined
|
||||
project_type:undefined,
|
||||
sort: "updated_on"
|
||||
})
|
||||
const { limit , sort , category_id } = this.state;
|
||||
this.getListData(1 ,limit, value , sort , undefined,category_id);
|
||||
|
|
@ -177,6 +178,7 @@ class Index extends Component{
|
|||
}
|
||||
|
||||
render(){
|
||||
const { current_user } = this.props;
|
||||
const menu=(
|
||||
<Menu onClick={this.ChangeSoryBy}>
|
||||
<Menu.Item key="updated_on">更新时间排序</Menu.Item>
|
||||
|
|
@ -200,6 +202,8 @@ class Index extends Component{
|
|||
<Pagination simple defaultCurrent={page} total={total} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>:""
|
||||
)
|
||||
|
||||
|
||||
return(
|
||||
<div style={{background:"#fafafa"}}>
|
||||
<p className="t_project_banner"></p>
|
||||
|
|
@ -218,11 +222,15 @@ class Index extends Component{
|
|||
<Spin spinning={isSpin}>
|
||||
<div className="list-r-operation">
|
||||
<div>
|
||||
<Dropdown overlay={newItem} trigger={["click"]} placement='bottomRight' className="mr30">
|
||||
<a className="ant-dropdown-link">
|
||||
<span className="color-blue font-16"><img src={img_new} alt="" width="13px"/> 新建</span>
|
||||
</a>
|
||||
</Dropdown>
|
||||
{
|
||||
current_user && current_user.login &&
|
||||
<Dropdown overlay={newItem} trigger={["click"]} placement='bottomRight' className="mr30">
|
||||
<a className="ant-dropdown-link">
|
||||
<span className="color-blue font-16"><img src={img_new} alt="" width="13px"/> 新建</span>
|
||||
</a>
|
||||
</Dropdown>
|
||||
}
|
||||
|
||||
<Dropdown overlay={menu} trigger={['click']} placement='bottomRight'>
|
||||
<a className="ant-dropdown-link">
|
||||
<span className="color-blue font-16">排序 <img src={img_array} alt="" width="10px"/></span>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
|
|||
import '../css/index.css'
|
||||
import './list.css';
|
||||
import img_parise from '../Images/parise.png';
|
||||
import img_fork from '../Images/fork.png';
|
||||
class IndexItem extends Component{
|
||||
// constructor(props){
|
||||
// super(props);
|
||||
|
|
@ -22,16 +23,33 @@ class IndexItem extends Component{
|
|||
projects && projects.length >0 ? projects.map((item,key)=>{
|
||||
return(
|
||||
<div className="p-r-Item" key={key}>
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`images/${item.author && item.author.image_url}`)} ></img>
|
||||
<Link to={`/users/${item.author.login}/projects`} className="show-user-link">
|
||||
<img className="p-r-photo" alt="" src={getImageUrl(`images/${item.author && item.author.image_url}`)} ></img>
|
||||
|
||||
</Link>
|
||||
<div className="p-r-Infos">
|
||||
<div className="p-r-name">
|
||||
<a onClick={()=>this.TurnToDetail(`${item.author && item.author.login}`,`/projects/${item.identifier}/coder`)} className="hide-1 font-16 color-grey-3" style={{whiteSpace:"wrap"}}>{item.name}</a>
|
||||
<Link to={`/projects/${item.id}/coders`} className="hide-1 color-grey-3 font-18 task-hide " style={{whiteSpace:"wrap",display:'flex',width:400}}>
|
||||
{item.author.name}/{item.name}
|
||||
{
|
||||
item.forked_from_project_id ?
|
||||
<span className="ml5">
|
||||
<img src={img_fork} alt="" width="14px"/>
|
||||
</span>
|
||||
: ""
|
||||
}
|
||||
|
||||
</Link>
|
||||
{
|
||||
item.is_public ? "" :
|
||||
<span className="p-r-tags"><span>私有</span></span>
|
||||
}
|
||||
</div>
|
||||
<div className="p-r-content">
|
||||
<p className="break_word task-hide flex1" style={{maxHeight:"40px"}}>{item.description}</p>
|
||||
<p className="break_word task-hide flex1" style={{maxHeight:"40px",width:"0"}}>{item.description}</p>
|
||||
<span className="p-r-tags">
|
||||
{/* { item.forked_count ? <span><label>Fork</label><span>{ item.forked_count}</span></span>:"" } */}
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg"/>点赞 ({ item.praises_count })</span>
|
||||
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg"/>赞 ({ item.praises_count })</span>
|
||||
{ item.language && item.language.id ? <span><label>{ item.language.name }</label></span>:"" }
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ body,#root{
|
|||
.detailHeader-wrapper{
|
||||
background:url(../Images/banner_sub.png) no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
height: 120px;
|
||||
height: 125px;
|
||||
}
|
||||
.headerMenu-wrapper{
|
||||
font-size: 16px;
|
||||
|
|
@ -267,6 +267,10 @@ body,#root{
|
|||
.headerMenu-wrapper li.active{
|
||||
background:linear-gradient(180deg,rgba(58,194,255,1) 0%,rgba(27,143,255,1) 100%);
|
||||
border-radius: 15px;
|
||||
|
||||
}
|
||||
.headerMenu-wrapper li.active a {
|
||||
color: #fff !important;
|
||||
}
|
||||
.detail_tag_btn{
|
||||
height:30px;
|
||||
|
|
@ -368,8 +372,8 @@ body,#root{
|
|||
}
|
||||
/* 分支 */
|
||||
.branchTable{
|
||||
border:1px solid #f4f4f4;
|
||||
background-color: #f4f4f4;
|
||||
border:1px solid #f7f7f7;
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 4px;
|
||||
margin-top:20px;
|
||||
}
|
||||
|
|
@ -442,10 +446,10 @@ body,#root{
|
|||
padding: 0px 10px;
|
||||
}
|
||||
.addFile a:first-child{
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.addFile a:last-child{
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
/* border-radius: 0px 4px 4px 0px; */
|
||||
border-left: 1px solid rgba(247, 247, 247, 0.3);
|
||||
}
|
||||
.addFile a:active{
|
||||
|
|
@ -492,14 +496,16 @@ body,#root{
|
|||
margin-top: 25px;
|
||||
}
|
||||
.commonBox .commonBox-title{
|
||||
padding:10px 15px;
|
||||
padding:3px 15px;
|
||||
box-sizing: border-box;
|
||||
font-size: 18px;
|
||||
font-size: 15px;
|
||||
background: #f0f0f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.commonBox .commonBox-info{
|
||||
padding:20px 15px;
|
||||
}
|
||||
.commonBox-title-read{vertical-align: middle;}
|
||||
|
||||
@media screen and (max-width: 370px){
|
||||
.p-r-tags,.p-r-btn{
|
||||
|
|
@ -559,4 +565,24 @@ body,#root{
|
|||
border: 1px solid #2185d0;
|
||||
}
|
||||
.content-file{margin-top: 8px;}
|
||||
|
||||
.content-file .CodeMirror{
|
||||
background-color: #f7f7f7;
|
||||
border: 1px solid #e4e4e4;
|
||||
border-radius: 4px;
|
||||
height: auto;
|
||||
}
|
||||
.text-center{text-align: center;}
|
||||
.fork-css{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50px;
|
||||
width: 100%;
|
||||
}
|
||||
.color-grey-ccc{
|
||||
color: #ccc !important;
|
||||
}
|
||||
a.color-grey-ccc:hover{
|
||||
color: #4cacff !important;
|
||||
}
|
||||
.pull-right{float: right;}
|
||||
|
|
@ -6,7 +6,7 @@ import Nav from '../Order/Nav';
|
|||
import UploadComponent from '../Upload/Index';
|
||||
|
||||
import{ Modal,Col,Form,Input,Tooltip,Popconfirm } from 'antd'
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import NoneData from '../Nodata';
|
||||
|
||||
|
||||
const TextArea = Input.TextArea;
|
||||
|
|
@ -108,7 +108,7 @@ class MergeDetail extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
//关闭工单
|
||||
//关闭任务
|
||||
closedetail=(id)=>{
|
||||
const {projectsId,orderId} = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}/close_issue.json`;
|
||||
|
|
@ -164,7 +164,7 @@ class MergeDetail extends Component{
|
|||
})
|
||||
}
|
||||
render(){
|
||||
const { projectsId,mergeid} = this.props.match.params;
|
||||
const { projectsId , mergeid } = this.props.match.params;
|
||||
const { data,journalsdata, showFiles } = this.state;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const url = this.props.history.location.pathname;
|
||||
|
|
@ -226,38 +226,53 @@ class MergeDetail extends Component{
|
|||
)
|
||||
}else{
|
||||
return(
|
||||
<NoneData />
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
<Link to={`/projects/${projectsId}/merge/new`} className="topWrapper_btn">创建合并请求</Link>
|
||||
</div>
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state}/>*/}
|
||||
{/*{*/}
|
||||
{/*data && data.issue.user_permission ?*/}
|
||||
{/*<Link to={`/projects/${projectsId}/merge/new`} className="topWrapper_btn">创建合并请求</Link>*/}
|
||||
{/*: ''*/}
|
||||
{/*}*/}
|
||||
|
||||
{/*</div>*/}
|
||||
<div>
|
||||
<div className="detailContent">
|
||||
<p>
|
||||
<span className="font-16" > { data && data.issue.subject}</span>
|
||||
<div>
|
||||
<Link to={`/projects/${projectsId}/merge/${mergeid}/updatemerge`} className="color-blue fr">编辑</Link>
|
||||
<div>
|
||||
{
|
||||
data && data.issue.user_permission ?
|
||||
<Link to={`/projects/${projectsId}/merge/${mergeid}/updatemerge`} className="color-blue fr">编辑</Link>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
</p>
|
||||
<p className="mt15">{ data && data.issue.description}</p>
|
||||
<p className="mt10 color-grey-c">
|
||||
<p className="mt10">
|
||||
<div className={data&&data.issue_status==="关闭"?"closedetail":"opendetail"}>{data&&data.issue_status==="关闭"?"关闭中!":"开启中!"} </div>
|
||||
由 { data && data.issue.author_name} 于 { data && data.issue.created_at }创建{ data && data.issue.journals_count && data.issue.journals_count > 0 ?` · ${data.issue.journals_count} 条评论`:""}
|
||||
<span className="color-grey-c">
|
||||
由 { data && data.issue.author_name} 于 { data && data.issue.created_at }创建{ data && data.issue.journals_count && data.issue.journals_count > 0 ?` · ${data.issue.journals_count} 条评论`:""}
|
||||
</span>
|
||||
|
||||
<span className="span_title ml10">
|
||||
请求从<strong> {data && data.pull_request.head} </strong>分支合并到<strong> {data && data.pull_request.base} </strong>分支
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div className="detailHeader-wrapper">
|
||||
<div className="normal f-wrap-between">
|
||||
<ul className="headerMenu-wrapper">
|
||||
<li className={url.indexOf("Messagecount")>0? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeid}/Messagecount`}>对话内容</Link></li>
|
||||
<li className={url.indexOf("MergeSubmit")>0 ? "active" : ""}><Link to={`projects/${projectsId}/merge/${mergeid}/MergeSubmit`}>代码提交</Link></li>
|
||||
<li className={url.indexOf("MergeSubmit")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeid}/MergeSubmit`}>代码提交</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -304,9 +319,9 @@ class MergeDetail extends Component{
|
|||
<span className="span_title">指派给</span>
|
||||
<span>{data && data.issue.assign_user_name}</span>
|
||||
</p>
|
||||
<p>
|
||||
<p style={{display: "inline-block",'white-space': "nowrap" }}>
|
||||
<span className="span_title">里程碑</span>
|
||||
<span>{data&&data.issue.version===null?"未添加里程碑":data&&data.issue.version.length===0?data.issue.version:'未添加里程碑'}</span>
|
||||
<span className="title_overflow">{data&&data.issue.version===null?"未添加里程碑":data&&data.issue.version.length===0?data.issue.version:'未添加里程碑'}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,29 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {Popconfirm} from "antd";
|
||||
|
||||
class MergeItem extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
//显示 隐藏
|
||||
isdisplay:false,
|
||||
orderid:'',
|
||||
}
|
||||
}
|
||||
|
||||
onMouseMove=(type)=>{
|
||||
this.setState({
|
||||
isdisplay:true,
|
||||
orderid:type
|
||||
})
|
||||
}
|
||||
|
||||
onMouseOut=()=>{
|
||||
this.setState({
|
||||
isdisplay:false
|
||||
})
|
||||
}
|
||||
|
||||
set_issue_tags =(issue_tags)=>{
|
||||
if(issue_tags && issue_tags.length > 0){
|
||||
|
|
@ -20,6 +42,7 @@ class MergeItem extends Component{
|
|||
render(){
|
||||
const { issues , search_count , page , limit } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { current_user } = this.props;
|
||||
const renderList =()=>{
|
||||
if(issues && issues.length > 0){
|
||||
return(
|
||||
|
|
@ -28,7 +51,7 @@ class MergeItem extends Component{
|
|||
<div className="issueItem">
|
||||
<div className="flex-1">
|
||||
<p className="mb15 df">
|
||||
<span className="issueNo"># {search_count - (key + (page-1) * limit)}</span>
|
||||
<span className={item.issue_status==="关闭"? "issueNo":"issueNo issueOpen"}># {search_count - (key + (page-1) * limit)}</span>
|
||||
<Link to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`} className="flex-1 hide-1 font-16 color-grey-3 lineh-30">{item.name}</Link>
|
||||
</p>
|
||||
<p className="color-grey-6 font-12">
|
||||
|
|
@ -41,12 +64,36 @@ class MergeItem extends Component{
|
|||
}
|
||||
</p>
|
||||
</div>
|
||||
<ul className="topWrapper_select">
|
||||
<ul className="topWrapper_select no-cursor" onMouseMove={()=>this.onMouseMove(item.id)} onMouseOut={()=>this.onMouseOut()}>
|
||||
<li>{this.set_issue_tags(item.issue_tags)}</li>
|
||||
{/*<li>{item.issue_type || "--"}</li>*/}
|
||||
<li>{item.version || "--"}</li>
|
||||
<li>{item.assign_user_name || "--"}</li>
|
||||
<li>{ item.journals_count ? <span><i className="iconfont icon-pinglun1 mr3 font-16"></i>{item.journals_count}</span> : "" }</li>
|
||||
<li>
|
||||
{
|
||||
item.assign_user_name ?
|
||||
<Link to={`/users/${item.assign_user_login}/projects`} className="show-user-link">
|
||||
{item.assign_user_name}
|
||||
</Link>
|
||||
: "--"
|
||||
}
|
||||
</li>
|
||||
<li>
|
||||
<div className="flex-1">
|
||||
<p>
|
||||
{ item.journals_count ? <Link to={`/projects/${projectsId}/merge/${item.pull_request_id}/Messagecount`}><i className="iconfont icon-pinglun1 mr3 font-16"></i>{item.journals_count}</Link> : "" }
|
||||
</p>
|
||||
{
|
||||
current_user && current_user.login ?
|
||||
<div className="milepostleft" style={{display:this.state.orderid===item.id&&this.state.isdisplay?'flex':'none'}}>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<Link to={`/projects/${projectsId}/merge/${item.pull_request_id}/updatemerge`} className="color-grey-9"><i className="iconfont icon-bianji3 font-14 mr5"></i></Link>
|
||||
</div>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
import React , {Component} from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
|
||||
import axios from 'axios';
|
||||
import Nav from '../Order/Nav';
|
||||
import UploadComponent from '../Upload/Index';
|
||||
|
||||
import{ Modal,Col,Form,Input,Tooltip,Popconfirm,Table} from 'antd'
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import{ Form , Table , Spin } from 'antd'
|
||||
import { getImageUrl } from 'educoder';
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
|
||||
const TextArea = Input.TextArea;
|
||||
|
||||
|
||||
class MergeSubmit extends Component{
|
||||
constructor(props){
|
||||
|
|
@ -30,15 +25,22 @@ class MergeSubmit extends Component{
|
|||
limit:50,
|
||||
page:1,
|
||||
titledata:undefined,
|
||||
isSpin:true
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
|
||||
this.getDetail();
|
||||
// this.getDetail();
|
||||
const { data } = this.props;
|
||||
const { page , limit } = this.state;
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
this.getCommitList( data.pull_request.base , page , limit );
|
||||
}
|
||||
|
||||
getDetail=()=>{
|
||||
|
||||
const { projectsId , mergeId} = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
|
|
@ -46,37 +48,17 @@ class MergeSubmit extends Component{
|
|||
this.setState({
|
||||
data:result.data,
|
||||
})
|
||||
const { page , limit } = this.state;
|
||||
|
||||
this.getCommitList( result.data.pull_request.base , page , limit );
|
||||
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
handleok=() => {
|
||||
this.setState({
|
||||
isShow:false
|
||||
});
|
||||
};
|
||||
handleCancel=()=>{
|
||||
this.setState({
|
||||
isShow:false
|
||||
});
|
||||
}
|
||||
|
||||
imgshow=()=>{
|
||||
this.setState({
|
||||
isShow:true
|
||||
});
|
||||
};
|
||||
|
||||
//获取提交列表
|
||||
getCommitList=(branch , page , limit)=>{
|
||||
const { login } = this.props.current_user;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/${login}/${projectsId}/commits.json`;
|
||||
const url = `/repositories/${projectsId}/commits.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
sha:branch,
|
||||
|
|
@ -89,6 +71,7 @@ class MergeSubmit extends Component{
|
|||
result.data && result.data.commits.length > 0 && result.data.commits.map((item,key)=>{
|
||||
array.push({
|
||||
name:item.author && item.author.name,
|
||||
login: item.author && item.author.login,
|
||||
image_url:item.author && item.author.image_url,
|
||||
sha:item.sha,
|
||||
time_from_now:item.time_from_now,
|
||||
|
|
@ -106,8 +89,8 @@ class MergeSubmit extends Component{
|
|||
|
||||
|
||||
render(){
|
||||
const { projectsId,mergeId} = this.props.match.params;
|
||||
const { data,titledata} = this.state;
|
||||
// const { projectsId,mergeId } = this.props.match.params;
|
||||
const { titledata } = this.state;
|
||||
|
||||
|
||||
const columns=[{
|
||||
|
|
@ -116,8 +99,10 @@ class MergeSubmit extends Component{
|
|||
width:"10%",
|
||||
render: (text,item) => (
|
||||
<span className="f-wrap-alignCenter">
|
||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>
|
||||
<label className="hide-1" style={{maxWidth:"75px"}}>{text}</label>
|
||||
<Link to={`/users/${item.login}/projects`} className="show-user-link">
|
||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>
|
||||
<label className="hide-1" style={{maxWidth:"75px",'vertical-align':'middle'}}>{text}</label>
|
||||
</Link>
|
||||
</span>
|
||||
),
|
||||
},{
|
||||
|
|
@ -154,56 +139,58 @@ class MergeSubmit extends Component{
|
|||
)
|
||||
}
|
||||
|
||||
const url = this.props.history.location.pathname;
|
||||
// const url = this.props.history.location.pathname;
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
<Link to={`/projects/${projectsId}/merge/new`} className="topWrapper_btn">创建合并请求</Link>
|
||||
</div>
|
||||
<div>
|
||||
<div className="detailContent">
|
||||
<p>
|
||||
{
|
||||
data ?
|
||||
<span className="font-20">【{ data.issue.tracker}】</span>
|
||||
:
|
||||
""
|
||||
}
|
||||
<span className="font-20" > { data && data.issue.subject }</span>
|
||||
// <div className="main">
|
||||
// <div className="topWrapper">
|
||||
// <Nav {...this.props} {...this.state}/>
|
||||
// <Link to={`/projects/${projectsId}/merge/new`} className="topWrapper_btn">创建合并请求</Link>
|
||||
// </div>
|
||||
// <div>
|
||||
// <div className="detailContent">
|
||||
// <p>
|
||||
// {
|
||||
// data ?
|
||||
// <span className="font-20">【{ data.issue.issue_classify==='issue'?data.issue.tracker:"合并"}】</span>
|
||||
// :
|
||||
// ""
|
||||
// }
|
||||
// <span className="font-20" > { data && data.issue.subject }</span>
|
||||
|
||||
</p>
|
||||
<p className="mt10 color-grey-c">
|
||||
<span className={data&&data.issue.issue_status==="关闭"?"closedetail":"opendetail"}>{data&&data.issue.issue_status==="关闭"?"关闭中":"开启中"} </span>
|
||||
<span className="ml10 lineH32">
|
||||
由 { data && data.issue.author_name} 于 { data && data.issue.created_at }创建{ data && data.issue.journals_count && data.issue.journals_count > 0 ?` · ${data.issue.journals_count} 条评论`:""}
|
||||
</span>
|
||||
<span className="pull-right lineH32">
|
||||
<Link to={`/projects/${projectsId}/merge/${mergeId}/UpdateMerge`} className="color-blue fr">编辑</Link>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
// </p>
|
||||
// <p className="mt10 color-grey-c">
|
||||
// <span className={data&&data.issue.issue_status==="关闭"?"closedetail":data&&data.pull_request.status===0?"opendetail":"prdetail"}>{data&&data.issue.issue_status==="关闭"?"关闭中":data&&data.pull_request.status===0?"开启中":"已合并"} </span>
|
||||
// <span className="ml10 lineH32">
|
||||
// 由 { data && data.issue.author_name} 于 { data && data.issue.created_at }创建{ data && data.issue.journals_count && data.issue.journals_count > 0 ?` · ${data.issue.journals_count} 条评论`:""}
|
||||
// </span>
|
||||
// <span className="pull-right lineH32">
|
||||
// <Link to={`/projects/${projectsId}/merge/${mergeId}/UpdateMerge`} className="color-blue fr">编辑</Link>
|
||||
// </span>
|
||||
// </p>
|
||||
// </div>
|
||||
|
||||
|
||||
<div className="detailHeader-wrapper">
|
||||
<div className="normal f-wrap-between">
|
||||
<ul className="headerMenu-wrapper" style={{paddingTop:42,paddingLeft:15}}>
|
||||
<li className={url.indexOf("Messagecount")>0? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/Messagecount`}>对话内容</Link></li>
|
||||
<li className={url.indexOf("MergeSubmit")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/MergeSubmit`}>代码提交</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<Table
|
||||
className="mt20 wrap-commit-table"
|
||||
columns={columns}
|
||||
dataSource={titledata}
|
||||
showHeader={false}
|
||||
size="small"
|
||||
pagination={false}
|
||||
title={() => title()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
// <div className="detailHeader-wrapper">
|
||||
// <div className="normal f-wrap-between">
|
||||
// <ul className="headerMenu-wrapper" style={{paddingTop:42,paddingLeft:15}}>
|
||||
// <li className={url.indexOf("Messagecount")>0? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/Messagecount`}>对话内容</Link></li>
|
||||
// <li className={url.indexOf("MergeSubmit")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/MergeSubmit`}>代码提交</Link></li>
|
||||
// </ul>
|
||||
// </div>
|
||||
// </div>
|
||||
<Spin spinning={this.state.isSpin}>
|
||||
<Table
|
||||
className="mt20 wrap-commit-table"
|
||||
columns={columns}
|
||||
dataSource={titledata}
|
||||
showHeader={false}
|
||||
size="small"
|
||||
pagination={false}
|
||||
title={() => title()}
|
||||
/>
|
||||
</Spin>
|
||||
// </div>
|
||||
// </div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,23 @@ import axios from 'axios';
|
|||
import Nav from '../Order/Nav';
|
||||
import UploadComponent from '../Upload/Index';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import {Modal, Col, Form, Input, Tooltip, Popconfirm, Pagination , Spin,Dropdown,Icon,Menu} from 'antd'
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import {Modal, Form, Input, Tooltip, Popconfirm, Pagination, Spin, Dropdown, Icon, Menu, Select} from 'antd'
|
||||
import Attachments from '../Upload/attachment'
|
||||
import './merge.css';
|
||||
import QuillForEditor from '../quillForEditor';
|
||||
import MergeSubmit from './MergeSubmit';
|
||||
import AmplifyImg from '../Order/AmplifyImg';
|
||||
|
||||
|
||||
const Option = Select.Option;
|
||||
const TextArea = Input.TextArea;
|
||||
|
||||
const options = [
|
||||
['bold', 'italic', 'underline'],
|
||||
[{header: [1,2,3,false]}],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['formula']
|
||||
];
|
||||
|
||||
class MessageCount extends Component{
|
||||
constructor(props){
|
||||
|
|
@ -39,11 +48,24 @@ class MessageCount extends Component{
|
|||
mergename:'合并请求',
|
||||
mergekey:'merge',
|
||||
title:'',
|
||||
body:''
|
||||
body:'',
|
||||
commentsContent:undefined,
|
||||
quillFlag:false,
|
||||
SpinFlag:true,
|
||||
editMerge: false,
|
||||
issue_tag_ids: undefined,
|
||||
issue_chosen: undefined,
|
||||
fixed_version_id: undefined,
|
||||
assigned_to_id: undefined,
|
||||
imageUrl:undefined,
|
||||
visible:false
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
this.setState({
|
||||
SpinFlag:true
|
||||
})
|
||||
this.getDetail();
|
||||
}
|
||||
|
||||
|
|
@ -81,12 +103,19 @@ class MessageCount extends Component{
|
|||
|
||||
//添加评论
|
||||
addjournals=()=>{
|
||||
const { data, page, limit, fileList , commentsContent } = this.state;
|
||||
if(!commentsContent){
|
||||
this.setState({
|
||||
quillFlag:true
|
||||
})
|
||||
return;
|
||||
}
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { data, page, limit, fileList } = this.state;
|
||||
const url = `/issues/${data.issue.id}/journals.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
content:JSON.stringify(commentsContent),
|
||||
issue_id:data.id,
|
||||
attachment_ids:fileList
|
||||
}).then(result=>{
|
||||
|
|
@ -96,7 +125,9 @@ class MessageCount extends Component{
|
|||
attachments_ids: undefined
|
||||
});
|
||||
this.setState({
|
||||
showFiles: false
|
||||
showFiles: false,
|
||||
quillFlag:false,
|
||||
commentsContent:undefined
|
||||
})
|
||||
this.getjournalslist(page, limit);
|
||||
this.props.showNotification("评论成功!");
|
||||
|
|
@ -124,7 +155,8 @@ class MessageCount extends Component{
|
|||
search_count:result.data.journals_count,
|
||||
isSpin:false,
|
||||
fileList:undefined,
|
||||
showFiles: true
|
||||
showFiles: true,
|
||||
SpinFlag:false
|
||||
})
|
||||
}
|
||||
}).catch(error=>{
|
||||
|
|
@ -133,7 +165,7 @@ class MessageCount extends Component{
|
|||
}
|
||||
|
||||
|
||||
//关闭工单
|
||||
//关闭任务
|
||||
closedetail=(id)=>{
|
||||
const {projectsId,orderId} = this.props.match.params;
|
||||
const {data } = this.state;
|
||||
|
|
@ -173,14 +205,14 @@ class MessageCount extends Component{
|
|||
|
||||
//修改评论
|
||||
updatedetail=(id)=>{
|
||||
console.log("updtedetail", this.state)
|
||||
// console.log("updtedetail", this.state)
|
||||
const {page, limit,data } = this.state;
|
||||
const {orderId} = this.props.match.params;
|
||||
const url = `/issues/${data.issue.id}/journals/${id}.json`;
|
||||
axios.put(url,{
|
||||
issue_id:orderId,
|
||||
id:id,
|
||||
content:this.state.countvalue
|
||||
content:JSON.stringify(this.state.countvalue)
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
|
|
@ -217,9 +249,9 @@ class MessageCount extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
changmodelname=(e)=>{
|
||||
changmodelname=(value)=>{
|
||||
this.setState({
|
||||
countvalue:e.target.value
|
||||
countvalue:value
|
||||
})
|
||||
}
|
||||
changtitlepr=(e)=>{
|
||||
|
|
@ -295,6 +327,54 @@ class MessageCount extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
handleSubmit=()=>{
|
||||
const { fileList } = this.state;
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId , mergeId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}/simple_update.json`;
|
||||
|
||||
if(values.issue_tag_ids===''){
|
||||
values.issue_tag_ids = []
|
||||
}else{
|
||||
values.issue_tag_ids = [parseInt(values.issue_tag_ids)]
|
||||
}
|
||||
|
||||
if(values.assigned_to_id===0){
|
||||
values.assigned_to_id = ""
|
||||
}
|
||||
axios.post(url,{
|
||||
...values
|
||||
}).then(result=>{
|
||||
if(result.data.status === 0){
|
||||
this.setState({
|
||||
editMerge:false
|
||||
})
|
||||
this.getDetail()
|
||||
this.props.showNotification(result.data.message);
|
||||
|
||||
}
|
||||
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
renderSelect=(list)=>{
|
||||
if(list && list.length >0){
|
||||
return(
|
||||
list.map((item,key)=>{
|
||||
return(
|
||||
<Option key={key+1} value={item.id}>{item.name}</Option>
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 翻页
|
||||
ChangePage=(page)=>{
|
||||
|
|
@ -306,22 +386,161 @@ class MessageCount extends Component{
|
|||
this.getjournalslist(page,limit);
|
||||
}
|
||||
getOption=(e)=>{
|
||||
if(e.key === "rebase"){
|
||||
this.setState({
|
||||
mergename:e.item.props.value,
|
||||
mergekey:e.key,
|
||||
title:'',
|
||||
body:'',
|
||||
buttonshow:'block'
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
mergename:e.item.props.value,
|
||||
mergekey:e.key,
|
||||
title:'',
|
||||
body:'',
|
||||
ismesrge:'block',
|
||||
buttonshow:'block'
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
changeComments=(value)=>{
|
||||
this.setState({
|
||||
mergename:e.item.props.value,
|
||||
mergekey:e.key,
|
||||
title:'',
|
||||
body:''
|
||||
commentsContent:value
|
||||
})
|
||||
if(value){
|
||||
this.setState({
|
||||
quillFlag:false
|
||||
})
|
||||
}
|
||||
}
|
||||
cancelSubmit=()=>{
|
||||
this.setState({
|
||||
editMerge: false
|
||||
})
|
||||
}
|
||||
|
||||
change_to_edit=()=>{
|
||||
const { projectsId , mergeId} = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}/edit.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
issue_chosen:result.data.issue.issue_chosen,
|
||||
issue_tag_ids: result.data.issue.issue_tags && result.data.issue.issue_tags[0].id,
|
||||
fixed_version_id: result.data.issue.fixed_version_id,
|
||||
assigned_to_id: result.data.issue.assigned_to_id,
|
||||
editMerge: true
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
stringJson=(value) =>{
|
||||
let _value = null;
|
||||
|
||||
try {
|
||||
_value = JSON.parse(value);
|
||||
} catch (e) {
|
||||
_value = value;
|
||||
}
|
||||
return _value
|
||||
}
|
||||
commentCtx = (ctx) => {
|
||||
let _ctx = null;
|
||||
|
||||
try {
|
||||
_ctx = JSON.parse(ctx);
|
||||
} catch (e) {
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
return (
|
||||
<QuillForEditor
|
||||
readOnly={true}
|
||||
value={_ctx}
|
||||
showUploadImage={this.handleShowImage}
|
||||
/>
|
||||
)
|
||||
};
|
||||
handleShowImage=(value)=>{
|
||||
this.setState({
|
||||
imageUrl:value,
|
||||
visible:true
|
||||
})
|
||||
}
|
||||
setVisible=(flag)=>{
|
||||
this.setState({
|
||||
visible:flag
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
const { projectsId,mergeId} = this.props.match.params;
|
||||
const { data,journalsdata, page, limit, search_count, isSpin, isedit, showFiles } = this.state;
|
||||
const { projectsId,mergeId } = this.props.match.params;
|
||||
const { data,journalsdata, page, limit, search_count, isSpin, isedit, showFiles , commentsContent , quillFlag, editMerge, issue_tag_ids, issue_chosen,fixed_version_id,assigned_to_id , visible , imageUrl } = this.state;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { current_user } = this.props;
|
||||
const url = this.props.history.location.pathname;
|
||||
|
||||
|
||||
const editMergeForm =()=>{
|
||||
return(
|
||||
<div>
|
||||
<Form>
|
||||
<Form.Item
|
||||
label="标签"
|
||||
>
|
||||
{getFieldDecorator('issue_tag_ids', {
|
||||
initialValue: issue_tag_ids ? [issue_tag_ids] : '',
|
||||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_tag.length > 0 ? '未选择标签':'请在仓库设置里添加标签'}</Option>
|
||||
{this.renderSelect(issue_chosen && issue_chosen.issue_tag)}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="里程碑"
|
||||
>
|
||||
{getFieldDecorator('fixed_version_id', {
|
||||
initialValue: fixed_version_id ? fixed_version_id : "",
|
||||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_version.length > 0 ? '未选择里程碑': '请添加里程碑'}</Option>
|
||||
{this.renderSelect(issue_chosen && issue_chosen.issue_version)}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="指派成员"
|
||||
>
|
||||
{getFieldDecorator('assigned_to_id', {
|
||||
initialValue: assigned_to_id ? assigned_to_id : "",
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>未指派成员</Option>
|
||||
{this.renderSelect(issue_chosen && issue_chosen.assign_user)}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<p className="clearfix mt15 text-right">
|
||||
<a className="topWrapper_btn fr" type="submit" style={{marginLeft: 5}} onClick={this.handleSubmit}>保存</a>
|
||||
<a className="a_btn cancel_btn fr" onClick={this.cancelSubmit}>取消</a>
|
||||
</p>
|
||||
</Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={(e)=>this.getOption(e)}>
|
||||
<Menu.Item key={'merge'} value="合并请求">合并请求</Menu.Item>
|
||||
|
|
@ -349,7 +568,9 @@ class MessageCount extends Component{
|
|||
return(
|
||||
<li key={key}>
|
||||
<div className="df">
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${item.user_picture && item.user_picture}`)} alt=""/></Link>
|
||||
<Link to={`/users/${item && item.user_login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${item && item.user_picture}`)} alt=""/>
|
||||
</Link>
|
||||
<div className="detail_context" >
|
||||
<div className="topWrapper_detali">
|
||||
<p className="ml6 detail_p lineH40">
|
||||
|
|
@ -370,7 +591,7 @@ class MessageCount extends Component{
|
|||
<div style={{display: (isedit && isedit === item.id) ? "none" : "block"}} >
|
||||
{
|
||||
item.content ?
|
||||
<div>{item.content}</div>
|
||||
this.commentCtx(item.content)
|
||||
:
|
||||
<div>
|
||||
{this.renderJournalList(item.journal_details)}
|
||||
|
|
@ -384,7 +605,20 @@ class MessageCount extends Component{
|
|||
}
|
||||
</div>
|
||||
<div style={{display: (isedit && isedit === item.id) ? "block" : "none"}}>
|
||||
<TextArea style={{height:"200px"}} value={this.state.countvalue} onChange={this.changmodelname}/>
|
||||
<QuillForEditor
|
||||
value = {this.stringJson(this.state.countvalue)}
|
||||
wrapStyle={{
|
||||
height: '220px',
|
||||
opacity:1,
|
||||
marginTop:"20px"
|
||||
}}
|
||||
// autoFocus={true}
|
||||
style={{ height: '170px' }}
|
||||
placeholder="评论内容"
|
||||
options={options}
|
||||
onContentChange={this.changmodelname}
|
||||
/>
|
||||
{/* <TextArea style={{height:"200px"}} value={this.state.countvalue} onChange={this.changmodelname}/> */}
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={()=>this.updatedetail(item.id)}>保存</a>
|
||||
<a className="a_btn cancel_btn fr" type="submit" onClick={()=>this.editdetail(item.content,undefined)}>取消</a>
|
||||
|
|
@ -409,135 +643,195 @@ class MessageCount extends Component{
|
|||
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
<Link to={`/projects/${projectsId}/merge/new`} className="topWrapper_btn">创建合并请求</Link>
|
||||
</div>
|
||||
{ visible && <AmplifyImg url={imageUrl} visible={visible} setVisible={this.setVisible}/> }
|
||||
<div>
|
||||
<div className="detailContent">
|
||||
<p>
|
||||
{
|
||||
data ?
|
||||
<span className="font-20">【{ data.issue.issue_classify==='issue'?data.issue.tracker:"合并"}】</span>
|
||||
:
|
||||
""
|
||||
}
|
||||
<span className="font-20" > { data && data.issue.subject }</span>
|
||||
|
||||
</p>
|
||||
{
|
||||
data &&
|
||||
<p>
|
||||
<span className="font-20">【{ data.issue && (data.issue.issue_classify==='issue' ? data.issue.tracker : "合并")}】</span>
|
||||
<span className="font-20" > { data.issue && data.issue.subject }</span>
|
||||
</p>
|
||||
}
|
||||
<p className="mt10 color-grey-c">
|
||||
<span className={data&&data.issue.issue_status==="关闭"?"closedetail":data&&data.pull_request.status===0?"opendetail":"prdetail"}>{data&&data.issue.issue_status==="关闭"?"关闭中":data&&data.pull_request.status===0?"开启中":"已合并"} </span>
|
||||
<span className="ml10 lineH32">
|
||||
<span className="color-grey-c ml10">
|
||||
由 { data && data.issue.author_name} 于 { data && data.issue.created_at }创建{ data && data.issue.journals_count && data.issue.journals_count > 0 ?` · ${data.issue.journals_count} 条评论`:""}
|
||||
</span>
|
||||
|
||||
<span className="span_title ml10">
|
||||
请求从<strong> {data && data.pull_request.head} </strong>分支合并到<strong> {data && data.pull_request.base} </strong>分支
|
||||
</span>
|
||||
<span className="pull-right lineH32">
|
||||
<Link to={`/projects/${projectsId}/merge/${mergeId}/UpdateMerge`} className="color-blue fr">编辑</Link>
|
||||
{/*{*/}
|
||||
{/*data && data.issue.user_permission ?*/}
|
||||
{/*<Link to={`/projects/${projectsId}/merge/${mergeId}/UpdateMerge`} className="color-blue fr">编辑</Link>*/}
|
||||
{/*: ''*/}
|
||||
{/*}*/}
|
||||
{
|
||||
data && data.issue.user_permission ?
|
||||
<a onClick={this.change_to_edit} className="color-blue fr">编辑</a>
|
||||
: ''
|
||||
}
|
||||
</span>
|
||||
</p>
|
||||
<div className="df mt20">
|
||||
{
|
||||
data && data.attachments.length > 0 ?
|
||||
<Attachments attachments={data.attachments} showNotification={this.props.showNotification}/>
|
||||
:
|
||||
""
|
||||
}
|
||||
</div>
|
||||
<div className="detailHeader-wrapper">
|
||||
{
|
||||
data && data.attachments.length > 0 ?
|
||||
<div className="df mt20">
|
||||
<Attachments attachments={data.attachments} showNotification={this.props.showNotification}/>
|
||||
</div>
|
||||
:
|
||||
""
|
||||
}
|
||||
|
||||
<div className="">
|
||||
<div className="normal f-wrap-between">
|
||||
<ul className="headerMenu-wrapper" style={{paddingTop:42,paddingLeft:15}}>
|
||||
<li className={url.indexOf("Messagecount")>0? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/Messagecount`}>对话内容</Link></li>
|
||||
<li className={url.indexOf("MergeSubmit")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/MergeSubmit`}>代码提交</Link></li>
|
||||
<ul className="headerMenu-wrapper" style={{paddingTop:15,paddingLeft:15}}>
|
||||
<li className={url.indexOf("Messagecount")>0? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/Messagecount`} className="color-grey">对话内容</Link></li>
|
||||
<li className={url.indexOf("MergeSubmit")>0 ? "active" : ""}><Link to={`/projects/${projectsId}/merge/${mergeId}/MergeSubmit`} className="color-grey">代码提交</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="f-wrap-between mt5" style={{alignItems:"flex-start"}}>
|
||||
<div className="item-list-right" >
|
||||
<Spin spinning={isSpin}>
|
||||
<ul className="ul_width">
|
||||
{renderList()}
|
||||
</ul>
|
||||
</Spin>
|
||||
|
||||
{ Paginations }
|
||||
<div className="df" style={{display:this.state.data&&this.state.data.pull_request.status===1?'none':'flex'}}>
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<div className="new_context" >
|
||||
<p>该合并请求可以进行自动合并操作</p>
|
||||
<p style={{marginTop:15,display:this.state.mergekey==='rebase'?this.state.buttonshow==='none'?"block":"none":this.state.ismesrge==='none'?"block":"none"}}>
|
||||
{/* <button className="topmerge_btn" onClick={this.submitmerge} >{this.state.mergename}</button> */}
|
||||
{/* <Dropdown style={{marginBottom:5}} overlay={menu} trigger={['click']} > */}
|
||||
<Dropdown.Button overlay={menu} type="primary" onClick={this.submitmerge} icon={<Icon type="caret-down"/>}>
|
||||
{this.state.mergename}
|
||||
</Dropdown.Button>
|
||||
|
||||
{/* </Dropdown> */}
|
||||
</p>
|
||||
|
||||
<div style={{display:this.state.ismesrge,marginTop:15}}>
|
||||
<Input placeholder="标题" value={this.state.title} onChange={this.changtitlepr}/>
|
||||
<TextArea placeholder="=描述..." style={{height:"300px",marginTop:15}} value={this.state.body} onChange={this.changbodypr} />
|
||||
</div>
|
||||
<p className="clearfix mt15" style={{display:this.state.buttonshow}}>
|
||||
<a className="topWrapper_btn " type="submit" onClick={()=>this.prmerge()}>合并请求</a>
|
||||
<a className="a_btn cancel_btn " type="submit" style={{marginLeft:15}} onClick={this.nonemerge}>取消</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{data && data.issue.user_permission &&
|
||||
<div className="pull-right pt15">
|
||||
<a className="Closeor_btn fr" type="submit"
|
||||
onClick={() => this.closedetail(data && data.issue.issue_status === "关闭" ? 2 : 5)}>{data && data.issue.issue_status === "关闭" ? "点击开启" : "关闭"}</a>
|
||||
</div>
|
||||
<div className="order_line" style={{marginLeft:80}}></div>
|
||||
<div className="df">
|
||||
<Link to={``}><img className="user_img"
|
||||
src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<div className="new_context">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('content', {
|
||||
rules: [{
|
||||
required: true, message: '请输入内容'
|
||||
}],
|
||||
})(
|
||||
<TextArea placeholder="添加评论..." style={{height: "200px"}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<UploadComponent load={this.UploadFunc} isComplete={showFiles}></UploadComponent>
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={this.addjournals}>评论</a>
|
||||
<a className="Closeor_btn fr" type="submit" style={{display:data&&data.pull_request.status===0?'block':'none'}}
|
||||
onClick={() => this.closedetail(data && data.issue.issue_status === "关闭" ? 2 : 5)}>{data && data.issue.issue_status === "关闭" ? "开启" : "关闭"}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="list-left DetailRight mt10">
|
||||
<p>
|
||||
<span className="span_title">标签</span>
|
||||
<span>{
|
||||
data && data.issue.issue_tags ? <span className="issue-tag-show" style={{background: data.issue.issue_tags[0].color}}>{data.issue.issue_tags[0].name}</span> : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">里程碑</span>
|
||||
<span>{
|
||||
data && data.issue.version ? data.issue.version : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">指派给</span>
|
||||
<span>{data && data.issue.assign_user_name ? data.issue.assign_user_name : "--"}</span>
|
||||
</p>
|
||||
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{
|
||||
url.indexOf("Messagecount")>0 ?
|
||||
<Spin spinning={this.state.SpinFlag}>
|
||||
<div className="f-wrap-between mt20" style={{alignItems:"flex-start"}}>
|
||||
<div className="item-list-right" >
|
||||
{
|
||||
data && data.issue.user_permission ?
|
||||
<div style={{display:data&&(data.pull_request.status===1 || data.issue.issue_status==="关闭")?'none':''}}>
|
||||
<div className="df" >
|
||||
<Link to={`/users/${current_user && current_user.login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
</Link>
|
||||
<div className="new_context">
|
||||
{
|
||||
data && data.issue.issue_status !== "关闭" &&
|
||||
<div>
|
||||
<p>该合并请求可以进行自动合并操作</p>
|
||||
<p style={{marginTop:15,display:this.state.mergekey==='rebase'?this.state.buttonshow==='none'?"block":"none":this.state.ismesrge==='none'?"block":"none"}}>
|
||||
|
||||
<Dropdown.Button overlay={menu} type="primary" onClick={this.submitmerge} icon={<Icon type="caret-down"/>}>
|
||||
{this.state.mergename}
|
||||
</Dropdown.Button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
<div style={{display:this.state.ismesrge,marginTop:15}}>
|
||||
<Input placeholder="标题" value={this.state.title} onChange={this.changtitlepr}/>
|
||||
<TextArea placeholder="请输入合并描述..." style={{height:"170px",marginTop:20}} value={this.state.body} onChange={this.changbodypr} />
|
||||
</div>
|
||||
<p className="clearfix mt15" style={{display:this.state.buttonshow}}>
|
||||
<a className="topWrapper_btn " type="submit" onClick={()=>this.prmerge()}>合并请求</a>
|
||||
<a className="a_btn cancel_btn " type="submit" style={{marginLeft:15}} onClick={this.nonemerge}>取消</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="order_line" style={{marginLeft:80}}></div>
|
||||
</div>
|
||||
: ''
|
||||
}
|
||||
|
||||
<Spin spinning={isSpin}>
|
||||
<ul className="ul_width">
|
||||
{renderList()}
|
||||
</ul>
|
||||
</Spin>
|
||||
|
||||
{ Paginations }
|
||||
|
||||
<div className="df">
|
||||
<Link to={`/users/${current_user && current_user.login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
</Link>
|
||||
{/*<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>*/}
|
||||
<div className="new_context">
|
||||
{/* <Form.Item>
|
||||
{getFieldDecorator('content', {
|
||||
rules: [{
|
||||
required: true, message: '请输入内容'
|
||||
}],
|
||||
})(
|
||||
<TextArea placeholder="添加评论..." style={{height: "200px"}}/>
|
||||
)}
|
||||
</Form.Item> */}
|
||||
<div className="quillContent">
|
||||
<QuillForEditor
|
||||
value = {commentsContent}
|
||||
wrapStyle={{
|
||||
height: '240px',
|
||||
opacity:1,
|
||||
}}
|
||||
// autoFocus={true}
|
||||
style={{ height: '170px' }}
|
||||
placeholder="请输入评论内容..."
|
||||
options={options}
|
||||
onContentChange={this.changeComments}
|
||||
/>
|
||||
<p className="quillFlag">
|
||||
{ quillFlag && <span className="">请输入评论内容</span>}
|
||||
</p>
|
||||
</div>
|
||||
<UploadComponent load={this.UploadFunc} isComplete={showFiles}></UploadComponent>
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={this.addjournals}>评论</a>
|
||||
{/*<a className="Closeor_btn fr" type="submit" style={{display:data&&data.pull_request.status===0?'block':'none'}}*/}
|
||||
{/*onClick={() => this.closedetail(data && data.issue.issue_status === "关闭" ? 2 : 5)}>{data && data.issue.issue_status === "关闭" ? "开启" : "关闭"}</a>*/}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
editMerge ?
|
||||
<div className="list-left DetailRight">
|
||||
{ editMergeForm() }
|
||||
</div>
|
||||
|
||||
:
|
||||
<div className="list-left DetailRight">
|
||||
<p>
|
||||
<span className="span_title">标签</span>
|
||||
<span>{
|
||||
data && data.issue.issue_tags ? <span className="issue-tag-show" style={{background: data.issue.issue_tags[0].color}}>{data.issue.issue_tags[0].name}</span> : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p style={{display: "inline-block",'white-space': "nowrap" }}>
|
||||
<span className="span_title">里程碑</span>
|
||||
<span className="title_overflow">{
|
||||
data && data.issue.version ? data.issue.version : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">指派给</span>
|
||||
<span>{data && data.issue.assign_user_name ? data.issue.assign_user_name : "--"}</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</Spin>
|
||||
:
|
||||
<MergeSubmit {...this.props} {...this.state} data={data} />
|
||||
}
|
||||
|
||||
</div>
|
||||
<Modal
|
||||
onCancel={this.handleCancel}
|
||||
visible={this.state.isShow}
|
||||
width="400px"
|
||||
footer={
|
||||
[]
|
||||
}
|
||||
bodyStyle={{textAlign:'center'}}
|
||||
onCancel={this.handleCancel}
|
||||
visible={this.state.isShow}
|
||||
width="400px"
|
||||
footer={[]}
|
||||
bodyStyle={{textAlign:'center'}}
|
||||
>
|
||||
<img className="list_img" src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt=""/>
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
import React , {Component} from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {Radio, Form,Menu,Dropdown,Input,Select,Table} from 'antd';
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import reactCSS from 'reactcss'
|
||||
import axios from 'axios';
|
||||
import moment from 'moment'
|
||||
import UploadComponent from '../Upload/Index';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import '../Order/order.css';
|
||||
import QuillForEditor from '../quillForEditor';
|
||||
|
||||
const { Group, Button } = Radio;
|
||||
|
||||
const { Button } = Radio;
|
||||
const Option = Select.Option;
|
||||
const TextArea = Input.TextArea;
|
||||
|
||||
const options = [
|
||||
['bold', 'italic', 'underline'],
|
||||
[{header: [1,2,3,false]}],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['formula']
|
||||
];
|
||||
class NewMerge extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
|
@ -21,6 +27,7 @@ class NewMerge extends Component{
|
|||
merge:undefined,
|
||||
pull:undefined,
|
||||
//判断 是否显示创建合并请求的页面
|
||||
desc:undefined,
|
||||
iscreatemerge:'none',
|
||||
issue_tag_ids:"",
|
||||
fixed_version_id:"",
|
||||
|
|
@ -147,9 +154,10 @@ class NewMerge extends Component{
|
|||
}else{
|
||||
values.issue_tag_ids = []
|
||||
}
|
||||
|
||||
const { desc } = this.state;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
body:JSON.stringify(desc),
|
||||
project_id:projectsId,
|
||||
head:this.state.merge,
|
||||
base:this.state.pull,
|
||||
|
|
@ -168,9 +176,8 @@ class NewMerge extends Component{
|
|||
|
||||
//获取提交列表
|
||||
getCommitList=(branch , page , limit)=>{
|
||||
const { current_user } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/${current_user&¤t_user.login}/${projectsId}/commits.json`;
|
||||
const url = `/repositories/${projectsId}/commits.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
sha:branch,
|
||||
|
|
@ -183,6 +190,7 @@ class NewMerge extends Component{
|
|||
result.data && result.data.commits.length > 0 && result.data.commits.map((item,key)=>{
|
||||
array.push({
|
||||
name:item.author && item.author.name,
|
||||
login: item.author && item.author.login,
|
||||
image_url:item.author && item.author.image_url,
|
||||
sha:item.sha,
|
||||
time_from_now:item.time_from_now,
|
||||
|
|
@ -202,7 +210,7 @@ class NewMerge extends Component{
|
|||
|
||||
ischeckmerge=(head,base)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/pull_requests/check_can_merge`;
|
||||
const url = `/projects/${projectsId}/pull_requests/check_can_merge.json`;
|
||||
axios.post(url,{
|
||||
project_id:projectsId,
|
||||
head:head,
|
||||
|
|
@ -221,12 +229,18 @@ class NewMerge extends Component{
|
|||
|
||||
}
|
||||
|
||||
onContentChange=(value)=>{
|
||||
this.setState({
|
||||
desc:value
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
render(){
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { current_user } = this.props;
|
||||
const { issue_tag_ids , fixed_version_id ,assigned_to_id ,issue_chosen,data,titledata} = this.state;
|
||||
const { issue_tag_ids , fixed_version_id ,assigned_to_id , data,titledata , desc } = this.state;
|
||||
|
||||
|
||||
const columns=[{
|
||||
|
|
@ -235,8 +249,12 @@ class NewMerge extends Component{
|
|||
width:"10%",
|
||||
render: (text,item) => (
|
||||
<span className="f-wrap-alignCenter">
|
||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>
|
||||
<label className="hide-1" style={{maxWidth:"75px"}}>{text}</label>
|
||||
<Link to={`/users/${item.login}/projects`} className="show-user-link">
|
||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>
|
||||
<label className="hide-1" style={{maxWidth:"75px",'vertical-align':'middle'}}>{text}</label>
|
||||
</Link>
|
||||
{/*<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr3 radius"/>*/}
|
||||
{/*<label className="hide-1" style={{maxWidth:"75px"}}>{text}</label>*/}
|
||||
</span>
|
||||
),
|
||||
},{
|
||||
|
|
@ -294,8 +312,8 @@ class NewMerge extends Component{
|
|||
return(
|
||||
<div className="main">
|
||||
|
||||
<h1 style={{marginLeft:15}}>创建合并请求</h1>
|
||||
<h5 style={{marginLeft:15}}>选择合并的目标分支和源分支</h5>
|
||||
<h1 className="mb10">创建合并请求</h1>
|
||||
<h5 className="mb10">选择合并的目标分支和源分支</h5>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="mergediv">
|
||||
<div>
|
||||
|
|
@ -317,8 +335,11 @@ class NewMerge extends Component{
|
|||
<div style={{display:this.state.iscreatemerge==='none'?'none':'block'}}>
|
||||
<Form>
|
||||
<div className="f-wrap-between mt20" style={{alignItems:"flex-start"}}>
|
||||
<div className="list-right df">
|
||||
<Link to={``}><img class="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<div className="list-right df" style={{padding:"0px",paddingTop:"10px"}}>
|
||||
<Link to={`/users/${current_user && current_user.login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
</Link>
|
||||
|
||||
<div className="new_context">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('title', {
|
||||
|
|
@ -326,16 +347,28 @@ class NewMerge extends Component{
|
|||
required: true, message: '请填写请求标题'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="标题"/>
|
||||
<Input placeholder="标题"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<QuillForEditor
|
||||
value = {desc}
|
||||
wrapStyle={{
|
||||
height: '240px',
|
||||
opacity:1,
|
||||
}}
|
||||
// autoFocus={true}
|
||||
style={{ height: '170px' }}
|
||||
placeholder="请输入合并请求的描述..."
|
||||
options={options}
|
||||
onContentChange={this.onContentChange}
|
||||
/>
|
||||
{/* <Form.Item>
|
||||
{getFieldDecorator('body', {
|
||||
rules: [],
|
||||
})(
|
||||
<TextArea placeholder="合并请求的描述。。。" style={{height:"300px"}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form.Item> */}
|
||||
<UploadComponent load={this.UploadFunc} isComplete={true} ></UploadComponent>
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={this.submit}>创建合并请求</a>
|
||||
|
|
@ -352,7 +385,7 @@ class NewMerge extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select value={issue_tag_ids}>
|
||||
<Option value="">未选择标签</Option>
|
||||
<Option value="">{data && data.issue_tags.length > 0 ? '未选择标签':'请在仓库设置里添加标签'}</Option>
|
||||
{ this.renderSelect(data && data.issue_tags) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
@ -365,7 +398,7 @@ class NewMerge extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select value={fixed_version_id}>
|
||||
<Option value="">未选择里程碑</Option>
|
||||
<Option value="">{data && data.issue_versions.length > 0 ? '未选择里程碑': '请添加里程碑'}</Option>
|
||||
{ this.renderSelect(data && data.issue_versions) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,21 @@ import Nav from '../Order/Nav';
|
|||
|
||||
import UploadComponent from '../Upload/Index';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import{ Modal,Col,Form,Input,Tooltip,Select } from 'antd'
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import{ Modal , Form , Input , Select } from 'antd'
|
||||
import QuillForEditor from '../quillForEditor';
|
||||
|
||||
|
||||
import Attachments from '../Upload/attachment'
|
||||
|
||||
const TextArea = Input.TextArea;
|
||||
const Option = Select.Option;
|
||||
|
||||
|
||||
const options = [
|
||||
['bold', 'italic', 'underline'],
|
||||
[{header: [1,2,3,false]}],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['formula']
|
||||
];
|
||||
class UpdateMerge extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
|
@ -38,7 +44,8 @@ class UpdateMerge extends Component{
|
|||
done_ratio:0,
|
||||
textcount:"",
|
||||
fileList:undefined,
|
||||
get_attachments: undefined
|
||||
get_attachments: undefined,
|
||||
desc:undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,17 +108,31 @@ class UpdateMerge extends Component{
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
onContentChange=(value)=>{
|
||||
this.setState({
|
||||
textcount:JSON.stringify(value)
|
||||
})
|
||||
}
|
||||
changmodelname=(e)=>{
|
||||
this.setState({
|
||||
subject:e.target.value
|
||||
})
|
||||
}
|
||||
changmodelcount=(e)=>{
|
||||
this.setState({
|
||||
textcount:e.target.value
|
||||
})
|
||||
this.setState({
|
||||
subject:e.target.value
|
||||
})
|
||||
}
|
||||
// changmodelcount=(e)=>{
|
||||
// this.setState({
|
||||
// textcount:e.target.value
|
||||
// })
|
||||
// }
|
||||
stringJson=(value) =>{
|
||||
let _value = null;
|
||||
|
||||
try {
|
||||
_value = JSON.parse(value);
|
||||
} catch (e) {
|
||||
_value = value;
|
||||
}
|
||||
return _value
|
||||
}
|
||||
|
||||
renderSelect=(list)=>{
|
||||
if(list && list.length >0){
|
||||
|
|
@ -134,8 +155,8 @@ class UpdateMerge extends Component{
|
|||
const { fileList } = this.state;
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId,mergeId} = this.props.match.params;
|
||||
const { subject ,data} = this.state;
|
||||
const { projectsId , mergeId } = this.props.match.params;
|
||||
const { subject ,data , textcount } = this.state;
|
||||
const url = `/projects/${projectsId}/pull_requests/${mergeId}.json`;
|
||||
|
||||
|
||||
|
|
@ -149,9 +170,10 @@ class UpdateMerge extends Component{
|
|||
values.assigned_to_id = ""
|
||||
}
|
||||
axios.put(url,{
|
||||
project_id:projectsId,
|
||||
id: data.issue.id,
|
||||
attachment_ids:fileList,
|
||||
project_id:projectsId,
|
||||
id: data.issue.id,
|
||||
attachment_ids:fileList,
|
||||
body:textcount,
|
||||
...values
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
|
|
@ -167,40 +189,53 @@ class UpdateMerge extends Component{
|
|||
|
||||
|
||||
render(){
|
||||
const { projectsId,mergeId } = this.props.match.params;
|
||||
const { projectsId , mergeId } = this.props.match.params;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { current_user } = this.props;
|
||||
const { issue_tag_ids , fixed_version_id , branch_name , status_id , tracker_id , issue_type ,assigned_to_id , priority_id , done_ratio,
|
||||
issue_chosen , branches, subject, textcount,get_attachments } = this.state;
|
||||
const { issue_tag_ids , fixed_version_id , assigned_to_id , issue_chosen , subject, textcount,get_attachments } = this.state;
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
</div>
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state}/>*/}
|
||||
{/*</div>*/}
|
||||
<div>
|
||||
<Form>
|
||||
<div className="f-wrap-between mt20" style={{alignItems:"flex-start"}}>
|
||||
<div className="list-right df" >
|
||||
<Link to={``}><img class="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<Link to={`/users/${current_user && current_user.login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
</Link>
|
||||
<div className="new_context">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('title', {
|
||||
rules: [{
|
||||
required: true, message: '请填写工单标题'
|
||||
required: true, message: '请填写任务标题'
|
||||
}],
|
||||
initialValue: subject
|
||||
})(
|
||||
<Input placeholder="标题" onChange={this.changmodelname}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{/* <Form.Item>
|
||||
{getFieldDecorator('body', {
|
||||
rules: [],
|
||||
initialValue: textcount
|
||||
})(
|
||||
<TextArea placeholder="请输入工单的描述..." style={{height:"300px"}} onChange={this.changmodelcount}/>
|
||||
<TextArea placeholder="请输入任务的描述..." style={{height:"300px"}} onChange={this.changmodelcount}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form.Item> */}
|
||||
<QuillForEditor
|
||||
value = {this.stringJson(textcount)}
|
||||
wrapStyle={{
|
||||
height: '240px',
|
||||
opacity:1,
|
||||
}}
|
||||
// autoFocus={true}
|
||||
style={{ height: '170px' }}
|
||||
placeholder="请输入合并请求的描述..."
|
||||
options={options}
|
||||
onContentChange={this.onContentChange}
|
||||
/>
|
||||
<UploadComponent load={this.UploadFunc} showNotification={this.props.showNotification} isComplete={true} ></UploadComponent>
|
||||
{
|
||||
get_attachments ?
|
||||
|
|
@ -225,7 +260,7 @@ class UpdateMerge extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>未选择标签</Option>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_tag.length > 0 ? '未选择标签':'请在仓库设置里添加标签'}</Option>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.issue_tag) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
@ -238,7 +273,7 @@ class UpdateMerge extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>未选择里程碑</Option>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_version.length > 0 ? '未选择里程碑': '请添加里程碑'}</Option>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.issue_version) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@
|
|||
border-radius:4px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.new_context{
|
||||
flex:1;
|
||||
}
|
||||
.topmerge_btn{
|
||||
background: #21ba45;
|
||||
color: #FFFFFF!important;
|
||||
|
|
@ -31,4 +34,7 @@
|
|||
/*width: 110px;*/
|
||||
border-radius: 4px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
form .ant-cascader-picker, form .ant-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import {Link} from 'react-router-dom';
|
|||
import { Input ,Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
|
||||
import './merge.css';
|
||||
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import NoneData from '../Nodata';
|
||||
import Nav from '../Order/Nav';
|
||||
import OrderItem from './MergeItem';
|
||||
|
||||
|
|
@ -166,8 +166,8 @@ class merge extends Component{
|
|||
if(type===1){
|
||||
this.setState({
|
||||
status_type:'1',
|
||||
openselect:current_user.user_id,
|
||||
closeselect:undefined,
|
||||
openselect:'123',
|
||||
issue_tag_ids:'标签',
|
||||
fixed_version_ids:'里程碑',
|
||||
assigned_to_ids:'指派人',
|
||||
|
|
@ -179,7 +179,8 @@ class merge extends Component{
|
|||
this.setState({
|
||||
status_type:'2',
|
||||
openselect:undefined,
|
||||
closeselect:current_user.user_id,
|
||||
closeselect:'123',
|
||||
|
||||
issue_tag_ids:'标签',
|
||||
fixed_version_ids:'里程碑',
|
||||
assigned_to_ids:'指派人',
|
||||
|
|
@ -214,6 +215,7 @@ class merge extends Component{
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.setState({
|
||||
order_name:e.key,
|
||||
|
|
@ -222,6 +224,15 @@ class merge extends Component{
|
|||
this.getIssueList(1,limit,search,author_id,assigned_to_id,status_type,undefined,undefined, e.item.props.value,e.key);
|
||||
}
|
||||
|
||||
islogin(){
|
||||
const { projectsId } = this.props.match.params;
|
||||
if (this.props.checkIfLogin() === false) {
|
||||
this.props.showLoginDialog()
|
||||
return
|
||||
}else{
|
||||
this.props.history.push(`/projects/${projectsId}/merge/new`);
|
||||
}
|
||||
}
|
||||
render(){
|
||||
|
||||
const { issue_chosen , issues , limit , page , search_count , data , isSpin,openselect,closeselect } = this.state;
|
||||
|
|
@ -248,64 +259,77 @@ class merge extends Component{
|
|||
)
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
<Link to={`/projects/${projectsId}/merge/new`} className="topWrapper_btn">创建合并请求</Link>
|
||||
</div>
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state}/>*/}
|
||||
{/*{*/}
|
||||
{/*<a className="topWrapper_btn" onClick={()=>this.islogin()}>创建合并请求</a> */}
|
||||
{/*}*/}
|
||||
{/*</div>*/}
|
||||
<div className="topWrapper" style={{borderBottom:"none"}}>
|
||||
<p className="topWrapper_type">
|
||||
<li className={openselect ? "active":""} onClick={()=>this.openorder(1)}>{data && data.open_count}个开启中</li>
|
||||
<li className={closeselect ? "active":""} onClick={()=>this.openorder(2)}>{data && data.close_count}个已关闭</li>
|
||||
<li className={openselect ? "active":""} onClick={()=>this.openorder(1)}>{data && data.open_count ? data.open_count : 0}个开启中</li>
|
||||
<li className={closeselect ? "active":""} onClick={()=>this.openorder(2)}>{data && data.close_count ? data.close_count : 0}个已关闭</li>
|
||||
{/* <span onClick={this.openorder} className={author_id ? "active":""}>{data && data.open_count}个开启中</span>
|
||||
<span onClick={this.closeorder} className={author_id ? "active":""}>{data && data.close_count}个已关闭</span> */}
|
||||
</p>
|
||||
<div>
|
||||
<Search
|
||||
placeholder="搜索"
|
||||
enterButton
|
||||
onSearch={this.searchFunc}
|
||||
style={{ width: 300 }}
|
||||
/>
|
||||
|
||||
<div className="topWrapper_select">
|
||||
<div>
|
||||
<Search
|
||||
placeholder="搜索"
|
||||
enterButton
|
||||
onSearch={this.searchFunc}
|
||||
style={{ width: 300 }}
|
||||
/>
|
||||
</div>
|
||||
<a className="topWrapper_btn ml10" onClick={()=>this.islogin()}>创建合并请求</a>
|
||||
</div>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="f-wrap-between mb20">
|
||||
<ul >
|
||||
<li> </li>
|
||||
</ul>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_tag,'标签','issue_tag_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.issue_tag_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_version,'里程碑','fixed_version_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.fixed_version_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user,'指派人','assigned_to_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.assigned_to_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.paix}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData></NoneData>
|
||||
{
|
||||
data && data.search_count && data.search_count > 0 ?
|
||||
<div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="f-wrap-between mb20">
|
||||
<ul >
|
||||
<li> </li>
|
||||
</ul>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_tag,'标签','issue_tag_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.issue_tag_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.issue_version,'里程碑','fixed_version_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.fixed_version_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={this.renderMenu(issue_chosen && issue_chosen.assign_user,'指派人','assigned_to_id')} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.assigned_to_ids}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>{this.state.paix}<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData _html="暂时还没有相关数据哦!"></NoneData>
|
||||
:
|
||||
<OrderItem issues={issues} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state}></OrderItem>
|
||||
}
|
||||
{ Paginations }
|
||||
</Spin>
|
||||
</div>
|
||||
:
|
||||
<OrderItem issues={issues} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state}></OrderItem>
|
||||
}
|
||||
{ Paginations }
|
||||
</Spin>
|
||||
|
||||
<NoneData _html="暂时还没有相关数据哦!"/>
|
||||
}
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Input , Form , Select , Checkbox , Button , Divider ,Spin } from 'antd';
|
||||
import { Input , Form , Select , Checkbox , Button , Divider , Spin , AutoComplete } from 'antd';
|
||||
|
||||
import '../css/index.css';
|
||||
import './new.css'
|
||||
|
||||
import axios from 'axios' ;
|
||||
import { callbackify } from 'util';
|
||||
const Option = Select.Option
|
||||
class Index extends Component{
|
||||
constructor(props){
|
||||
|
|
@ -22,10 +23,39 @@ class Index extends Component{
|
|||
LanguageList:undefined,
|
||||
GitignoreList:undefined,
|
||||
LicensesList:undefined,
|
||||
isSpin:false
|
||||
isSpin:false,
|
||||
|
||||
project_language_id:undefined,
|
||||
project_category_id:undefined,
|
||||
license_id:undefined,
|
||||
ignore_id:undefined,
|
||||
|
||||
project_language_list:undefined,
|
||||
project_category_list:undefined,
|
||||
license_list:undefined,
|
||||
ignore_list:undefined,
|
||||
|
||||
project_language_name:undefined,
|
||||
project_category_name:undefined,
|
||||
license_name:undefined,
|
||||
ignore_name:undefined
|
||||
}
|
||||
}
|
||||
getUserInfo=()=>{
|
||||
const url = `/users/me.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result && result.data.login){
|
||||
this.setState({
|
||||
current_user:result.data
|
||||
})
|
||||
this.getDetail();
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
componentDidMount=()=>{
|
||||
// this.getUserInfo();
|
||||
// 获取项目类别
|
||||
this.getCategory();
|
||||
// 获取项目语言
|
||||
|
|
@ -39,9 +69,9 @@ class Index extends Component{
|
|||
const url = `/project_categories.json`
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
let CategoryList = this.setOptionsList(result.data.project_categories)
|
||||
this.setOptionsList(result.data.project_categories,'project_category');
|
||||
this.setState({
|
||||
CategoryList
|
||||
CategoryList:result.data.project_categories
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{})
|
||||
|
|
@ -51,9 +81,9 @@ class Index extends Component{
|
|||
const url = `/project_languages.json`
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
let LanguageList = this.setOptionsList(result.data.project_languages)
|
||||
this.setOptionsList(result.data.project_languages,'project_language')
|
||||
this.setState({
|
||||
LanguageList
|
||||
LanguageList:result.data.project_languages
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{})
|
||||
|
|
@ -63,9 +93,9 @@ class Index extends Component{
|
|||
const url = `/ignores.json`
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
let GitignoreList = this.setOptionsList(result.data.ignores)
|
||||
this.setOptionsList(result.data.ignores,'ignore');
|
||||
this.setState({
|
||||
GitignoreList
|
||||
GitignoreList:result.data.ignores
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{})
|
||||
|
|
@ -75,24 +105,30 @@ class Index extends Component{
|
|||
const url = `/licenses.json`
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
let LicensesList = this.setOptionsList(result.data.licenses)
|
||||
this.setOptionsList(result.data.licenses,'license');
|
||||
this.setState({
|
||||
LicensesList
|
||||
LicensesList:result.data.licenses
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{})
|
||||
}
|
||||
|
||||
setOptionsList = (data) =>{
|
||||
let list = undefined;
|
||||
// 设置option
|
||||
setOptionsList = (data,_head,name) =>{
|
||||
if(data && data.length > 0){
|
||||
list = data.map((item,key)=>{
|
||||
return(
|
||||
<Option key={item.id}>{item.name}</Option>
|
||||
)
|
||||
let _data = data;
|
||||
if(name){
|
||||
_data = data.filter(item=>item.name.toLowerCase().indexOf(name.toLowerCase())>-1);
|
||||
}
|
||||
let list = _data && _data.map((item) => (
|
||||
<Option key={item.id} value={item.name}>
|
||||
{item.name}
|
||||
</Option>
|
||||
));
|
||||
this.setState({
|
||||
[_head+"_list"]:list
|
||||
})
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
subMitFrom = () =>{
|
||||
|
|
@ -103,9 +139,14 @@ class Index extends Component{
|
|||
if(!err){
|
||||
const { current_user } = this.props;
|
||||
const { projectsType } =this.props.match.params;
|
||||
const { project_language_id, project_category_id, license_id, ignore_id } = this.state;
|
||||
const url = projectsType === "deposit" ? "/projects.json" :"/projects/migrate.json";
|
||||
axios.post(url,{
|
||||
...values,
|
||||
project_language_id,
|
||||
project_category_id,
|
||||
license_id,
|
||||
ignore_id,
|
||||
user_id:current_user.user_id
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
|
|
@ -114,7 +155,7 @@ class Index extends Component{
|
|||
isSpin:false
|
||||
})
|
||||
this.props.showNotification(`${projectsType === "deposit" ? "托管" :"镜像"}项目创建成功!`);
|
||||
this.props.history.push(`/projects/${result.data.identifier}/coder`);
|
||||
this.props.history.push(`/projects/${result.data.id}/coders`);
|
||||
}
|
||||
}
|
||||
}).catch((error)=>{
|
||||
|
|
@ -131,9 +172,41 @@ class Index extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
ChangePlatform=(value,e,name,list)=>{
|
||||
this.setOptionsList(list,name,value)
|
||||
this.setState({
|
||||
[name+"_id"]:e.key,
|
||||
[name+"_name"]:value,
|
||||
})
|
||||
}
|
||||
|
||||
blurCategory=(value,list,name)=>{
|
||||
// console.log(value);
|
||||
let filter = list && list.filter(item=>item.name === value);
|
||||
if(!filter || filter.length===0){
|
||||
this.props.form.setFieldsValue({
|
||||
[name]:undefined
|
||||
})
|
||||
this.setState({
|
||||
[name+"_name"]:undefined,
|
||||
[name+"_id"]:undefined
|
||||
})
|
||||
this.setOptionsList(list,name);
|
||||
}
|
||||
}
|
||||
|
||||
checkId=(rule, value, callback,list,title)=>{
|
||||
let filter = list.filter(item=>item.name === value);
|
||||
if(filter && filter.length>0){
|
||||
callback();
|
||||
}else{
|
||||
callback('请在下拉选项中选择正确的'+title+"!");
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
render(){
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
console.log(this.props);
|
||||
// 项目类型:deposit-托管项目,mirror-镜像项目
|
||||
const { projectsType } =this.props.match.params;
|
||||
const {
|
||||
|
|
@ -148,8 +221,18 @@ class Index extends Component{
|
|||
LanguageList,
|
||||
GitignoreList,
|
||||
LicensesList,
|
||||
isSpin
|
||||
isSpin,
|
||||
project_language_name,
|
||||
project_category_name,
|
||||
license_name,
|
||||
ignore_name,
|
||||
|
||||
project_language_list,
|
||||
project_category_list,
|
||||
license_list,
|
||||
ignore_list,
|
||||
}=this.state;
|
||||
console.log("a:",project_category_list);
|
||||
return(
|
||||
<div className="main back-white">
|
||||
<div className="newPanel">
|
||||
|
|
@ -157,21 +240,8 @@ class Index extends Component{
|
|||
<Spin spinning={isSpin}>
|
||||
<Form>
|
||||
<div className="newPanel_content">
|
||||
{/* <Form.Item
|
||||
label="拥有者"
|
||||
>
|
||||
{getFieldDecorator('user_id', {
|
||||
rules: [{
|
||||
required: true, message: '请选择拥有者'
|
||||
}],
|
||||
})(
|
||||
<Select value={authorValue}>
|
||||
<Option key="0">kosasa</Option>
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item> */}
|
||||
{
|
||||
projectsType != "deposit" &&
|
||||
projectsType !== "deposit" &&
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
label="镜像版本库地址"
|
||||
|
|
@ -208,60 +278,62 @@ class Index extends Component{
|
|||
required: true, message: '请填写项目简介'
|
||||
}],
|
||||
})(
|
||||
<Input.TextArea autoSize={{ minRows: 2, maxRows: 6 }}/>
|
||||
<Input.TextArea placeholder="项目的介绍" autoSize={{ minRows: 2, maxRows: 6 }}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="仓库名称"
|
||||
style={{marginBottom:"0px"}}
|
||||
>
|
||||
{getFieldDecorator('repository_name', {
|
||||
rules: [{
|
||||
required: true, message: '请填写仓库名称'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="请输入仓库名称"/>
|
||||
<Input placeholder="仓库名称请使用与项目相关的英文关键字"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<p className="formTip">好的存储库名称使用简单、深刻和独特的关键字</p>
|
||||
{/*<p className="formTip">好的存储库名称使用简单、深刻和独特的关键字</p>*/}
|
||||
{/* <div className="newContent_inline"> */}
|
||||
<Form.Item
|
||||
label="项目类别"
|
||||
>
|
||||
{getFieldDecorator('project_category_id', {
|
||||
{getFieldDecorator('project_category', {
|
||||
rules: [{
|
||||
required: true, message: '请选择大类别'
|
||||
required: true, message: '请选择大类别',
|
||||
},{
|
||||
validator:(rule, value, callback)=>this.checkId(rule, value, callback,CategoryList,'项目类别')
|
||||
}],
|
||||
})(
|
||||
<Select value={preType}>
|
||||
{CategoryList}
|
||||
</Select>
|
||||
<AutoComplete
|
||||
placeholder="请选择项目类别"
|
||||
onChange={(value,e)=>this.ChangePlatform(value,e,'project_category',CategoryList)}
|
||||
className="plateAutoComplete"
|
||||
onBlur={(value)=>this.blurCategory(value,CategoryList,"project_category")}
|
||||
>
|
||||
{/* {this.setOptionsList(CategoryList,project_category_name)} */}
|
||||
{project_category_list}
|
||||
</AutoComplete>
|
||||
)}
|
||||
</Form.Item>
|
||||
{/* <Form.Item>
|
||||
{getFieldDecorator('project_language_id', {
|
||||
rules: [{
|
||||
required: true, message: '请选择子类别'
|
||||
}],
|
||||
})(
|
||||
<Select value={subType} className="inline_Tag">
|
||||
<Option key="0">HTMl</Option>
|
||||
<Option key="1">HTMl111</Option>
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item> */}
|
||||
{/* </div> */}
|
||||
<Form.Item
|
||||
label="项目语言"
|
||||
>
|
||||
{getFieldDecorator('project_language_id', {
|
||||
{getFieldDecorator('project_language', {
|
||||
rules: [{
|
||||
required: true, message: '请选择项目语言'
|
||||
},{
|
||||
validator:(rule, value, callback)=>this.checkId(rule, value, callback,LanguageList,'项目语言')
|
||||
}],
|
||||
})(
|
||||
<Select value={languageValue}>
|
||||
{LanguageList}
|
||||
</Select>
|
||||
<AutoComplete
|
||||
placeholder="请选择项目语言"
|
||||
onChange={(value,e)=>this.ChangePlatform(value,e,'project_language',LanguageList)}
|
||||
className="plateAutoComplete"
|
||||
onBlur={(value)=>this.blurCategory(value,LanguageList,"project_language")}
|
||||
>
|
||||
{/* {this.setOptionsList(LanguageList,project_language_name)} */}
|
||||
{project_language_list}
|
||||
</AutoComplete>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
|
@ -273,19 +345,43 @@ class Index extends Component{
|
|||
<Form.Item
|
||||
label=".gitignore"
|
||||
>
|
||||
{getFieldDecorator('ignore_id')(
|
||||
<Select value={gitignoreType} className="inline_Tag">
|
||||
{GitignoreList}
|
||||
</Select>
|
||||
{getFieldDecorator('ignore',{
|
||||
rules: [{
|
||||
required: true, message: '请选择gitignore'
|
||||
},{
|
||||
validator:(rule, value, callback)=>this.checkId(rule, value, callback,GitignoreList,'gitignore')
|
||||
}],
|
||||
})(
|
||||
<AutoComplete
|
||||
placeholder="请选择gitignore,用来定义哪些文件不需要添加到版本管理中"
|
||||
onChange={(value,e)=>this.ChangePlatform(value,e,'ignore',GitignoreList)}
|
||||
className="plateAutoComplete"
|
||||
onBlur={(value)=>this.blurCategory(value,GitignoreList,"ignore")}
|
||||
>
|
||||
{/* {this.setOptionsList(GitignoreList,ignore_name)} */}
|
||||
{ignore_list}
|
||||
</AutoComplete>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="开源许可证"
|
||||
>
|
||||
{getFieldDecorator('license_id')(
|
||||
<Select value={LicensesType} className="inline_Tag">
|
||||
{LicensesList}
|
||||
</Select>
|
||||
{getFieldDecorator('license',{
|
||||
rules: [{
|
||||
required: true, message: '请选择开源许可证'
|
||||
},{
|
||||
validator:(rule, value, callback)=>this.checkId(rule, value, callback,LicensesList,'开源许可证')
|
||||
}],
|
||||
})(
|
||||
<AutoComplete
|
||||
placeholder="请选择开源许可证"
|
||||
onChange={(value,e)=>this.ChangePlatform(value,e,'license',LicensesList)}
|
||||
className="plateAutoComplete"
|
||||
onBlur={(value)=>this.blurCategory(value,LicensesList,"license")}
|
||||
>
|
||||
{/* {this.setOptionsList(LicensesList,license_name)} */}
|
||||
{license_list}
|
||||
</AutoComplete>
|
||||
)}
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
|
|
@ -295,10 +391,19 @@ class Index extends Component{
|
|||
style={{marginBottom:"0px"}}
|
||||
>
|
||||
{getFieldDecorator('private')(
|
||||
<Checkbox value="limit">将项目设为私有</Checkbox>
|
||||
<Checkbox value="limit">将项目设为私有<span className="ml15 font-13 color-grey-9">(只有项目所有人或拥有权限的项目成员才能看到)</span></Checkbox>
|
||||
)}
|
||||
</Form.Item >
|
||||
<p className="formTip">只有企业所有人或拥有权限的企业成员才能看到</p>
|
||||
<div className="ant-row ant-form-item">
|
||||
<div className="ant-col ant-form-item-label">
|
||||
注:
|
||||
</div>
|
||||
<div className="ant-col ant-form-item-control-wrapper color-grey-9">
|
||||
<div className="ant-form-item-control">
|
||||
<span className="ant-form-item-required"></span> 为必填项,否则为选填
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Form.Item className="formTip">
|
||||
<Button type="primary" onClick={this.subMitFrom} className="mr20">创建项目</Button>
|
||||
<Link to={'/projects'} className="btn_32">取消</Link>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class Index extends Component{
|
|||
}
|
||||
// 取消,弹框询问
|
||||
CancelAddFile=()=>{
|
||||
|
||||
this.props.history.goBack();
|
||||
}
|
||||
|
||||
changeEditor=(editorValue)=>{
|
||||
|
|
|
|||
|
|
@ -22,22 +22,23 @@ class UserSubmitComponent extends Component{
|
|||
|
||||
// 提交变更
|
||||
subMitFrom=()=>{
|
||||
const { current_user , filepath , content } = this.props;
|
||||
const { filepath , content } = this.props;
|
||||
const { branch , projectsId } = this.props.match.params;
|
||||
const { submitType } = this.state;
|
||||
let path = filepath.substr(1);
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const url = `/${current_user && current_user.login}/${projectsId}/contents.json`;
|
||||
const url = `/repositories/${projectsId}/create_file.json`;
|
||||
axios.post(url,{
|
||||
filepath:path,
|
||||
branch:submitType==="0" ? branch : undefined,
|
||||
branch:branch,
|
||||
new_branch:submitType==="1" ? values.branchname:undefined,
|
||||
content,
|
||||
message:values.desc
|
||||
}).then((result)=>{
|
||||
if(result && result.data.name){
|
||||
this.props.history.push(`/projects/${projectsId}/coder`);
|
||||
const url = values.branchname ? `/projects/${projectsId}/coders?branch=${values.branchname}` : `/projects/${projectsId}/coders`;
|
||||
this.props.history.push(url);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
|
|
@ -56,15 +57,27 @@ class UserSubmitComponent extends Component{
|
|||
const changeSubmitBranch = ()=>{
|
||||
if(submitType==="1"){
|
||||
return(
|
||||
<Form.Item style={{paddingLeft:"24px"}}>
|
||||
{getFieldDecorator('branchname', {
|
||||
rules: [{
|
||||
required: true, message: '请输入分支名称'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder={`请输入分支名称`}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<div className="mt24">
|
||||
<Form.Item style={{paddingLeft:"24px"}}>
|
||||
{getFieldDecorator('desc', {
|
||||
rules: [{
|
||||
required:true,message:'请输入合并请求的描述内容'
|
||||
}],
|
||||
})(
|
||||
<TextArea placeholder={`请输入合并请求的描述,(必填)`} authSize={{minRows:3,maxRows:5}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item style={{paddingLeft:"24px"}}>
|
||||
{getFieldDecorator('branchname', {
|
||||
rules: [{
|
||||
required: true, message: '请输入分支名称'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder={`请输入分支名称`}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -80,13 +93,7 @@ class UserSubmitComponent extends Component{
|
|||
<Input placeholder={`/${projectDetail && projectDetail.identifier}${filepath}`} readOnly/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('desc', {
|
||||
rules: [],
|
||||
})(
|
||||
<TextArea placeholder={`添加一个可扩展的描述`} authSize={{minRows:3,maxRows:5}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Radio.Group value={submitType} onChange={this.changeSubmittype}>
|
||||
<Radio value="0"><i className="iconfont icon-banbenku font-16 mr5"></i>直接提交至<span>{branch}</span>分支</Radio>
|
||||
<Radio value="1"><Icon type="pull-request" className="mr5" />为此提交创建一个<span className="font-bd">新的分支</span>并发起合并请求</Radio>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import React , { Component } from 'react';
|
||||
|
||||
import nodata from './Images/nodata.png';
|
||||
|
||||
class Nodata extends Component{
|
||||
render(){
|
||||
const { _html } = this.props;
|
||||
return(
|
||||
<div className="none_panels">
|
||||
<div>
|
||||
<img src={nodata} alt="" />
|
||||
<div className="none_p_title">{_html}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Nodata;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import React , { useEffect, useState } from 'react';
|
||||
import { Modal } from 'antd';
|
||||
|
||||
import './order.css';
|
||||
function AmplifyImg (props){
|
||||
|
||||
return(
|
||||
<Modal
|
||||
title={null}
|
||||
footer={null}
|
||||
visible={props.visible}
|
||||
onCancel={()=>props.setVisible(false)}
|
||||
closable={true}
|
||||
centered={true}
|
||||
width={'96%'}
|
||||
className={'AmplifyImg'}
|
||||
>
|
||||
<div className={"amplifyContent"}>
|
||||
<img src={props.url} alt=""/>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
export default AmplifyImg;
|
||||
|
|
@ -5,14 +5,21 @@ import axios from 'axios';
|
|||
import Nav from './Nav';
|
||||
import UploadComponent from '../Upload/Index';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import{ Modal,Col,Form,Input,Tooltip,Select } from 'antd'
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import{ Modal ,Form , Input , Select } from 'antd';
|
||||
import QuillForEditor from '../quillForEditor';
|
||||
import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html'
|
||||
import Attachments from '../Upload/attachment'
|
||||
|
||||
const TextArea = Input.TextArea;
|
||||
const Option = Select.Option;
|
||||
|
||||
|
||||
const options = [
|
||||
['bold', 'italic', 'underline'],
|
||||
[{header: [1,2,3,false]}],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['formula']
|
||||
];
|
||||
class CopyDetail extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
|
@ -36,7 +43,7 @@ class CopyDetail extends Component{
|
|||
done_ratio:0,
|
||||
textcount:"",
|
||||
fileList:undefined,
|
||||
get_attachments: undefined
|
||||
get_attachments: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,10 +106,20 @@ class CopyDetail extends Component{
|
|||
isShow:true
|
||||
});
|
||||
};
|
||||
stringJson=(value) =>{
|
||||
let _value = null;
|
||||
|
||||
//删除工单
|
||||
try {
|
||||
_value = JSON.parse(value);
|
||||
} catch (e) {
|
||||
_value = value;
|
||||
}
|
||||
return _value
|
||||
}
|
||||
|
||||
//删除任务
|
||||
deleteorder=(id)=>{
|
||||
const { projectsId , orderId} = this.props.match.params;
|
||||
const { projectsId , orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}.json`;
|
||||
axios.delete(url,{ data: {
|
||||
project_id: projectsId,
|
||||
|
|
@ -117,6 +134,12 @@ class CopyDetail extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
onContentChange=(value)=>{
|
||||
this.setState({
|
||||
textcount:value
|
||||
})
|
||||
}
|
||||
|
||||
changmodelname=(e)=>{
|
||||
this.setState({
|
||||
subject:e.target.value
|
||||
|
|
@ -144,7 +167,7 @@ class CopyDetail extends Component{
|
|||
const { fileList } = this.state;
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId,orderId} = this.props.match.params;
|
||||
const { projectsId , orderId } = this.props.match.params;
|
||||
const { subject } = this.state;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}.json`;
|
||||
if(values.issue_tag_ids===0){
|
||||
|
|
@ -155,12 +178,19 @@ class CopyDetail extends Component{
|
|||
if(values.assigned_to_id===0){
|
||||
values.assigned_to_id = ""
|
||||
}
|
||||
const { textcount } = this.state;
|
||||
let _html = '';
|
||||
try {
|
||||
_html = new QuillDeltaToHtmlConverter(textcount.ops, {}).convert();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
axios.put(url,{
|
||||
project_id:projectsId,
|
||||
subject:subject,
|
||||
id: orderId,
|
||||
description:this.state.textcount,
|
||||
description:_html,
|
||||
attachment_ids:fileList,
|
||||
...values
|
||||
}).then(result=>{
|
||||
|
|
@ -177,7 +207,7 @@ class CopyDetail extends Component{
|
|||
|
||||
|
||||
render(){
|
||||
const { projectsId,orderId } = this.props.match.params;
|
||||
const { projectsId , orderId } = this.props.match.params;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { current_user } = this.props;
|
||||
const { issue_tag_ids , fixed_version_id , branch_name , status_id , tracker_id , issue_type ,assigned_to_id , priority_id , done_ratio,
|
||||
|
|
@ -197,21 +227,35 @@ class CopyDetail extends Component{
|
|||
<Form.Item>
|
||||
{getFieldDecorator('subject', {
|
||||
rules: [{
|
||||
required: true, message: '请填写工单标题'
|
||||
required: true, message: '请填写任务标题'
|
||||
}],
|
||||
initialValue: subject
|
||||
})(
|
||||
<Input placeholder="标题" onChange={this.changmodelname}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<div className="quillContent" style={{marginBottom:"20px"}}>
|
||||
<QuillForEditor
|
||||
value = {this.stringJson(textcount)}
|
||||
wrapStyle={{
|
||||
height: '220px',
|
||||
opacity:1,
|
||||
}}
|
||||
// autoFocus={true}
|
||||
style={{ height: '170px' }}
|
||||
placeholder="请输入任务的描述..."
|
||||
options={options}
|
||||
onContentChange={this.onContentChange}
|
||||
/>
|
||||
</div>
|
||||
{/* <Form.Item>
|
||||
{getFieldDecorator('description', {
|
||||
rules: [],
|
||||
initialValue: textcount
|
||||
})(
|
||||
<TextArea placeholder="请输入工单的描述..." style={{height: "300px"}} onChange={this.changmodelcount}/>
|
||||
<TextArea placeholder="请输入任务的描述..." style={{height: "300px"}} onChange={this.changmodelcount}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form.Item> */}
|
||||
<UploadComponent load={this.UploadFunc}
|
||||
showNotification={this.props.showNotification} isComplete={true} ></UploadComponent>
|
||||
{
|
||||
|
|
@ -258,7 +302,7 @@ class CopyDetail extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>未选择标签</Option>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_tag.length > 0 ? '未选择标签':'请在仓库设置里添加标签'}</Option>
|
||||
{this.renderSelect(issue_chosen && issue_chosen.issue_tag)}
|
||||
</Select>
|
||||
)}
|
||||
|
|
@ -271,7 +315,7 @@ class CopyDetail extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>未选择里程碑</Option>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_version.length > 0 ? '未选择里程碑': '请添加里程碑'}</Option>
|
||||
{this.renderSelect(issue_chosen && issue_chosen.issue_version)}
|
||||
</Select>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,20 @@ import React , {Component} from 'react';
|
|||
import {Link} from 'react-router-dom';
|
||||
|
||||
import axios from 'axios';
|
||||
import Nav from './Nav';
|
||||
import UploadComponent from '../Upload/Index';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import {Modal, Col, Form, Input, Tooltip, Popconfirm, Pagination , Spin} from 'antd'
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import Attachments from '../Upload/attachment'
|
||||
|
||||
|
||||
const TextArea = Input.TextArea;
|
||||
import {Modal , Form , Tooltip, Popconfirm, Pagination , Spin} from 'antd'
|
||||
import Attachments from '../Upload/attachment';
|
||||
import QuillForEditor from '../quillForEditor';
|
||||
import AmplifyImg from './AmplifyImg';
|
||||
|
||||
const options = [
|
||||
['bold', 'italic', 'underline'],
|
||||
[{header: [1,2,3,false]}],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['formula']
|
||||
];
|
||||
|
||||
class Detail extends Component{
|
||||
constructor(props){
|
||||
|
|
@ -32,7 +36,12 @@ class Detail extends Component{
|
|||
page:1,
|
||||
search_count:undefined,
|
||||
isSpin:false,
|
||||
showFiles: true
|
||||
showFiles: true,
|
||||
quillValue:'',
|
||||
quillFlag:false,
|
||||
// 点击放大的图片路径
|
||||
imageUrl:undefined,
|
||||
visible:false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,25 +83,35 @@ class Detail extends Component{
|
|||
|
||||
//添加评论
|
||||
addjournals=()=>{
|
||||
const { quillValue } = this.state;
|
||||
if(!quillValue){
|
||||
this.setState({
|
||||
quillFlag:true
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { data, page, limit, fileList } = this.state;
|
||||
const url = `/issues/${data.id}/journals.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
content:JSON.stringify(quillValue),
|
||||
issue_id:data.id,
|
||||
attachment_ids:fileList
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification("评论成功!");
|
||||
this.props.form.setFieldsValue({
|
||||
content: ""
|
||||
});
|
||||
this.setState({
|
||||
showFiles: false
|
||||
showFiles: false,
|
||||
quillValue:'',
|
||||
quillFlag:false
|
||||
})
|
||||
this.getjournalslist(page, limit);
|
||||
this.props.showNotification("评论成功!");
|
||||
// this.UploadFunc(undefined)
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
|
|
@ -123,9 +142,9 @@ class Detail extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
//删除工单信息
|
||||
//删除任务信息
|
||||
deletedetail=(id)=>{
|
||||
const { projectsId , orderId} = this.props.match.params;
|
||||
const { projectsId , orderId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}.json`;
|
||||
axios.delete(url,{ data: {
|
||||
project_id: projectsId,
|
||||
|
|
@ -140,7 +159,7 @@ class Detail extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
//关闭工单
|
||||
//关闭任务
|
||||
closedetail=(id)=>{
|
||||
const {projectsId,orderId} = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}/close_issue.json`;
|
||||
|
|
@ -159,13 +178,13 @@ class Detail extends Component{
|
|||
|
||||
//修改评论
|
||||
updatedetail=(id)=>{
|
||||
const {page, limit } = this.state;
|
||||
const { page , limit , countvalue } = this.state;
|
||||
const {orderId} = this.props.match.params;
|
||||
const url = `/issues/${orderId}/journals/${id}.json`;
|
||||
axios.put(url,{
|
||||
issue_id:orderId,
|
||||
id:id,
|
||||
content:this.state.countvalue
|
||||
content:JSON.stringify(countvalue)
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
|
|
@ -202,20 +221,15 @@ class Detail extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
changmodelname=(e)=>{
|
||||
this.setState({
|
||||
countvalue:e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
editdetail=(count,status)=>{
|
||||
this.setState({
|
||||
countvalue:count,
|
||||
countvalue:this.stringJson(count),
|
||||
isedit:status
|
||||
})
|
||||
}
|
||||
|
||||
renderJournalList=(list)=>{
|
||||
console.log(list);
|
||||
if(list && list.length >0){
|
||||
return(
|
||||
list.map((item,key)=>{
|
||||
|
|
@ -250,7 +264,7 @@ class Detail extends Component{
|
|||
|
||||
//复制
|
||||
copydetail=()=>{
|
||||
const {projectsId,orderId} = this.props.match.params;
|
||||
const {projectsId , orderId} = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}/copy.json`;
|
||||
axios.post(url,{
|
||||
project_id:projectsId,
|
||||
|
|
@ -280,11 +294,68 @@ class Detail extends Component{
|
|||
showFiles:flag
|
||||
})
|
||||
}
|
||||
// 新建评论
|
||||
onContentChange=(value)=>{
|
||||
if(value){
|
||||
this.setState({
|
||||
quillValue:value,
|
||||
quillFlag:false
|
||||
})
|
||||
}
|
||||
}
|
||||
// 编辑评论
|
||||
onEditContentChange=(value)=>{
|
||||
if(value){
|
||||
this.setState({
|
||||
countvalue:value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
handleShowImage=(value)=>{
|
||||
this.setState({
|
||||
imageUrl:value,
|
||||
visible:true
|
||||
})
|
||||
}
|
||||
setVisible=(flag)=>{
|
||||
this.setState({
|
||||
visible:flag
|
||||
})
|
||||
}
|
||||
|
||||
stringJson=(value) =>{
|
||||
let _value = null;
|
||||
|
||||
try {
|
||||
_value = JSON.parse(value);
|
||||
} catch (e) {
|
||||
_value = value;
|
||||
}
|
||||
return _value
|
||||
}
|
||||
|
||||
commentCtx = (ctx) => {
|
||||
let _ctx = null;
|
||||
|
||||
try {
|
||||
_ctx = JSON.parse(ctx);
|
||||
} catch (e) {
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
return (
|
||||
<QuillForEditor
|
||||
readOnly={true}
|
||||
value={_ctx}
|
||||
showUploadImage={this.handleShowImage}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
render(){
|
||||
const { projectsId,orderId} = this.props.match.params;
|
||||
const { data,journalsdata, page, limit, search_count, isSpin, isedit, showFiles } = this.state;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { projectsId , orderId } = this.props.match.params;
|
||||
const { data,journalsdata, page, limit, search_count, isSpin, isedit, showFiles , quillValue , quillFlag , countvalue , imageUrl , visible } = this.state;
|
||||
const { current_user } = this.props;
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
|
|
@ -303,64 +374,87 @@ class Detail extends Component{
|
|||
journalsdata.issue_journals.map((item,key)=>{
|
||||
return(
|
||||
<li key={key}>
|
||||
<div className="df">
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${item.user_picture && item.user_picture}`)} alt=""/></Link>
|
||||
<div className="detail_context" >
|
||||
<div className="topWrapper_detali">
|
||||
<p className="ml6 detail_p lineH40">
|
||||
{item.user_name}
|
||||
<span className="color-grey-9 ml3 mr3">评论于</span>
|
||||
<Tooltip title={item.format_time} placement="bottom">
|
||||
<span>{item.created_at}</span>
|
||||
</Tooltip>
|
||||
</p>
|
||||
<div className="detail_right" style={{display: current_user && isedit === undefined && (current_user.admin || current_user.login === item.user_login) ? "block" : "none"}}>
|
||||
<span onClick={()=>this.editdetail(item.content,item.id)} className="detail_edit_action">编辑</span>
|
||||
<Popconfirm placement="bottom" title={'确定要删除当前评论吗?'} okText="是" cancelText="否" onConfirm={()=>this.deleteorder(item.id)}>
|
||||
<span className="detail_edit_action">删除</span>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail_ptitlecount">
|
||||
<div style={{display: (isedit && isedit === item.id) ? "none" : "block"}} >
|
||||
{
|
||||
item.content ?
|
||||
<div>{item.content}</div>
|
||||
{
|
||||
key > 0&&
|
||||
<div className="order_line" style={{marginLeft:80}}></div>
|
||||
}
|
||||
<div className="df">
|
||||
<Link to={`/users/${item && item.user_login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${item && item.user_picture}`)} alt=""/>
|
||||
</Link>
|
||||
|
||||
<div className="detail_context" >
|
||||
<div className="topWrapper_detali">
|
||||
<p className="ml6 detail_p lineH40">
|
||||
{item.user_name}
|
||||
<span className="color-grey-9 ml3 mr3">评论于</span>
|
||||
<Tooltip title={item.format_time} placement="bottom">
|
||||
<span>{item.created_at}</span>
|
||||
</Tooltip>
|
||||
</p>
|
||||
<div className="detail_right" style={{display: current_user && isedit === undefined && (current_user.admin || current_user.login === item.user_login) ? "block" : "none"}}>
|
||||
<span onClick={()=>this.editdetail(item.content,item.id)} className="detail_edit_action">编辑</span>
|
||||
<Popconfirm placement="bottom" title={'确定要删除当前评论吗?'} okText="是" cancelText="否" onConfirm={()=>this.deleteorder(item.id)}>
|
||||
<span className="detail_edit_action">删除</span>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail_ptitlecount">
|
||||
<div style={{display: (isedit && isedit === item.id) ? "none" : "block"}} >
|
||||
{
|
||||
item.content ?
|
||||
this.commentCtx(item.content)
|
||||
:
|
||||
<div>
|
||||
{this.renderJournalList(item.journal_details)}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
item && item.attachments && item.attachments.length > 0 ?
|
||||
<Attachments attachments={item.attachments} showNotification={this.props.showNotification} canDelete={current_user && (current_user.admin || current_user.login === item.user_login)}/>
|
||||
:
|
||||
<div>
|
||||
{this.renderJournalList(item.journal_details)}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
item && item.attachments && item.attachments.length > 0 ?
|
||||
<Attachments attachments={item.attachments} showNotification={this.props.showNotification} canDelete={current_user && (current_user.admin || current_user.login === item.user_login)}/>
|
||||
:
|
||||
""
|
||||
}
|
||||
""
|
||||
}
|
||||
</div>
|
||||
<div style={{display: (isedit && isedit === item.id) ? "block" : "none"}}>
|
||||
<div className="quillContent mt20">
|
||||
<QuillForEditor
|
||||
wrapStyle={{
|
||||
height: '220px',
|
||||
opacity:1,
|
||||
}}
|
||||
autoFocus={true}
|
||||
style={{ height: '170px' }}
|
||||
placeholder="添加评论..."
|
||||
options={options}
|
||||
value={countvalue}
|
||||
onContentChange={this.onEditContentChange}
|
||||
/>
|
||||
<p className="quillFlag">
|
||||
{ quillFlag && <span className="">请输入评论内容</span>}
|
||||
</p>
|
||||
</div>
|
||||
{/*<TextArea style={{height:"200px"}} value={this.state.countvalue} onChange={this.changmodelname}/>*/}
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={()=>this.updatedetail(item.id)}>保存</a>
|
||||
<a className="a_btn cancel_btn fr" type="submit" onClick={()=>this.editdetail(item.content,undefined)}>取消</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{display: (isedit && isedit === item.id) ? "block" : "none"}}>
|
||||
<TextArea style={{height:"200px"}} value={this.state.countvalue} onChange={this.changmodelname}/>
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={()=>this.updatedetail(item.id)}>保存</a>
|
||||
<a className="a_btn cancel_btn fr" type="submit" onClick={()=>this.editdetail(item.content,undefined)}>取消</a>
|
||||
</p>
|
||||
<div style={{display: this.state.display}}>
|
||||
<div className="div_line" ></div>
|
||||
{/* <List
|
||||
grid={{ gutter: 16, column: 6 }}
|
||||
dataSource={valuse}
|
||||
renderItem={obj => (
|
||||
<List.Item>
|
||||
<img class="list_img" onClick={this.imgshow} src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt=""/>
|
||||
</List.Item>
|
||||
)}
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{display: this.state.display}}>
|
||||
<div className="div_line" ></div>
|
||||
{/* <List
|
||||
grid={{ gutter: 16, column: 6 }}
|
||||
dataSource={valuse}
|
||||
renderItem={obj => (
|
||||
<List.Item>
|
||||
<img class="list_img" onClick={this.imgshow} src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt=""/>
|
||||
</List.Item>
|
||||
)}
|
||||
/> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="order_line" style={{marginLeft:80}}></div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
|
|
@ -370,151 +464,170 @@ class Detail extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
<Link to={`/projects/${projectsId}/orders/new`} className="topWrapper_btn">创建工单</Link>
|
||||
</div>
|
||||
<div>
|
||||
<div className="detailContent">
|
||||
<p>
|
||||
{
|
||||
data ?
|
||||
<span className="font-20">【{data.issue_classify === "issue" ? data.tracker : "合并请求"}】</span>
|
||||
:
|
||||
""
|
||||
}
|
||||
<span className="font-20" > { data && data.subject }</span>
|
||||
|
||||
</p>
|
||||
<p className="mt10 color-grey-c">
|
||||
<span className={data&&data.issue_status==="关闭"?"closedetail":"opendetail"}>{data&&data.issue_status==="关闭"?"关闭中":"开启中"} </span>
|
||||
<span className="ml10 lineH32">
|
||||
由 { data && data.author_name} 于 { data && data.created_at }创建{ data && data.journals_count && data.journals_count > 0 ?` · ${data.journals_count} 条评论`:""}
|
||||
</span>
|
||||
{
|
||||
data && data.user_permission ?
|
||||
<span className="pull-right lineH32">
|
||||
<a className="color-blue fr" onClick={this.copydetail}>复制</a>
|
||||
<Popconfirm placement="bottom" title={'您确定要删除吗'} okText="是" cancelText="否" onConfirm={()=>this.deletedetail(orderId)}>
|
||||
<a className="color-blue fr" style={{marginLeft:20,marginRight:20}}>删除</a>
|
||||
</Popconfirm>
|
||||
|
||||
<Link to={`/projects/${projectsId}/orders/${orderId}/updatedetail`} className="color-blue fr">编辑</Link>
|
||||
</span>
|
||||
:
|
||||
""
|
||||
}
|
||||
</p>
|
||||
<div className="df mt20">
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${data && data.author_picture}`)} alt=""/></Link>
|
||||
<div className="detail_context">
|
||||
<div className="detail_p">
|
||||
{ data && data.description }
|
||||
</div>
|
||||
{ visible && <AmplifyImg url={imageUrl} visible={visible} setVisible={this.setVisible}/> }
|
||||
<div>
|
||||
<div className="detailContent">
|
||||
<p>
|
||||
{
|
||||
data && data.attachments && data.attachments.length > 0 ?
|
||||
<Attachments attachments={data.attachments} showNotification={this.props.showNotification}/>
|
||||
data ?
|
||||
<span className="font-20">【{data.issue_classify === "issue" ? (data.tracker ? data.tracker : "缺陷" ) : "合并请求"}】</span>
|
||||
:
|
||||
""
|
||||
}
|
||||
</div>
|
||||
<span className="font-20" > { data && data.subject }</span>
|
||||
|
||||
</p>
|
||||
<p className="mt15 color-grey-c">
|
||||
<span className={data&&data.issue_status==="关闭"?"closedetail":"opendetail"}>{data&&data.issue_status==="关闭"?"关闭中":"开启中"} </span>
|
||||
<span className="ml10 lineH32">
|
||||
由 { data && data.author_name} 于 { data && data.created_at }创建{ data && data.journals_count && data.journals_count > 0 ?` · ${data.journals_count} 条评论`:""}
|
||||
</span>
|
||||
{
|
||||
data && data.user_permission ?
|
||||
<span className="pull-right lineH32">
|
||||
<a className="color-blue fr" onClick={this.copydetail}>复制</a>
|
||||
<Popconfirm placement="bottom" title={'您确定要删除吗'} okText="是" cancelText="否" onConfirm={()=>this.deletedetail(orderId)}>
|
||||
<a className="color-blue fr" style={{marginLeft:20,marginRight:20}}>删除</a>
|
||||
</Popconfirm>
|
||||
|
||||
<Link to={`/projects/${projectsId}/orders/${orderId}/updatedetail`} className="color-blue fr">编辑</Link>
|
||||
</span>
|
||||
:
|
||||
""
|
||||
}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="f-wrap-between mt5" style={{alignItems:"flex-start"}}>
|
||||
<div className="item-list-right" >
|
||||
<Spin spinning={isSpin}>
|
||||
<ul className="ul_width">
|
||||
{renderList()}
|
||||
</ul>
|
||||
</Spin>
|
||||
|
||||
{ Paginations }
|
||||
|
||||
<div className="df">
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<div className="new_context">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('content', {
|
||||
rules: [{
|
||||
required: true, message: '请输入内容'
|
||||
}],
|
||||
})(
|
||||
<TextArea placeholder="添加评论..." style={{height: "200px"}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<UploadComponent load={this.UploadFunc} isComplete={showFiles} changeIsComplete={this.changeIsComplete}></UploadComponent>
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={this.addjournals}>评论</a>
|
||||
<div className="f-wrap-between mt20" style={{alignItems:"flex-start"}}>
|
||||
<div className="item-list-right" >
|
||||
<div className="df ">
|
||||
<Link to={``}><img className="user_img" src={getImageUrl(`images/${data && data.author_picture}`)} alt=""/></Link>
|
||||
<div className="detail_context">
|
||||
<div className="detail_p">
|
||||
{data&&data.description&&(data.description.length > 0)?this.commentCtx(data.description): <span className="color-grey-9 ml3 mr3">没有描述</span>}
|
||||
</div>
|
||||
{
|
||||
data && data.user_permission ?
|
||||
<a className="Closeor_btn fr" type="submit"
|
||||
onClick={() => this.closedetail(data && data.issue_status === "关闭" ? 2 : 5)}>{data && data.issue_status === "关闭" ? "重新开启" : "关闭"}</a>
|
||||
data && data.attachments && data.attachments.length > 0 ?
|
||||
<Attachments attachments={data.attachments} showNotification={this.props.showNotification}/>
|
||||
:
|
||||
""
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="order_line" style={{marginLeft:80}}></div>
|
||||
<Spin spinning={isSpin}>
|
||||
<ul className="ul_width">
|
||||
{renderList()}
|
||||
</ul>
|
||||
</Spin>
|
||||
|
||||
{ Paginations }
|
||||
{
|
||||
current_user && current_user.login ?
|
||||
<React.Fragment>
|
||||
<div className="order_line" style={{marginLeft:80}}></div>
|
||||
<div className="df">
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
<div className="new_context">
|
||||
<div className="quillContent">
|
||||
<QuillForEditor
|
||||
|
||||
wrapStyle={{
|
||||
height: '220px',
|
||||
opacity:1,
|
||||
}}
|
||||
autoFocus={true}
|
||||
style={{ height: '150px' }}
|
||||
placeholder="添加评论..."
|
||||
options={options}
|
||||
value={quillValue}
|
||||
onContentChange={this.onContentChange}
|
||||
// showUploadImage={this.handleShowImage}
|
||||
/>
|
||||
<p className="quillFlag">
|
||||
{ quillFlag && <span className="">请输入评论内容</span>}
|
||||
</p>
|
||||
</div>
|
||||
<UploadComponent load={this.UploadFunc} isComplete={showFiles} changeIsComplete={this.changeIsComplete}></UploadComponent>
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={this.addjournals}>评论</a>
|
||||
{
|
||||
data && data.user_permission ?
|
||||
<a className="Closeor_btn fr" type="submit"
|
||||
onClick={() => this.closedetail(data && data.issue_status === "关闭" ? 2 : 5)}>{data && data.issue_status === "关闭" ? "重新开启" : "关闭"}</a>
|
||||
:
|
||||
""
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
:
|
||||
<div className="loginDiv"><Link to={`/login`}>登录</Link>并参与到对话中</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
<div className="list-left DetailRight" style={{backgroundColor:"#fff"}}>
|
||||
<p>
|
||||
<span className="span_title">分支</span>
|
||||
<span>{
|
||||
data && data.branch_name ? data.branch_name : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">标签</span>
|
||||
<span>{
|
||||
data && data.issue_tags ? <span className="issue-tag-show" style={{background: data.issue_tags[0].color}}>{data.issue_tags[0].name}</span> : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p style={{display: "inline-block",'white-space': "nowrap" }}>
|
||||
<span className="span_title">里程碑</span>
|
||||
<span className="title_overflow">{
|
||||
data && data.version ? data.version : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">当前状态</span>
|
||||
<span>{
|
||||
data && data.issue_status ? data.issue_status : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">分类</span>
|
||||
<span>{
|
||||
data && data.tracker ? data.tracker : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">指派给</span>
|
||||
<span>{data && data.assign_user_name ? data.assign_user_name : "--"}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">优先级</span>
|
||||
<span>{data && data.priority ? data.priority : "--"}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">完成度</span>
|
||||
<span>{data && data.done_ratio ? data.done_ratio : "--"}</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="list-left DetailRight mt10">
|
||||
<p>
|
||||
<span className="span_title">分支</span>
|
||||
<span>{
|
||||
data && data.branch_name ? data.branch_name : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">标签</span>
|
||||
<span>{
|
||||
data && data.issue_tags ? <span className="issue-tag-show" style={{background: data.issue_tags[0].color}}>{data.issue_tags[0].name}</span> : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">里程碑</span>
|
||||
<span>{
|
||||
data && data.version ? data.version : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">当前状态</span>
|
||||
<span>{
|
||||
data && data.issue_status ? data.issue_status : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">分类</span>
|
||||
<span>{
|
||||
data && data.tracker ? data.tracker : "--"
|
||||
}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">指派给</span>
|
||||
<span>{data && data.assign_user_name ? data.assign_user_name : "--"}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">优先级</span>
|
||||
<span>{data && data.priority ? data.priority : "--"}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span className="span_title">完成度</span>
|
||||
<span>{data && data.done_ratio ? data.done_ratio : "--"}</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
onCancel={this.handleCancel}
|
||||
visible={this.state.isShow}
|
||||
width="400px"
|
||||
footer={
|
||||
[]
|
||||
}
|
||||
bodyStyle={{textAlign:'center'}}
|
||||
>
|
||||
<img className="list_img" src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt=""/>
|
||||
<Modal
|
||||
onCancel={this.handleCancel}
|
||||
visible={this.state.isShow}
|
||||
width="400px"
|
||||
footer={
|
||||
[]
|
||||
}
|
||||
bodyStyle={{textAlign:'center'}}
|
||||
>
|
||||
<img className="list_img" src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1608431072,669449145&fm=27&gp=0.jpg" alt=""/>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React , {Component} from 'react';
|
|||
import { Link } from 'react-router-dom';
|
||||
import { Dropdown , Icon , Menu , Pagination,Typography,Popconfirm} from 'antd';
|
||||
import Nav from './Nav';
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import NoneData from '../Nodata';
|
||||
import axios from 'axios';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
|
@ -41,6 +41,7 @@ class Milepost extends Component{
|
|||
}
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
|
||||
this.setState({
|
||||
data:result.data
|
||||
})
|
||||
|
|
@ -75,7 +76,7 @@ class Milepost extends Component{
|
|||
|
||||
updatestatusemile=(status,arr)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions/${arr.id}/update_status`;
|
||||
const url = `/projects/${projectsId}/versions/${arr.id}/update_status.json`;
|
||||
const { current_user } = this.props;
|
||||
axios.post(url,{
|
||||
project_id:projectsId,
|
||||
|
|
@ -98,7 +99,7 @@ class Milepost extends Component{
|
|||
|
||||
closemile=(arr)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions/${arr.id}`;
|
||||
const url = `/projects/${projectsId}/versions/${arr.id}.json`;
|
||||
axios.delete(url,{ data: {
|
||||
project_id: projectsId,
|
||||
id: arr.id
|
||||
|
|
@ -153,8 +154,8 @@ class Milepost extends Component{
|
|||
<Menu.Item key={'created_on'} value="asc">到期日从远到近</Menu.Item>
|
||||
<Menu.Item key={'percent'} value="desc">完成度从低到高</Menu.Item>
|
||||
<Menu.Item key={'percent'} value="asc">完成度从高到低</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="desc">工单从多到少</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="asc">工单从少到多</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="desc">任务从多到少</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="asc">任务从少到多</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
|
||||
|
|
@ -172,12 +173,14 @@ class Milepost extends Component{
|
|||
const renderList =()=>{
|
||||
if(data && data.versions && data.versions.length>0 ){
|
||||
return(
|
||||
<div className="tagList">
|
||||
{
|
||||
data.versions.map((item,key)=>{
|
||||
return(
|
||||
<div style={{display:'block'}}>
|
||||
<div className="milepostdiv">
|
||||
<div>
|
||||
<div className="tagList">
|
||||
{
|
||||
|
||||
data.versions.length===0?<NoneData></NoneData>:data.versions.map((item,key)=>{
|
||||
return(
|
||||
<div style={{display:'block'}}>
|
||||
<div className="milepostdiv">
|
||||
<div className="milepostwidth">
|
||||
<div className="grid-item width100">
|
||||
<i className="iconfont icon-lubiaosignpost3 font-12 mr3"></i>
|
||||
|
|
@ -185,8 +188,8 @@ class Milepost extends Component{
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="milepostdiv" style={{marginTop:5}}>
|
||||
</div>
|
||||
<div className="milepostdiv" style={{marginTop:5}}>
|
||||
<div className="milepostrighe">
|
||||
|
||||
<div className="grid-item mr10">
|
||||
|
|
@ -212,47 +215,49 @@ class Milepost extends Component{
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="milepostleft">
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-bianji3 font-14 mr5"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/meilpost`} className="color-grey-9">编辑</Link>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-yiguanbi1 font-14 mr5"></i>
|
||||
<a onClick={()=>this.updatestatusemile(this.state.status==="closed"?"open":"closed",item)} className="color-grey-9">{this.state.status==="closed"?"开启":"关闭"}</a>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-lajitong font-14 mr5" ></i>
|
||||
<Popconfirm placement="bottom" title={'是否删除里程碑?'} okText="是" cancelText="否" onConfirm={()=>this.closemile(item)}>
|
||||
<a className="color-grey-9">删除</a>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="milepostleft">
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-bianji3 font-14 mr5"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/meilpost`} className="color-grey-9">编辑</Link>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-yiguanbi1 font-14 mr5"></i>
|
||||
<a onClick={()=>this.updatestatusemile(this.state.status==="closed"?"open":"closed",item)} className="color-grey-9">{this.state.status==="closed"?"开启":"关闭"}</a>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-lajitong font-14 mr5" ></i>
|
||||
<Popconfirm placement="bottom" title={'是否删除里程碑?'} okText="是" cancelText="否" onConfirm={()=>this.closemile(item)}>
|
||||
<a className="color-grey-9">删除</a>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
: ''
|
||||
}
|
||||
|
||||
</div>
|
||||
<div className="milepostdiv"style={{marginTop:5}}>
|
||||
</div>
|
||||
<div className="milepostdiv"style={{marginTop:5}}>
|
||||
<div className="textwidth">
|
||||
<Text
|
||||
<Text
|
||||
type="secondary"
|
||||
ellipsis={{rows: 30, expandable: false, onExpand: Function}}
|
||||
>
|
||||
>
|
||||
{item.description}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<NoneData />
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -260,16 +265,15 @@ class Milepost extends Component{
|
|||
return(
|
||||
<div className="main">
|
||||
<div>
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state} />
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<Link to={`/projects/${projectsId}/orders/meilpost`} className="topWrapper_btn">新的里程碑</Link>
|
||||
: ''
|
||||
}
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state} />*/}
|
||||
{/*{*/}
|
||||
{/*data && data.user_admin_or_member ?*/}
|
||||
{/*<Link to={`/projects/${projectsId}/orders/meilpost`} className="topWrapper_btn">新的里程碑</Link>*/}
|
||||
{/*: ''*/}
|
||||
{/*}*/}
|
||||
|
||||
|
||||
</div>
|
||||
{/*</div>*/}
|
||||
<div style={{display: this.state.display}}>
|
||||
<div className="tagdiv" >
|
||||
<span>里程碑{ data && data.issue_tags_count }已创建</span>
|
||||
|
|
@ -277,19 +281,29 @@ class Milepost extends Component{
|
|||
</div>
|
||||
<div className="topWrapper">
|
||||
<div className="topWrapper_type">
|
||||
<li className={openselect ? "active":""} onClick={()=>this.opneMilelist(1)}>{data && data.open_count}个开启中</li>
|
||||
<li className={closeselect ? "active":""} onClick={()=>this.opneMilelist(2)}>{data && data.closed_count}个已关闭</li>
|
||||
<li className={openselect ? "active":""} onClick={()=>this.opneMilelist(1)}>{data && data.open_count}个开启中</li>
|
||||
<li className={closeselect ? "active":""} onClick={()=>this.opneMilelist(2)}>{data && data.closed_count}个已关闭</li>
|
||||
{/* <span onClick={this.opneMilelist}>{ data && data.open_count }开启中</span>
|
||||
<span onClick={this.closeMilelist}>{ data && data.closed_count }已关闭</span> */}
|
||||
</div>
|
||||
<div className="topWrapper_select">
|
||||
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>排序<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<Link to={`/projects/${projectsId}/orders/meilpost`} className="topWrapper_btn">新的里程碑</Link>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>排序<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{ renderList()}
|
||||
{ Paginations }
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {Link} from 'react-router-dom';
|
|||
import { Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
|
||||
import './order.css';
|
||||
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import NoneData from '../Nodata';
|
||||
import OrderItem from './OrderItem';
|
||||
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ class MilepostDetail extends Component{
|
|||
render(){
|
||||
|
||||
const { issue_chosen , issues , limit , page , search_count , data , isSpin,openselect,closeselect } = this.state;
|
||||
const { projectsId,meilid } = this.props.match.params;
|
||||
const { projectsId , meilid } = this.props.match.params;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={(e)=>this.getOption(e)}>
|
||||
|
|
@ -287,7 +287,7 @@ class MilepostDetail extends Component{
|
|||
<p>{data&&data.name}</p>
|
||||
<div className="milepostdiv">
|
||||
<Link to={`/projects/${projectsId}/orders/${meilid}/meilpost`} className="topWrapper_btn" style={{marginRight:15}} >编辑里程碑</Link>
|
||||
<Link to={`/projects/${projectsId}/orders/new`} className="topWrapper_btn">创建工单</Link>
|
||||
<Link to={`/projects/${projectsId}/orders/${meilid}/new`} className="topWrapper_btn">创建任务</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-item mr10">
|
||||
|
|
@ -362,7 +362,7 @@ class MilepostDetail extends Component{
|
|||
</div>
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData></NoneData>
|
||||
<NoneData _html="暂时还没有相关数据哦!"/>
|
||||
:
|
||||
<OrderItem issues={issues} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state}></OrderItem>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
class OrderItem extends Component{
|
||||
set_issue_tags =(issue_tags)=>{
|
||||
if(issue_tags && issue_tags.length > 0){
|
||||
return(
|
||||
issue_tags.map((item,key)=>{
|
||||
return(
|
||||
<span className="issue-tag-show" style={{background: item.color}}>{item.name}</span>
|
||||
)
|
||||
})
|
||||
)
|
||||
}else{
|
||||
return("--")
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
const { issues , search_count , page , limit } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const renderList =()=>{
|
||||
data.versions.map((item,key)=>{
|
||||
return(
|
||||
<div style={{display:'block'}}>
|
||||
<div className="milepostdiv">
|
||||
<div className="milepostwidth">
|
||||
<div className="grid-item width100">
|
||||
<i className="iconfont icon-lubiaosignpost3 font-12 mr3"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/MilepostDetail`} className="font-16">{item.name}</Link>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div className="milepostdiv" style={{marginTop:5}}>
|
||||
<div className="milepostrighe">
|
||||
|
||||
<div className="grid-item mr10">
|
||||
<i className="iconfont icon-rili font-14 mr5">
|
||||
</i>
|
||||
{
|
||||
item.effective_date ?
|
||||
<span className="color-red">{item.effective_date}</span>
|
||||
:
|
||||
<span className="color-grey-c">暂无截止时间</span>
|
||||
}
|
||||
</div>
|
||||
<div className="grid-item mr10 color-grey-9">
|
||||
<i className="iconfont icon-issue font-14 mr5"></i>
|
||||
<span>
|
||||
{item.open_issues_count}个开启
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid-item mr10 color-grey-9">
|
||||
<i className="iconfont icon-shanchudiao font-14 mr5"></i>
|
||||
<span>
|
||||
{item.close_issues_count}个关闭
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="milepostleft">
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-bianji3 font-14 mr5"></i>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/meilpost`} className="color-grey-9">编辑</Link>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-yiguanbi1 font-14 mr5"></i>
|
||||
<a onClick={()=>this.updatestatusemile(this.state.status==="closed"?"open":"closed",item)} className="color-grey-9">{this.state.status==="closed"?"开启":"关闭"}</a>
|
||||
</div>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<i className="iconfont icon-lajitong font-14 mr5" ></i>
|
||||
<Popconfirm placement="bottom" title={'是否删除里程碑?'} okText="是" cancelText="否" onConfirm={()=>this.closemile(item)}>
|
||||
<a className="color-grey-9">删除</a>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
: ''
|
||||
}
|
||||
|
||||
</div>
|
||||
<div className="milepostdiv"style={{marginTop:5}}>
|
||||
<div className="textwidth">
|
||||
<Text
|
||||
type="secondary"
|
||||
ellipsis={{rows: 30, expandable: false, onExpand: Function}}
|
||||
>
|
||||
{item.description}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
{renderList()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default OrderItem;
|
||||
|
|
@ -1,17 +1,25 @@
|
|||
import React , { Component } from "react";
|
||||
import { Form , Input , Select } from 'antd';
|
||||
import {Link} from 'react-router-dom';
|
||||
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
import Nav from './Nav';
|
||||
import UploadComponent from '../Upload/Index';
|
||||
import QuillForEditor from '../quillForEditor';
|
||||
|
||||
import './order.css';
|
||||
|
||||
import axios from 'axios';
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
const Option = Select.Option;
|
||||
const TextArea = Input.TextArea;
|
||||
const options = [
|
||||
['bold', 'italic', 'underline'],
|
||||
[{header: [1,2,3,false]}],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['formula']
|
||||
];
|
||||
class New extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
|
@ -27,11 +35,16 @@ class New extends Component{
|
|||
done_ratio:"0%",
|
||||
issue_chosen:undefined,
|
||||
branches:undefined,
|
||||
fileList:undefined
|
||||
fileList:undefined,
|
||||
description:undefined
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
if(!this.props.checkIfLogin()){
|
||||
this.props.showLoginDialog();
|
||||
return;
|
||||
}
|
||||
this.InitData();
|
||||
this.getSelectList();
|
||||
}
|
||||
|
|
@ -43,7 +56,19 @@ class New extends Component{
|
|||
}
|
||||
|
||||
getSelectList=()=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
let projectsId = ""
|
||||
if(this.props.match.params.milepostId){
|
||||
projectsId = this.props.match.params.projectsId;
|
||||
this.props.form.setFieldsValue({
|
||||
fixed_version_id: this.props.match.params.milepostId
|
||||
});
|
||||
// this.setState({
|
||||
// fixed_version_id: this.props.match.params.milepostId
|
||||
// })
|
||||
}else{
|
||||
projectsId = this.props.match.params.projectsId;
|
||||
}
|
||||
|
||||
const url = `/projects/${projectsId}/issues/new.json`;
|
||||
axios.get(url).then((result)=>{
|
||||
if(result){
|
||||
|
|
@ -94,13 +119,15 @@ class New extends Component{
|
|||
if(values.issue_tag_ids.length > 0){
|
||||
values.issue_tag_ids = [values.issue_tag_ids]
|
||||
}
|
||||
|
||||
const { description } = this.state;
|
||||
|
||||
axios.post(url,{
|
||||
...values,
|
||||
description:JSON.stringify(description),
|
||||
attachment_ids:fileList
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification("工单创建成功!");
|
||||
this.props.showNotification("任务创建成功!");
|
||||
this.props.history.push(`/projects/${projectsId}/orders`);
|
||||
}
|
||||
}).catch(error=>{
|
||||
|
|
@ -118,45 +145,61 @@ class New extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
onContentChange=(value)=>{
|
||||
this.setState({
|
||||
description:value
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { current_user } = this.props;
|
||||
const { issue_tag_ids , fixed_version_id , branch_name , status_id , tracker_id , issue_type ,assigned_to_id , priority_id , done_ratio,
|
||||
const { issue_tag_ids , fixed_version_id , branch_name , status_id , tracker_id , description ,assigned_to_id , priority_id , done_ratio,
|
||||
issue_chosen , branches } = this.state;
|
||||
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state} />
|
||||
</div>
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state} />*/}
|
||||
{/*</div>*/}
|
||||
<Form>
|
||||
<div className="f-wrap-between mt20" style={{alignItems:"flex-start"}}>
|
||||
<div className="list-right df">
|
||||
<Link to={``}><img class="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<Link to={`/users/${current_user && current_user.login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
</Link>
|
||||
|
||||
<div className="new_context">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('subject', {
|
||||
rules: [{
|
||||
required: true, message: '请填写工单标题'
|
||||
required: true, message: '请填写任务标题'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="标题"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('description', {
|
||||
rules: [],
|
||||
})(
|
||||
<TextArea placeholder="请输入工单的描述..." style={{height:"300px"}}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<div className="quillContent" style={{marginBottom:"20px"}}>
|
||||
<QuillForEditor
|
||||
value = {description}
|
||||
wrapStyle={{
|
||||
height: '240px',
|
||||
opacity:1,
|
||||
}}
|
||||
// autoFocus={true}
|
||||
style={{ height: '180px' }}
|
||||
placeholder="请输入任务的描述..."
|
||||
options={options}
|
||||
onContentChange={this.onContentChange}
|
||||
/>
|
||||
</div>
|
||||
<UploadComponent load={this.UploadFunc} showNotification={this.props.showNotification} isComplete={true}></UploadComponent>
|
||||
<p className="clearfix mt15">
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={this.handleSubmit}>创建Issue</a>
|
||||
<a className="topWrapper_btn fr" type="submit" onClick={this.handleSubmit}>创建任务</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="list-left" style={{paddingRight:"0px",paddingLeft:"15px",paddingTop:"10px"}}>
|
||||
<div className="list-left mt10" style={{paddingRight:"0px",paddingLeft:"0px",width:"25%",backgroundColor:"#fff"}}>
|
||||
<div className="list-l-panel">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('branch_name', {
|
||||
|
|
@ -181,7 +224,7 @@ class New extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select value={issue_tag_ids}>
|
||||
<Option value={""}>未选择标签</Option>
|
||||
<Option value={""}>{issue_chosen && issue_chosen.issue_tag.length > 0 ? '未选择标签':'请在仓库设置里添加标签'}</Option>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.issue_tag) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
@ -191,9 +234,10 @@ class New extends Component{
|
|||
>
|
||||
{getFieldDecorator('fixed_version_id', {
|
||||
rules: [],
|
||||
|
||||
})(
|
||||
<Select value={fixed_version_id}>
|
||||
<Option value={""}>未选择里程碑</Option>
|
||||
<Select>
|
||||
<Option value={""}>{issue_chosen && issue_chosen.issue_version.length > 0 ? '未选择里程碑': '请添加里程碑'}</Option>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.issue_version) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,18 @@
|
|||
import React , { Component } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Popconfirm} from 'antd'
|
||||
|
||||
|
||||
|
||||
class OrderItem extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
//显示 隐藏
|
||||
isdisplay:false,
|
||||
orderid:'',
|
||||
}
|
||||
}
|
||||
set_issue_tags =(issue_tags)=>{
|
||||
if(issue_tags && issue_tags.length > 0){
|
||||
return(
|
||||
|
|
@ -16,9 +27,27 @@ class OrderItem extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
deletedetail=(id)=>{ // 学习挣钱,调用父组件方法
|
||||
this.props.deletedetail(id);
|
||||
}
|
||||
|
||||
onMouseMove=(type)=>{
|
||||
this.setState({
|
||||
isdisplay:true,
|
||||
orderid:type
|
||||
})
|
||||
}
|
||||
|
||||
onMouseOut=()=>{
|
||||
this.setState({
|
||||
isdisplay:false
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
const { issues , search_count , page , limit } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const {current_user} = this.props
|
||||
|
||||
const renderList =()=>{
|
||||
if(issues && issues.length > 0){
|
||||
|
|
@ -28,7 +57,7 @@ class OrderItem extends Component{
|
|||
<div className="issueItem" key={key}>
|
||||
<div className="flex-1">
|
||||
<p className="mb15 df">
|
||||
<span className="issueNo"># {search_count - (key + (page-1) * limit)}</span>
|
||||
<span className={item.issue_status==="关闭"? "issueNo":"issueNo issueOpen"}># {search_count - (key + (page-1) * limit)}</span>
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/detail`} className="flex-1 hide-1 font-16 color-grey-3 lineh-30">{item.name}</Link>
|
||||
</p>
|
||||
<p className="color-grey-6 font-12">
|
||||
|
|
@ -41,15 +70,55 @@ class OrderItem extends Component{
|
|||
}
|
||||
</p>
|
||||
</div>
|
||||
<ul className="topWrapper_select">
|
||||
<ul className="topWrapper_select no-cursor" onMouseMove={()=>this.onMouseMove(item.id)} onMouseOut={()=>this.onMouseOut()} >
|
||||
<li>{this.set_issue_tags(item.issue_tags)}</li>
|
||||
{/*<li>{item.issue_type || "--"}</li>*/}
|
||||
<li>{item.tracker || "--"}</li>
|
||||
<li>{item.author_name || "--"}</li>
|
||||
<li>{item.assign_user_name || "--"}</li>
|
||||
<li>{item.priority || "--"}</li>
|
||||
<li>
|
||||
{
|
||||
item.author_name ?
|
||||
<Link to={`/users/${item.author_login}/projects`} className="show-user-link">
|
||||
{item.author_name}
|
||||
</Link>
|
||||
: "--"
|
||||
}
|
||||
|
||||
</li>
|
||||
<li>
|
||||
{
|
||||
item.assign_user_name ?
|
||||
<Link to={`/users/${item.assign_user_login}/projects`} className="show-user-link">
|
||||
{item.assign_user_name}
|
||||
</Link>
|
||||
: "--"
|
||||
}
|
||||
{/* {item.assign_user_name || "--"} */}
|
||||
</li>
|
||||
<li><p style={{width:60,height:25,margin:'auto', paddingTop:2,background:item.priority==='高'?'#e67e22':item.priority==='正常'?'#28be6c':item.priority==='低'?'#1abc9c':'#e74c3c',color:'#ffffff',borderRadius:4}}>{item.priority|| "--"}</p></li>
|
||||
<li>{item.done_ratio || "--"}</li>
|
||||
<li>{ item.journals_count ? <span><i className="iconfont icon-pinglun1 mr3 font-16"></i>{item.journals_count}</span> : "" }</li>
|
||||
<li>
|
||||
<div className="flex-1">
|
||||
<p>
|
||||
{ item.journals_count ? <Link to={`/projects/${projectsId}/orders/${item.id}/detail`}><i className="iconfont icon-pinglun1 mr3 font-16"></i>{item.journals_count}</Link> : "" }
|
||||
</p>
|
||||
{
|
||||
current_user && current_user.login ?
|
||||
<div className="milepostleft" style={{display:this.state.orderid===item.id&&this.state.isdisplay?'flex':'none'}}>
|
||||
<div className="grid-item mr15 color-grey-9">
|
||||
<Link to={`/projects/${projectsId}/orders/${item.id}/updatedetail`} className="color-grey-9"><i className="iconfont icon-bianji3 font-14 mr5"></i></Link>
|
||||
</div>
|
||||
<div className="grid-item color-grey-9">
|
||||
<Popconfirm placement="bottom" title={'您确定要删除吗'} okText="是" cancelText="否" onConfirm={()=>this.deletedetail(item.id)}>
|
||||
<i className="iconfont icon-yiguanbi1 font-14"></i>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React , {Component} from 'react';
|
|||
import { Dropdown , Icon , Menu , Pagination, Modal,Input,Popconfirm,Form } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Nav from './Nav';
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import NoneData from '../Nodata';
|
||||
import { SketchPicker } from 'react-color'
|
||||
import reactCSS from 'reactcss'
|
||||
import axios from 'axios';
|
||||
|
|
@ -63,7 +63,7 @@ class Tags extends Component{
|
|||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags`;
|
||||
const url = `/projects/${projectsId}/issue_tags.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
project_id:projectsId,
|
||||
|
|
@ -280,37 +280,50 @@ class Tags extends Component{
|
|||
const renderList =()=>{
|
||||
if(data && data.issue_tags && data.issue_tags.length>0 ){
|
||||
return(
|
||||
<div className="tagList">
|
||||
{
|
||||
data.issue_tags.map((item,key)=>{
|
||||
return(
|
||||
<div>
|
||||
<div>
|
||||
<div className="topWrapper">
|
||||
<span>共{ data && data.issue_tags_count }个标签</span>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>标签<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="tagList">
|
||||
{
|
||||
data.issue_tags.map((item,key)=>{
|
||||
return(
|
||||
<div>
|
||||
<span className="width20 mr10">
|
||||
<span style={{backgroundColor:`${item.color}`}} className="tagColor"></span>
|
||||
{item.name}
|
||||
</span>
|
||||
<span className="hide-1 width50 mr10">{item.description}</span>
|
||||
<span className="width15 mr10">{item.issues_count}个开启的工单</span>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="width15 text-right">
|
||||
<a onClick={()=>this.editshow(item)} className="topWrapper_btn fr" >编辑</a>
|
||||
<Popconfirm placement="bottom" title={'删除标签会将其从所有引用中删除。继续?'} okText="是" cancelText="否" onConfirm={()=>this.deletetag(item.id)}>
|
||||
<a className="a_btn delete_btn fr" >删除</a>
|
||||
</Popconfirm>
|
||||
<span className="hide-1 width50 mr10">{item.description}</span>
|
||||
<span className="width15 mr10">{item.issues_count}个开启的任务</span>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="width15 text-right">
|
||||
<a onClick={()=>this.editshow(item)} className="topWrapper_btn fr" >编辑</a>
|
||||
<Popconfirm placement="bottom" title={'删除标签会将其从所有引用中删除。继续?'} okText="是" cancelText="否" onConfirm={()=>this.deletetag(item.id)}>
|
||||
<a className="a_btn delete_btn fr" >删除</a>
|
||||
</Popconfirm>
|
||||
|
||||
</div>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<NoneData />
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -378,16 +391,7 @@ class Tags extends Component{
|
|||
|
||||
|
||||
</div>
|
||||
<div className="topWrapper">
|
||||
<span>共{ data && data.issue_tags_count }个标签</span>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>标签<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{ renderList() }
|
||||
{ Paginations }
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,15 +5,20 @@ import axios from 'axios';
|
|||
import Nav from './Nav';
|
||||
import UploadComponent from '../Upload/Index';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import{ Modal,Col,Form,Input,Tooltip,Select } from 'antd'
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import{ Modal , Form , Input , Select } from 'antd'
|
||||
|
||||
import Attachments from '../Upload/attachment'
|
||||
import Attachments from '../Upload/attachment';
|
||||
import QuillForEditor from '../quillForEditor';
|
||||
|
||||
const TextArea = Input.TextArea;
|
||||
const Option = Select.Option;
|
||||
|
||||
|
||||
const options = [
|
||||
['bold', 'italic', 'underline'],
|
||||
[{header: [1,2,3,false]}],
|
||||
['blockquote', 'code-block'],
|
||||
['link', 'image'],
|
||||
['formula']
|
||||
];
|
||||
class UpdateDetail extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
|
@ -100,6 +105,12 @@ class UpdateDetail extends Component{
|
|||
});
|
||||
};
|
||||
|
||||
onContentChange=(value)=>{
|
||||
this.setState({
|
||||
textcount:JSON.stringify(value)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
changmodelname=(e)=>{
|
||||
this.setState({
|
||||
|
|
@ -123,6 +134,61 @@ class UpdateDetail extends Component{
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 切换完成度
|
||||
changeRatio=(e)=>{
|
||||
if(e === 0){
|
||||
this.props.form.setFieldsValue({
|
||||
status_id:1
|
||||
})
|
||||
this.setState({
|
||||
status_id:1
|
||||
})
|
||||
}else if(e === 100){
|
||||
this.props.form.setFieldsValue({
|
||||
status_id:3
|
||||
})
|
||||
this.setState({
|
||||
status_id:3
|
||||
})
|
||||
}else{
|
||||
this.props.form.setFieldsValue({
|
||||
status_id:2
|
||||
})
|
||||
this.setState({
|
||||
status_id:2
|
||||
})
|
||||
}
|
||||
}
|
||||
// 切换状态
|
||||
changeStatus=(e)=>{
|
||||
// console.log(e);
|
||||
if(e === 1){
|
||||
this.props.form.setFieldsValue({
|
||||
done_ratio:0
|
||||
})
|
||||
this.setState({
|
||||
done_ratio:0
|
||||
})
|
||||
}else if(e === 3){
|
||||
this.props.form.setFieldsValue({
|
||||
done_ratio:100
|
||||
})
|
||||
this.setState({
|
||||
done_ratio:100
|
||||
})
|
||||
}
|
||||
}
|
||||
stringJson=(value) =>{
|
||||
let _value = null;
|
||||
|
||||
try {
|
||||
_value = JSON.parse(value);
|
||||
} catch (e) {
|
||||
_value = value;
|
||||
}
|
||||
return _value
|
||||
}
|
||||
// 获取上传后的文件id数组
|
||||
UploadFunc=(fileList)=>{
|
||||
this.setState({
|
||||
|
|
@ -133,7 +199,7 @@ class UpdateDetail extends Component{
|
|||
const { fileList } = this.state;
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId,orderId} = this.props.match.params;
|
||||
const { projectsId , orderId } = this.props.match.params;
|
||||
const { subject } = this.state;
|
||||
const url = `/projects/${projectsId}/issues/${orderId}.json`;
|
||||
|
||||
|
|
@ -145,16 +211,18 @@ class UpdateDetail extends Component{
|
|||
if(values.assigned_to_id===0){
|
||||
values.assigned_to_id = ""
|
||||
}
|
||||
const { textcount } = this.state;
|
||||
|
||||
axios.put(url,{
|
||||
project_id:projectsId,
|
||||
subject:subject,
|
||||
id: orderId,
|
||||
description:this.state.textcount,
|
||||
description:textcount,
|
||||
attachment_ids:fileList,
|
||||
...values
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.history.push(`/projects/${projectsId}/orders`);
|
||||
this.props.history.push(`/projects/${projectsId}/orders/${orderId}/detail`);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
|
|
@ -166,40 +234,48 @@ class UpdateDetail extends Component{
|
|||
|
||||
|
||||
render(){
|
||||
const { projectsId,orderId } = this.props.match.params;
|
||||
const { projectsId , orderId } = this.props.match.params;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const { current_user } = this.props;
|
||||
const { issue_tag_ids , fixed_version_id , branch_name , status_id , tracker_id , issue_type ,assigned_to_id , priority_id , done_ratio,
|
||||
issue_chosen , branches, subject, textcount,get_attachments } = this.state;
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
</div>
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state}/>*/}
|
||||
{/*</div>*/}
|
||||
<div>
|
||||
<Form>
|
||||
<div className="f-wrap-between mt20" style={{alignItems:"flex-start"}}>
|
||||
<div className="list-right df" >
|
||||
<Link to={``}><img class="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/></Link>
|
||||
<Link to={`/users/${current_user && current_user.login}/projects`} className="show-user-link">
|
||||
<img className="user_img" src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt=""/>
|
||||
</Link>
|
||||
<div className="new_context">
|
||||
<Form.Item>
|
||||
{getFieldDecorator('subject', {
|
||||
rules: [{
|
||||
required: true, message: '请填写工单标题'
|
||||
required: true, message: '请填写任务标题'
|
||||
}],
|
||||
initialValue: subject
|
||||
})(
|
||||
<Input placeholder="标题" onChange={this.changmodelname}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('description', {
|
||||
rules: [],
|
||||
initialValue: textcount
|
||||
})(
|
||||
<TextArea placeholder="请输入工单的描述..." style={{height:"300px"}} onChange={this.changmodelcount}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<div className="quillContent" style={{marginBottom:"20px"}}>
|
||||
<QuillForEditor
|
||||
value = {this.stringJson(textcount)}
|
||||
wrapStyle={{
|
||||
height: '220px',
|
||||
opacity:1,
|
||||
}}
|
||||
// autoFocus={true}
|
||||
style={{ height: '170px' }}
|
||||
placeholder="请输入任务的描述..."
|
||||
options={options}
|
||||
onContentChange={this.onContentChange}
|
||||
/>
|
||||
</div>
|
||||
<UploadComponent load={this.UploadFunc} showNotification={this.props.showNotification} isComplete={true}></UploadComponent>
|
||||
{
|
||||
get_attachments ?
|
||||
|
|
@ -213,7 +289,7 @@ class UpdateDetail extends Component{
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="list-left" style={{paddingRight:"0px",paddingLeft:"15px",paddingTop:"10px"}}>
|
||||
<div className="list-left mt10" style={{paddingRight:"0px",paddingLeft:"0px",width:"25%",backgroundColor:"#fff"}}>
|
||||
<div className="list-l-panel">
|
||||
<Form.Item
|
||||
label="分支"
|
||||
|
|
@ -242,7 +318,7 @@ class UpdateDetail extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>未选择标签</Option>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_tag.length > 0 ? '未选择标签':'请在仓库设置里添加标签'}</Option>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.issue_tag) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
@ -255,7 +331,7 @@ class UpdateDetail extends Component{
|
|||
rules: [],
|
||||
})(
|
||||
<Select>
|
||||
<Option value={''}>未选择里程碑</Option>
|
||||
<Option value={''}>{issue_chosen && issue_chosen.issue_version.length > 0 ? '未选择里程碑': '请添加里程碑'}</Option>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.issue_version) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
@ -269,7 +345,7 @@ class UpdateDetail extends Component{
|
|||
required: true, message: '请选择完成状态'
|
||||
}],
|
||||
})(
|
||||
<Select >
|
||||
<Select onChange={this.changeStatus}>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.issue_status) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
@ -324,7 +400,7 @@ class UpdateDetail extends Component{
|
|||
required: true, message: '请选择完成度'
|
||||
}],
|
||||
})(
|
||||
<Select value={done_ratio}>
|
||||
<Select value={done_ratio} onChange={this.changeRatio}>
|
||||
{ this.renderSelect(issue_chosen && issue_chosen.done_ratio) }
|
||||
</Select>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -109,14 +109,14 @@ class UpdateMilepost extends Component{
|
|||
return(
|
||||
<div className="main">
|
||||
<Form>
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state} />
|
||||
{/* <a onClick={this.newshow} className="topWrapper_btn" >新建里程碑</a> */}
|
||||
|
||||
</div>
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state} />*/}
|
||||
{/*/!* <a onClick={this.newshow} className="topWrapper_btn" >新建里程碑</a> *!/*/}
|
||||
|
||||
{/*</div>*/}
|
||||
<div style={{marginLeft:15, marginTop: 24}}>
|
||||
<h1 >编辑里程碑</h1>
|
||||
<h5 className="mt-5 color-grey-9">里程碑组织工单,合并请求和跟踪进度.</h5>
|
||||
<h5 className="mt-5 color-grey-9">里程碑可以组织任务和合并请求,并跟踪进度.</h5>
|
||||
</div>
|
||||
<Divider/>
|
||||
<div style={{display:'flex'}}>
|
||||
|
|
@ -140,7 +140,7 @@ class UpdateMilepost extends Component{
|
|||
required: true, message: '请输入描述内容'
|
||||
}],
|
||||
})(
|
||||
<TextArea placeholder="添加一个可选的扩展描述。。。" style={{height:"300px"}} />
|
||||
<TextArea placeholder="请输入描述内容..." style={{height:"150px"}} />
|
||||
|
||||
)}
|
||||
</Form.Item>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class NewMilepost extends Component{
|
|||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/versions`;
|
||||
const url = `/projects/${projectsId}/versions.json`;
|
||||
let time=undefined;
|
||||
if(this.state.selectedValue===undefined){
|
||||
|
||||
|
|
@ -77,14 +77,14 @@ class NewMilepost extends Component{
|
|||
return(
|
||||
<div className="main">
|
||||
<Form>
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state} />
|
||||
{/* <a onClick={this.newshow} className="topWrapper_btn" >新建里程碑</a> */}
|
||||
|
||||
</div>
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state} />*/}
|
||||
{/*/!* <a onClick={this.newshow} className="topWrapper_btn" >新建里程碑</a> *!/*/}
|
||||
|
||||
{/*</div>*/}
|
||||
<div style={{marginLeft:15, marginTop: 24}}>
|
||||
<h1 >新的里程碑</h1>
|
||||
<h5 className="mt-5 color-grey-9">里程碑组织工单,合并请求和跟踪进度.</h5>
|
||||
<h5 className="mt-5 color-grey-9">里程碑可以组织任务和合并请求,并跟踪进度.</h5>
|
||||
</div>
|
||||
<Divider/>
|
||||
<div style={{display:'flex'}}>
|
||||
|
|
@ -108,7 +108,7 @@ class NewMilepost extends Component{
|
|||
required: true, message: '请输入描述内容'
|
||||
}],
|
||||
})(
|
||||
<TextArea placeholder="添加一个可选的扩展描述。。。" style={{height:"300px"}}/>
|
||||
<TextArea placeholder="请输入描述内容..." style={{height:"150px"}}/>
|
||||
|
||||
)}
|
||||
</Form.Item>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,18 @@
|
|||
border-bottom: 1px solid #EEEEEE;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.quillContent{
|
||||
position: relative;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.quillFlag{
|
||||
position: absolute;
|
||||
bottom:0px;
|
||||
left:6px;
|
||||
height: 20px;
|
||||
line-height: 18px;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.topmilepost{
|
||||
padding: 20px 0;
|
||||
|
|
@ -152,6 +164,15 @@
|
|||
.topWrapper .ant-btn.ant-input-search-button{
|
||||
height: 30px;
|
||||
}
|
||||
.title_overflow{
|
||||
max-width: 220px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
display: inline-flex;
|
||||
white-space: nowrap;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.topWrapper_select li{
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
|
@ -168,6 +189,7 @@
|
|||
background: #f4f4f4;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.no-cursor li{cursor: default !important;}
|
||||
.ant-dropdown-menu .ant-dropdown-menu-item{
|
||||
text-align: center;
|
||||
padding:6px 30px;
|
||||
|
|
@ -177,11 +199,11 @@
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
border-bottom:1px dashed #f4f4f4;
|
||||
border-bottom:1px dashed #cecdcd;
|
||||
padding:16px 0px;
|
||||
}
|
||||
.issueItem:first-child{
|
||||
border-top:1px dashed #f4f4f4;
|
||||
border-top:1px dashed #cecdcd;
|
||||
}
|
||||
.issueNo{
|
||||
padding:0px 5px;
|
||||
|
|
@ -193,6 +215,10 @@
|
|||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.issueOpen{
|
||||
background: #21ba45 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.margin_detail{
|
||||
margin-left: 15px;
|
||||
|
|
@ -245,7 +271,7 @@
|
|||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/*编辑工单*/
|
||||
/*编辑任务*/
|
||||
.editingsheet{
|
||||
background: #ffffff;
|
||||
color: #21ba45!important;
|
||||
|
|
@ -340,7 +366,7 @@
|
|||
top: 14px;
|
||||
right: 100%;
|
||||
}
|
||||
/* 工单标签列表 */
|
||||
/* 任务标签列表 */
|
||||
.tagList > div{
|
||||
border-bottom: 1px dashed #f4f4f4;
|
||||
display: flex;
|
||||
|
|
@ -354,9 +380,6 @@
|
|||
width: 80%;
|
||||
padding-left: 80px;
|
||||
}
|
||||
.detail_ptitlecount{
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.tagList > div:last-child{
|
||||
border-bottom: none;
|
||||
|
|
@ -415,7 +438,7 @@
|
|||
padding: 15px;
|
||||
width: 30%;
|
||||
}
|
||||
/* 工单详情 */
|
||||
/* 任务详情 */
|
||||
.detailContent{
|
||||
padding:15px 0px;
|
||||
border-bottom: 1px solid #f4f4f4;
|
||||
|
|
@ -435,6 +458,21 @@
|
|||
.inputcount{
|
||||
width: 40%;
|
||||
}
|
||||
.loginDiv{
|
||||
border: 1px solid #f7c977;
|
||||
background: rgb(255, 204, 113,0.3);
|
||||
text-align: center;
|
||||
padding:8px 0px;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
color: #999;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.loginDiv a{
|
||||
text-decoration: underline;
|
||||
color: #4CACFF;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.tagdiv{
|
||||
padding: 15px;
|
||||
|
|
@ -455,6 +493,7 @@
|
|||
flex-wrap: wrap;
|
||||
}
|
||||
.issue-tag-show{padding: 3px 8px; color: #fff; border-radius: 6px;}
|
||||
.journal-list-item{padding: 12px 15px}
|
||||
|
||||
/*.DetailRight > p >span:nth-child(1){*/
|
||||
/*min-width: 90px;*/
|
||||
|
|
@ -479,7 +518,7 @@ a.issue-type-button.active:hover{background: #f4f4f4; color: #4CACFF;}
|
|||
.ml10{margin-left: 10px;}
|
||||
.lineH32{line-height: 32px;}
|
||||
.lineH40{line-height: 40px;}
|
||||
.item-list-right{width: 74%; padding: 10px 15px 10px 0}
|
||||
.item-list-right{width: 74%; padding: 0px 15px 10px 0}
|
||||
.detail_edit_action{padding:10px; color: #999; cursor: pointer; line-height: 40px;}
|
||||
.attachmentsList{
|
||||
margin-left:4px;
|
||||
|
|
@ -491,4 +530,26 @@ a.issue-type-button.active:hover{background: #f4f4f4; color: #4CACFF;}
|
|||
.attachment-list-a{color: rgba(0, 0, 0, 0.65) !important;}
|
||||
.btp1{border-top: 1px solid #f4f4f4;}
|
||||
.grid-item{display: grid; align-items: center; grid-template-columns: max-content 1fr;}
|
||||
.fwb{font-weight: bold;}
|
||||
.fwb{font-weight: bold;}
|
||||
|
||||
/* 发布人、指派人数量过多时要出现滚动条 */
|
||||
.ant-dropdown-menu{
|
||||
max-height: 350px;
|
||||
overflow-y:auto;
|
||||
}
|
||||
.ql-bubble .ql-editor img{
|
||||
min-width:100px!important;
|
||||
}
|
||||
.AmplifyImg .ant-modal{
|
||||
padding:0px;
|
||||
}
|
||||
.AmplifyImg img{
|
||||
max-width: 100%;
|
||||
margin: 0px auto;
|
||||
}
|
||||
.AmplifyImg .ant-modal-body{
|
||||
padding:25px;
|
||||
}
|
||||
.amplifyContent{
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -1,13 +1,12 @@
|
|||
import React , { Component } from "react";
|
||||
import {Link} from 'react-router-dom';
|
||||
import { Input ,Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
|
||||
import { Input ,Dropdown , Menu , Icon , Pagination , Spin, Button } from 'antd';
|
||||
import './order.css';
|
||||
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import NoneData from '../Nodata';
|
||||
import Nav from './Nav';
|
||||
import OrderItem from './OrderItem';
|
||||
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
const Search = Input.Search;
|
||||
|
|
@ -57,7 +56,7 @@ class order extends Component{
|
|||
|
||||
componentDidMount=()=>{
|
||||
this.getSelectList();
|
||||
this.getIssueList();
|
||||
this.getIssueList("","","","","","1","","","","");
|
||||
}
|
||||
|
||||
getSelectList=()=>{
|
||||
|
|
@ -217,13 +216,14 @@ class order extends Component{
|
|||
|
||||
openorder=(type)=>{
|
||||
if(type){
|
||||
|
||||
console.log(this.state.closeselect+"|"+this.state.openselect)
|
||||
const { current_user } = this.props;
|
||||
if(type===1){
|
||||
this.setState({
|
||||
status_type:'1',
|
||||
openselect:current_user.user_id,
|
||||
closeselect:undefined,
|
||||
openselect:1,
|
||||
|
||||
issue_tag_ids:'标签',
|
||||
tracker_ids:'所有分类',
|
||||
author_ids:'发布人',
|
||||
|
|
@ -238,7 +238,8 @@ class order extends Component{
|
|||
this.setState({
|
||||
status_type:'2',
|
||||
openselect:undefined,
|
||||
closeselect:current_user.user_id,
|
||||
closeselect:1,
|
||||
|
||||
issue_tag_ids:'标签',
|
||||
tracker_ids:'所有分类',
|
||||
author_ids:'发布人',
|
||||
|
|
@ -257,11 +258,20 @@ class order extends Component{
|
|||
// 筛选:全部、指派给我、由我创建
|
||||
ChangeAssign=(type)=>{
|
||||
const { limit, search,status_type} = this.state;
|
||||
const { current_user } = this.props;
|
||||
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
console.log(current_user)
|
||||
|
||||
if(type){
|
||||
const { current_user } = this.props;
|
||||
if(current_user===undefined){
|
||||
this.setState({
|
||||
isSpin:false
|
||||
})
|
||||
return;
|
||||
}
|
||||
if(type===1){
|
||||
this.setState({
|
||||
page:1,
|
||||
|
|
@ -308,8 +318,36 @@ class order extends Component{
|
|||
this.getIssueList(1,limit,search,undefined,undefined,status_type);
|
||||
}
|
||||
}
|
||||
deletedetail=(id)=>{
|
||||
const { projectsId} = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issues/${id}.json`;
|
||||
axios.delete(url,{ data: {
|
||||
project_id: projectsId,
|
||||
id:id
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
this.getIssueList()
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
console.log(id)
|
||||
}
|
||||
|
||||
islogin(){
|
||||
const { projectsId } = this.props.match.params;
|
||||
if (this.props.checkIfLogin() === false) {
|
||||
this.props.showLoginDialog()
|
||||
return
|
||||
}else{
|
||||
this.props.history.push(`/projects/${projectsId}/orders/new`);
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
const { current_user } = this.props;
|
||||
|
||||
const { issue_chosen , issues , limit , page , search_count , data , assigned_to_id , author_id , isSpin,openselect,closeselect } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
|
|
@ -334,15 +372,13 @@ class order extends Component{
|
|||
)
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="topWrapper">
|
||||
<Nav {...this.props} {...this.state}/>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<Link to={`/projects/${projectsId}/orders/new`} className="topWrapper_btn">创建工单</Link>
|
||||
: ''
|
||||
}
|
||||
{/*<div className="topWrapper">*/}
|
||||
{/*<Nav {...this.props} {...this.state}/>*/}
|
||||
{/*{*/}
|
||||
{/*<a className="topWrapper_btn" onClick={()=>this.islogin()} >创建任务</a>*/}
|
||||
{/*}*/}
|
||||
|
||||
</div>
|
||||
{/*</div>*/}
|
||||
|
||||
<div className="topWrapper" style={{borderBottom:"none"}}>
|
||||
<p className="topWrapper_type">
|
||||
|
|
@ -351,21 +387,27 @@ class order extends Component{
|
|||
{/* <span onClick={this.openorder} className={author_id ? "active":""}>{data && data.open_count}个开启中</span>
|
||||
<span onClick={this.closeorder} className={author_id ? "active":""}>{data && data.close_count}个已关闭</span> */}
|
||||
</p>
|
||||
<div className="target-detail-search">
|
||||
<Search
|
||||
placeholder="搜索"
|
||||
enterButton
|
||||
onSearch={this.searchFunc}
|
||||
style={{ width: 300 }}
|
||||
/>
|
||||
|
||||
<div className="topWrapper_select">
|
||||
<div className="target-detail-search">
|
||||
<Search
|
||||
placeholder="搜索"
|
||||
enterButton
|
||||
onSearch={this.searchFunc}
|
||||
style={{ width: 300 }}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<a className="topWrapper_btn ml10" onClick={()=>this.islogin()} >创建任务</a>
|
||||
</div>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="f-wrap-between mb20">
|
||||
<ul className="topWrapper_type">
|
||||
<li className={!author_id && !assigned_to_id ? "active":""} onClick={()=>this.ChangeAssign()}>全部</li>
|
||||
<li className={assigned_to_id ? "active":""} onClick={()=>this.ChangeAssign(1)}>指派给我</li>
|
||||
<li className={author_id ? "active":""} onClick={()=>this.ChangeAssign(2)}>由我创建</li>
|
||||
{}
|
||||
<li style={{display:current_user&¤t_user.login===""?'none':'flex'}} className={assigned_to_id ? "active":""} onClick={ ()=>this.ChangeAssign(1)}>指派给我</li>
|
||||
<li style={{display:current_user&¤t_user.login===""?'none':'flex'}} className={author_id ? "active":""} onClick={()=>this.ChangeAssign(2)}>由我创建</li>
|
||||
{/* <li>@我的</li> */}
|
||||
</ul>
|
||||
<ul className="topWrapper_select">
|
||||
|
|
@ -413,11 +455,12 @@ class order extends Component{
|
|||
</div>
|
||||
{
|
||||
search_count === 0 ?
|
||||
<NoneData></NoneData>
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
:
|
||||
<OrderItem issues={issues} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state}></OrderItem>
|
||||
<OrderItem issues={issues} search_count={search_count} page={page} limit={limit} {...this.props} {...this.state} deletedetail={this.deletedetail}></OrderItem>
|
||||
}
|
||||
{ Paginations }
|
||||
|
||||
</Spin>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React , { Component } from 'react';
|
|||
import { Link } from 'react-router-dom';
|
||||
import { Input , AutoComplete , Dropdown , Menu , Icon , Spin , Pagination } from 'antd';
|
||||
import axios from 'axios';
|
||||
import { getImageUrl } from 'educoder';
|
||||
|
||||
const { Option } = AutoComplete;
|
||||
const MENU_LIST = [{
|
||||
|
|
@ -9,10 +10,10 @@ const MENU_LIST = [{
|
|||
name:'管理员'
|
||||
},{
|
||||
id:"Developer",
|
||||
name:'开发人员'
|
||||
name:'可写权限'
|
||||
},{
|
||||
id:"Reporter",
|
||||
name:'报告人员'
|
||||
name:'可读权限'
|
||||
}];
|
||||
const LIMIT = 15;
|
||||
class Collaborator extends Component{
|
||||
|
|
@ -25,7 +26,8 @@ class Collaborator extends Component{
|
|||
userDataSource:undefined,
|
||||
page:1,
|
||||
total_count:undefined,
|
||||
isSpin:true
|
||||
isSpin:true,
|
||||
searchKey: undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,14 +66,18 @@ class Collaborator extends Component{
|
|||
}
|
||||
// 输入用户
|
||||
changeInputUser=(e)=>{
|
||||
this.setState({
|
||||
searchKey: e
|
||||
})
|
||||
this.getUserList(e);
|
||||
}
|
||||
// 选择用户
|
||||
selectInputUser=(e,option)=>{
|
||||
this.setState({
|
||||
user_id:e
|
||||
user_id:e,
|
||||
searchKey: option.props.searchValue
|
||||
})
|
||||
this.getUserList(option.props.children);
|
||||
this.getUserList(option.props.searchValue);
|
||||
}
|
||||
getUserList=(e)=>{
|
||||
const url = `/users/list.json`;
|
||||
|
|
@ -140,8 +146,9 @@ class Collaborator extends Component{
|
|||
onOk:()=>{
|
||||
const { project_id } = this.props;
|
||||
const url = `/projects/${project_id}/members/remove.json`;
|
||||
axios.delete(url,{
|
||||
user_id:id
|
||||
axios.delete(url,{ data: {
|
||||
user_id:id
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
|
|
@ -164,7 +171,7 @@ class Collaborator extends Component{
|
|||
this.getMember(project_id,page);
|
||||
}
|
||||
render(){
|
||||
const { userDataSource , listData , isSpin , page , total_count } = this.state;
|
||||
const { userDataSource , listData , isSpin , page , total_count,searchKey } = this.state;
|
||||
// 获取当前项目的拥有者
|
||||
const { author } = this.props;
|
||||
const menu =(id)=> (
|
||||
|
|
@ -181,7 +188,13 @@ class Collaborator extends Component{
|
|||
|
||||
const source = userDataSource && userDataSource.map((item,key)=>{
|
||||
return(
|
||||
<Option key={key} value={`${item.user_id}`}>{item.username}</Option>
|
||||
<Option key={key} value={`${item.user_id}`} searchValue={`${item.username}`}>
|
||||
<img className="user_img radius" width="28" height="28" src={getImageUrl(`images/${item && item.image_url}`)} alt=""/>
|
||||
<span className="ml10" style={{'vertical-align':'middle'}}>
|
||||
{item.username}
|
||||
<span className="color-grey ml10">({item.login})</span>
|
||||
</span>
|
||||
</Option>
|
||||
)
|
||||
})
|
||||
return(
|
||||
|
|
@ -190,6 +203,17 @@ class Collaborator extends Component{
|
|||
<div className="normalBox-title font-16">
|
||||
协作者
|
||||
</div>
|
||||
<div className="addPanel">
|
||||
<AutoComplete
|
||||
dataSource={source}
|
||||
value={searchKey}
|
||||
style={{ width: 300 }}
|
||||
onChange={this.changeInputUser}
|
||||
onSelect={this.selectInputUser}
|
||||
placeholder="用户名或邮箱搜索..."
|
||||
/>
|
||||
<a className="small_submitBtn ml20" onClick={this.addCollaborator}>增加协作者</a>
|
||||
</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="collaboratorList">
|
||||
{
|
||||
|
|
@ -197,7 +221,16 @@ class Collaborator extends Component{
|
|||
const operation = MENU_LIST.filter(i=>i.id === item.role);
|
||||
return(
|
||||
<div className="collaboratorItem">
|
||||
<span><Link to={``} className="color-blue">{item.name}</Link></span>
|
||||
<span>
|
||||
<Link to={`/users/${item && item.login}/projects`} className="show-user-link">
|
||||
<img className="user_img radius" width="28" height="28" src={getImageUrl(`images/${item && item.image_url}`)} alt=""/>
|
||||
<span className="ml10" style={{'vertical-align':'middle'}}>
|
||||
{item.name}
|
||||
<span className="color-grey ml10">({item.login})</span>
|
||||
</span>
|
||||
|
||||
</Link>
|
||||
</span>
|
||||
<span>
|
||||
{
|
||||
author && author.login === item.login ?
|
||||
|
|
@ -207,7 +240,7 @@ class Collaborator extends Component{
|
|||
<span>{operation && operation[0].name}<Icon type="down" /></span>
|
||||
</Dropdown>
|
||||
}
|
||||
|
||||
|
||||
</span>
|
||||
<span style={{justifyContent:"center"}}>
|
||||
{
|
||||
|
|
@ -219,20 +252,11 @@ class Collaborator extends Component{
|
|||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</Spin>
|
||||
<div className="addPanel">
|
||||
<AutoComplete
|
||||
dataSource={source}
|
||||
style={{ width: 200 }}
|
||||
onChange={this.changeInputUser}
|
||||
onSelect={this.selectInputUser}
|
||||
placeholder="搜索用户"
|
||||
/>
|
||||
<a className="small_submitBtn ml20" onClick={this.addCollaborator}>增加协作者</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{
|
||||
total_count && total_count > LIMIT ?
|
||||
|
|
@ -245,4 +269,4 @@ class Collaborator extends Component{
|
|||
)
|
||||
}
|
||||
}
|
||||
export default Collaborator;
|
||||
export default Collaborator;
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ const Collaborator = Loadable({
|
|||
loader: () => import('./Collaborator'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Tags = Loadable({
|
||||
loader: () => import('./new_tags'),
|
||||
loading: Loading,
|
||||
})
|
||||
class Index extends Component{
|
||||
render(){
|
||||
const { projectsId } = this.props.match.params;
|
||||
console.log(this.props);
|
||||
const { pathname } = this.props.history.location;
|
||||
|
||||
const flag = (pathname === `/projects/${projectsId}/setting`);
|
||||
|
|
@ -31,16 +34,11 @@ class Index extends Component{
|
|||
<ul className="settingNav">
|
||||
<li className={flag?"active":""}><Link to={`/projects/${projectsId}/setting`}>仓库</Link></li>
|
||||
<li className={pathname.indexOf('setting/collaborator')>-1?"active":""}><Link to={`/projects/${projectsId}/setting/collaborator`}>协作者</Link></li>
|
||||
<li className={pathname.indexOf('setting/tags')>-1?"active":""}><Link to={`/projects/${projectsId}/setting/tags`}>项目标签</Link></li>
|
||||
{/* <li className={pathname.indexOf('setting/branch')>-1?"active":""}><Link to={`/projects/${projectsId}/setting/branch`}>分支列表</Link></li> */}
|
||||
</ul>
|
||||
<div className="main">
|
||||
<Switch {...this.props}>
|
||||
{/* 分支列表 */}
|
||||
{/* <Route path="/projects/:projectsId/setting/branch"
|
||||
render={
|
||||
(props) => (<Branch {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route> */}
|
||||
{/* 协作者 */}
|
||||
<Route path="/projects/:projectsId/setting/collaborator"
|
||||
render={
|
||||
|
|
@ -48,11 +46,18 @@ class Index extends Component{
|
|||
}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
<Route path="/projects/:projectsId/setting/tags"
|
||||
render={
|
||||
(props) => (<Tags {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* 修改仓库信息 */}
|
||||
<Route path="/projects/:projectsId/setting"
|
||||
render={
|
||||
(props) => (<Setting {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -32,9 +32,8 @@ class Setting extends Component{
|
|||
}
|
||||
|
||||
getInfo=()=>{
|
||||
const { current_user } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/${current_user.login}/${projectsId}/edit.json`;
|
||||
const url = `/repositories/${projectsId}/edit.json`;
|
||||
axios.get(url).then(result=>{
|
||||
if(result){
|
||||
this.props.form.setFieldsValue({
|
||||
|
|
@ -200,7 +199,7 @@ class Setting extends Component{
|
|||
<div className="flex-a-center padding15-10">
|
||||
<div>
|
||||
<p className="font-bd font-16">删除本仓库</p>
|
||||
<p className="mt10">删除仓库是永久性的, 无法撤消</p>
|
||||
<p className="mt10">删除仓库是永久性的, 无法撤消,且删除后,与仓库关联的项目/任务/合并请求/版本发布等,均会被删除</p>
|
||||
</div>
|
||||
<a onClick={this.deleteProject} className="red_deleteBtn">删除本仓库</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,434 @@
|
|||
import React , {Component} from 'react';
|
||||
import { Dropdown , Icon , Menu , Pagination, Modal,Input,Popconfirm,Form } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import '../Order/order.css'
|
||||
import NoneData from '../Nodata';
|
||||
import { SketchPicker } from 'react-color'
|
||||
import reactCSS from 'reactcss'
|
||||
import axios from 'axios';
|
||||
class NewTags extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
data:undefined,
|
||||
limit:15,
|
||||
page:1,
|
||||
order_name:undefined,
|
||||
order_type:undefined,
|
||||
//新建标签区域是否显示 none 隐藏 block 显示
|
||||
display:'none',
|
||||
//调色盘颜色
|
||||
displayColorPicker: false,
|
||||
color: {
|
||||
r: '241',
|
||||
g: '112',
|
||||
b: '19',
|
||||
a: '1',
|
||||
},
|
||||
textcolor:'#F17013',
|
||||
isShow:false,
|
||||
newcolor:'',
|
||||
name:'',
|
||||
description:'',
|
||||
id:'',
|
||||
modelname:''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
this.getList();
|
||||
}
|
||||
|
||||
|
||||
getList=(page,order_name,order_type)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { limit } = this.state;
|
||||
const url = `/projects/${projectsId}/issue_tags.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
page,limit,order_name,order_type
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
data:result.data
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
createtagpost=()=>{
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
project_id:projectsId,
|
||||
color:this.state.textcolor
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.form.setFieldsValue({
|
||||
name: "",
|
||||
description: ""
|
||||
});
|
||||
this.setState({
|
||||
color: {
|
||||
r: '241',
|
||||
g: '112',
|
||||
b: '19',
|
||||
a: '1',
|
||||
},
|
||||
textcolor:'#F17013',
|
||||
display:'none'
|
||||
});
|
||||
this.getList()
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ChangePage=(page)=>{
|
||||
this.setState({
|
||||
page
|
||||
})
|
||||
|
||||
this.getList(page);
|
||||
}
|
||||
|
||||
// 排序
|
||||
arrayList=(e)=>{
|
||||
this.setState({
|
||||
order_name:e.key,
|
||||
order_type:e.item.props.value
|
||||
})
|
||||
|
||||
this.getList(1,e.key,e.item.props.value);
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.setState({ displayColorPicker: !this.state.displayColorPicker })
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({ displayColorPicker: false })
|
||||
};
|
||||
|
||||
handleChange = (color) => {
|
||||
this.setState({
|
||||
color: color.rgb,
|
||||
textcolor:color.hex,
|
||||
newcolor:color.hex,
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
|
||||
//控制新建标签页是否显示
|
||||
newshow=()=>{
|
||||
this.setState({
|
||||
display:'block'
|
||||
});
|
||||
|
||||
};
|
||||
newclose=()=>{
|
||||
this.setState({
|
||||
display:'none'
|
||||
});
|
||||
};
|
||||
|
||||
handleok=()=>{
|
||||
this.updatetag();
|
||||
}
|
||||
updatetag=()=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
let id=this.state.id;
|
||||
const url = `/projects/${projectsId}/issue_tags/${id}.json`;
|
||||
let name=this.state.name;
|
||||
let description=this.state.description;
|
||||
let modalcolor=this.state.newcolor
|
||||
axios.put(url,{
|
||||
project_id:projectsId,
|
||||
id:id,
|
||||
name:name,
|
||||
description:description,
|
||||
color:modalcolor
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
isShow:false
|
||||
});
|
||||
this.getList()
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
deletetag=(id)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags/${id}.json`;
|
||||
axios.delete(url,{ data: {
|
||||
project_id: projectsId,
|
||||
id: id
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
this.getList()
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
handleCancel=()=>{
|
||||
this.setState({
|
||||
isShow:false
|
||||
});
|
||||
}
|
||||
|
||||
changmodelname=(e)=>{
|
||||
this.setState({
|
||||
name:e.target.value
|
||||
})
|
||||
}
|
||||
changdescription=(e)=>{
|
||||
this.setState({
|
||||
description:e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
editshow=(arr)=>{
|
||||
this.setState({
|
||||
isShow:true,
|
||||
newcolor:arr.color,
|
||||
name:arr.name,
|
||||
description:arr.description,
|
||||
id:arr.id
|
||||
});
|
||||
};
|
||||
|
||||
render(){
|
||||
const { data , limit , page } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={this.arrayList}>
|
||||
<Menu.Item key={'created_at'} value="desc">按创建时间降序排序</Menu.Item>
|
||||
<Menu.Item key={'created_at'} value="asc">按创建时间升序排序</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="desc">按issue个数降序排序</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="asc">按issue个数升序排序</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
const styles = reactCSS({
|
||||
'default': {
|
||||
color: {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
borderRadius: '2px',
|
||||
background: `rgba(${ this.state.color.r }, ${ this.state.color.g }, ${ this.state.color.b }, ${ this.state.color.a })`,
|
||||
},
|
||||
swatch: {
|
||||
padding: '5px',
|
||||
background: '#fff',
|
||||
borderRadius: '1px',
|
||||
width:'100px',
|
||||
marginTop:'5px',
|
||||
height:'28px',
|
||||
boxShadow: '0 0 0 1px rgba(0,0,0,.1)',
|
||||
display: 'flex',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
popover: {
|
||||
position: 'absolute',
|
||||
zIndex: '2',
|
||||
},
|
||||
cover: {
|
||||
position: 'fixed',
|
||||
top: '0px',
|
||||
right: '0px',
|
||||
bottom: '0px',
|
||||
left: '0px',
|
||||
},
|
||||
modalcolor:{
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
borderRadius: '2px',
|
||||
background: this.state.newcolor,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
{
|
||||
data && data.issue_tags_count > limit ?
|
||||
<div className="mt30 mb50 edu-txt-center">
|
||||
<Pagination simple defaultCurrent={page} total={data && data.issue_tags_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>:""
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
const renderList =()=>{
|
||||
if(data && data.issue_tags && data.issue_tags.length>0 ){
|
||||
return(
|
||||
<div>
|
||||
<div className="topWrapper">
|
||||
<span>共{ data && data.issue_tags_count }个标签</span>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>标签<Icon type="caret-down" className="ml5" /></span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="tagList">
|
||||
{
|
||||
data.issue_tags.map((item,key)=>{
|
||||
return(
|
||||
<div>
|
||||
<span className="width20 mr10">
|
||||
<span style={{backgroundColor:`${item.color}`}} className="tagColor"></span>
|
||||
{item.name}
|
||||
</span>
|
||||
<span className="hide-1 width50 mr10">{item.description}</span>
|
||||
<span className="width15 mr10">{item.issues_count}个开启的任务</span>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="width15 text-right">
|
||||
<a onClick={()=>this.editshow(item)} className="topWrapper_btn fr" >编辑</a>
|
||||
<Popconfirm placement="bottom" title={'删除标签会将其从所有引用中删除。继续?'} okText="是" cancelText="否" onConfirm={()=>this.deletetag(item.id)}>
|
||||
<a className="a_btn delete_btn fr" >删除</a>
|
||||
</Popconfirm>
|
||||
|
||||
</div>
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="main">
|
||||
<div className="normalBox">
|
||||
<div className="normalBox-title font-16 topWrapper_select" style={{"justify-content":"space-between"}}>
|
||||
<span className="topWrapper_select">项目标签</span>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<div className="topWrapper_select">
|
||||
<a onClick={this.newshow} className="topWrapper_btn" >创建标签</a>
|
||||
</div>
|
||||
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
<div style={{display: this.state.display}} className="padding15">
|
||||
<Form>
|
||||
<div className="tagdiv" >
|
||||
<Form.Item
|
||||
className="inptwidth"
|
||||
>
|
||||
{getFieldDecorator('name', {
|
||||
rules: [{
|
||||
required: true, message: '请填写标签名字'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="标签名字" maxLength="10"/>
|
||||
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
className="inputcount"
|
||||
>
|
||||
{getFieldDecorator('description', {
|
||||
rules: [{
|
||||
required: true, message: '描述不能为空'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="描述, 30字以内" maxLength="30"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
|
||||
<div>
|
||||
<div style={ styles.swatch } onClick={ this.handleClick }>
|
||||
<div style={ styles.color }>
|
||||
<p style={{paddingLeft:25}}>{this.state.textcolor}</p>
|
||||
</div>
|
||||
</div>
|
||||
{ this.state.displayColorPicker ? <div style={ styles.popover }>
|
||||
<div style={ styles.cover } onClick={ this.handleClose }/>
|
||||
<SketchPicker color={ this.state.color } onChange={ this.handleChange } />
|
||||
</div> :
|
||||
null }
|
||||
</div>
|
||||
<div className="fr" style={{marginTop:5}}>
|
||||
<a onClick={this.createtagpost} className="topWrapper_btn fr" >创建标签</a>
|
||||
<a onClick={this.newclose} className="a_btn cancel_btn fr" >取消</a>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
||||
|
||||
</div>
|
||||
<div className="padding15">
|
||||
{ renderList() }
|
||||
{ Paginations }
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<Modal
|
||||
title="编辑标签"
|
||||
onCancel={this.handleCancel}
|
||||
visible={this.state.isShow}
|
||||
onOk={this.handleok}
|
||||
mask={true}
|
||||
width="60%"
|
||||
>
|
||||
<div className="dialogdiv">
|
||||
<Input placeholder="标签名字" maxLength="10" className="inptwidth" value={this.state.name} onChange={this.changmodelname}/>
|
||||
<Input placeholder="描述, 30字以内" maxLength="30" className="inputcount" value={this.state.description} onChange={this.changdescription}/>
|
||||
<div>
|
||||
<div style={ styles.swatch } onClick={ this.handleClick }>
|
||||
<div style={ styles.modalcolor }>
|
||||
<p style={{paddingLeft:25,width:100}}>{this.state.newcolor}</p>
|
||||
</div>
|
||||
</div>
|
||||
{ this.state.displayColorPicker ? <div style={ styles.popover }>
|
||||
<div style={ styles.cover } onClick={ this.handleClose }/>
|
||||
<SketchPicker color={ this.state.color } onChange={ this.handleChange } />
|
||||
</div> :
|
||||
null }
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
const WrappedTags = Form.create({ name: 'tageFrom' })(NewTags);
|
||||
export default WrappedTags;
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
}
|
||||
.collaboratorItem{
|
||||
display: flex;
|
||||
border-bottom: 1px solid #f4f4f4;
|
||||
border-top: 1px solid #f4f4f4;
|
||||
padding:15px;
|
||||
}
|
||||
.collaboratorItem>span{
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class Attachment extends Component{
|
|||
attachments.map((item,key)=>{
|
||||
return(
|
||||
<div key= {key} style={{display: (Deleted.length > 0 && Deleted.indexOf(item.id) !== -1) ? "none" : "block"}} className="mt10 attachment-list-div" >
|
||||
<Link to={`${item.url}`} className="attachment-list-a">
|
||||
<Link to={`${item.url}`} target="_blank" className="attachment-list-a">
|
||||
<i className="iconfont icon-fujian mr8 paper-clip-color font-12"></i>
|
||||
<span>{item.title}</span>
|
||||
<span className="ml20">{item.filesize}</span>
|
||||
|
|
|
|||
|
|
@ -142,10 +142,10 @@ class NewVersion extends Component{
|
|||
<div className="main">
|
||||
<Form>
|
||||
<h1 style={{marginLeft:15,marginTop:20}}>发布新版</h1>
|
||||
<h5 style={{marginLeft:15}}>版本发布组织项目的版本。</h5>
|
||||
<h5 style={{marginLeft:15}}>发布一个特定的打包好的项目版本</h5>
|
||||
<Divider/>
|
||||
<div style={{display:'flex'}}>
|
||||
<Input placeholder="标签名称" style={{width:180,marginLeft:15}} value={tag_name} onChange={this.changmodelname}/>
|
||||
<Input placeholder="标签名称" style={{width:180,marginLeft:15}} value={tag_name} onChange={this.changmodelname} />
|
||||
<div style={{marginLeft:20,marginRight:20,lineHeight: '32px'}}>@ </div>
|
||||
<Dropdown overlay={this.renderMenu(branches &&branches,'pull')} trigger={['click']} placement="bottomCenter">
|
||||
<Button style={{width:180}}>{pull}</Button>
|
||||
|
|
@ -161,7 +161,7 @@ class NewVersion extends Component{
|
|||
required: true, message: '请输入标题'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="标题"/>
|
||||
<Input placeholder="标题" maxLength="32"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
|
@ -172,7 +172,7 @@ class NewVersion extends Component{
|
|||
required: true, message: '请输入描述内容'
|
||||
}],
|
||||
})(
|
||||
<TextArea placeholder="添加描述内容..." style={{height:"300px"}}/>
|
||||
<TextArea placeholder="添加描述内容..." style={{'min-height':"150px"}}/>
|
||||
|
||||
)}
|
||||
</Form.Item>
|
||||
|
|
@ -181,9 +181,8 @@ class NewVersion extends Component{
|
|||
</div>
|
||||
|
||||
<Divider/>
|
||||
<div className="fr">
|
||||
<Checkbox onChange={this.RedieonChange}>标记为预行版</Checkbox>
|
||||
<p>标记此版本不适合生产使用</p>
|
||||
<div className="fr mb15">
|
||||
<Checkbox onChange={this.RedieonChange}>标记为预行版<span className="ml15 color-grey-9 font-13">(此版本不适合生产使用)</span></Checkbox>
|
||||
</div>
|
||||
<div className="clearfix mt15" style={{marginTop:5}} >
|
||||
<a className='topWrapper_btn_close fr' onClick={()=>this.handleSubmit(true)} style={{marginLeft:15}} >保存草稿</a> <a className='topWrapper_btn fr' onClick={()=>this.handleSubmit(false)} style={{marginRight:15}}>发布版本</a>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class NewVersion extends Component{
|
|||
|
||||
//delete
|
||||
deleteversion=()=>{
|
||||
const { projectsId , versionId} = this.props.match.params;
|
||||
const { projectsId , versionId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/version_releases/${versionId}.json`;
|
||||
axios.delete(url,{ data: {
|
||||
project_id: projectsId,
|
||||
|
|
@ -68,7 +68,7 @@ class NewVersion extends Component{
|
|||
handleSubmit=()=>{
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
const { projectsId,versionId} = this.props.match.params;
|
||||
const { projectsId , versionId } = this.props.match.params;
|
||||
const { pull,ischeck } = this.state;
|
||||
const url = `/projects/${projectsId}/version_releases/${versionId}.json`;
|
||||
// if(values.issue_type==="普通"){
|
||||
|
|
@ -134,8 +134,8 @@ class NewVersion extends Component{
|
|||
return(
|
||||
<div className="main">
|
||||
<Form>
|
||||
<h1 style={{marginLeft:15,marginTop:20}}>发布新版</h1>
|
||||
<h5 style={{marginLeft:15}}>版本发布组织项目的版本。</h5>
|
||||
<h1 style={{marginLeft:15,marginTop:20}}>编辑版本</h1>
|
||||
<h5 style={{marginLeft:15}}>编辑这个特定的打包好的项目版本</h5>
|
||||
<Divider/>
|
||||
<div style={{display:'flex',marginLeft:15}}>
|
||||
{this.state.data&&this.state.data.tag_name}@{this.state.data&&this.state.data.target_commitish}
|
||||
|
|
@ -152,7 +152,7 @@ class NewVersion extends Component{
|
|||
initialValue:this.state.data&&this.state.data.name
|
||||
|
||||
})(
|
||||
<Input placeholder="标题"/>
|
||||
<Input placeholder="标题" maxLength="32"/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
|
@ -164,7 +164,7 @@ class NewVersion extends Component{
|
|||
}],
|
||||
initialValue:this.state.data&&this.state.data.body
|
||||
})(
|
||||
<TextArea placeholder="添加一个可选的扩展描述。。。" style={{height:"300px"}}/>
|
||||
<TextArea placeholder="添加描述内容..." style={{'min-height':"150px"}}/>
|
||||
|
||||
)}
|
||||
</Form.Item>
|
||||
|
|
@ -173,14 +173,13 @@ class NewVersion extends Component{
|
|||
</div>
|
||||
|
||||
<Divider/>
|
||||
<div className="fr">
|
||||
<Checkbox onChange={this.RedieonChange}>标记为预行版</Checkbox>
|
||||
<p>标记此版本不适合生产使用</p>
|
||||
<div style={{textAlign:"right"}}>
|
||||
<Checkbox onChange={this.RedieonChange}>标记为预行版<span className="ml15 color-grey-9 font-13">(此版本不适合生产使用)</span></Checkbox>
|
||||
</div>
|
||||
<div className="clearfix mt15" style={{marginTop:5}} >
|
||||
<a className='topWrapper_btn_delete fr' onClick={()=>this.deleteversion()} style={{marginLeft:15}}>删除发布</a>
|
||||
<a className='topWrapper_btn fr' onClick={()=>this.handleSubmit()} style={{marginRight:15}}>编辑发布信息</a>
|
||||
<Link to={`/projects/${projectsId}/version`} style={{marginRight:30}} className='topWrapper_btn fr'>取消</Link>
|
||||
<a className='topWrapper_btn_delete fr' onClick={()=>this.deleteversion()} style={{marginLeft:15}}>删除发布</a>
|
||||
<a className='topWrapper_btn fr' onClick={()=>this.handleSubmit()} style={{marginRight:15}}>发布版本</a>
|
||||
<Link to={`/projects/${projectsId}/version`} style={{marginRight:30}} className='topWrapper_btn fr'>取消</Link>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,22 @@
|
|||
.topWrapper {
|
||||
padding: 20px 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #EEEEEE;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.topWrapper_btn {
|
||||
background: #21ba45;
|
||||
color: #FFFFFF!important;
|
||||
padding:0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
||||
.versionmilepostleft{
|
||||
padding: 15px;
|
||||
margin-right: 50px;
|
||||
|
|
@ -91,4 +110,7 @@
|
|||
margin-left: -4px;
|
||||
margin-bottom: 10px;
|
||||
background: rgb(83, 81, 81);
|
||||
}
|
||||
}
|
||||
.ver-middle{
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
|
@ -1,14 +1,11 @@
|
|||
import React , { Component } from "react";
|
||||
import {Link} from 'react-router-dom';
|
||||
import { Input ,Dropdown , Menu , Icon , Pagination , Spin, Divider } from 'antd';
|
||||
import NoneData from '../../modules/courses/coursesPublic/NoneData';
|
||||
import Nav from '../Order/Nav';
|
||||
import { Input } from 'antd';
|
||||
import NoneData from '../Nodata';
|
||||
import './version.css';
|
||||
|
||||
|
||||
import { getImageUrl } from 'educoder';
|
||||
import axios from 'axios';
|
||||
|
||||
const Search = Input.Search;
|
||||
/**
|
||||
* issue_chosen:下拉的筛选列表,
|
||||
* data:列表接口返回的所有数据,
|
||||
|
|
@ -61,7 +58,7 @@ class version extends Component{
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
render(){
|
||||
|
|
@ -71,73 +68,90 @@ class version extends Component{
|
|||
if(data && data.releases && data.releases.length>0 ){
|
||||
return(
|
||||
<div>{
|
||||
data.releases.map((item,key)=>{
|
||||
return(
|
||||
<div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<div className="versionrighe"></div><span className={item&&item.draft==="稳定"?"opendversionetail":"closedversionetail"} style={{marginTop:5,margin:'auto',marginRight:15}}>{item.draft} </span>
|
||||
</div>
|
||||
<div className="version_line_one">
|
||||
<p className="versionrectangle"> </p>
|
||||
</div>
|
||||
data.releases.map((item,key)=>{
|
||||
return(
|
||||
<div key={key}>
|
||||
{
|
||||
data && data.user_permission ?
|
||||
<div className="versionrighe">
|
||||
<h1 style={{marginLeft:15,marginTop:5}}>{item.name}<Link to={`/projects/${projectsId}/version/${item.version_id}/upversion`} style={{color:'blue',fontSize:10,marginLeft:5}}>(编辑)</Link> </h1>
|
||||
item && item.id ?
|
||||
<div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<div className="versionrighe"></div><span className={item&&item.draft==="稳定"?"opendversionetail":"closedversionetail"} style={{marginTop:5,margin:'auto',marginRight:15}}>{item.draft} </span>
|
||||
</div>
|
||||
<div className="version_line_one">
|
||||
<p className="versionrectangle"> </p>
|
||||
</div>
|
||||
<div className="versionrighe">
|
||||
<h1 style={{marginLeft:15,marginTop:5}}>{item.name}
|
||||
{
|
||||
data && data.user_permission ?
|
||||
<Link to={`/projects/${projectsId}/version/${item.version_id}/upversion`} style={{color:'blue',fontSize:10,marginLeft:5}}>(编辑)</Link>
|
||||
: ''
|
||||
}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<span style={{marginTop:5,margin:'auto',marginRight:15}}>{item.tag_name} </span>
|
||||
</div>
|
||||
<div className="version_line_one">
|
||||
<p style={{width:4}}> </p>
|
||||
|
||||
</div>
|
||||
<div className="versionrighe">
|
||||
<h5 style={{marginLeft:15,marginTop:10}}>{item.body} </h5>
|
||||
<div className="ml15">
|
||||
<Link to={`/users/${item && item.login}/projects`} className="show-user-link">
|
||||
<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr5 radius"/>
|
||||
<span className="mr10 ver-middle">{item.user_name}</span>
|
||||
</Link>
|
||||
<span className="color-grey-9 ver-middle">发布于{item.created_at}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<span style={{marginTop:5,marginRight:15}}></span>
|
||||
</div>
|
||||
<div className="version_line_tpw">
|
||||
<p style={{width:4}}> </p>
|
||||
</div>
|
||||
<div className="versionrighe">
|
||||
<h1 style={{marginLeft:15,marginTop:10}}>下载附件
|
||||
</h1>
|
||||
<a href={item.zipball_url} download="源代码(ZIP)" style={{color:'blue',marginLeft:15}}>源代码(ZIP)</a>
|
||||
<a href={item.tarball_url} download="源文件(TAR.GZ)" style={{color:'blue',marginLeft:15}}>源文件(TAR.GZ)</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<span style={{marginTop:5,marginRight:15}}></span>
|
||||
</div>
|
||||
<div className="version_line_tpw">
|
||||
<p style={{width:4}}> </p>
|
||||
</div>
|
||||
<div className="versionrighe">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
: ''
|
||||
:
|
||||
""
|
||||
}
|
||||
|
||||
</div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<span style={{marginTop:5,margin:'auto',marginRight:15}}>{item.tag_name} </span>
|
||||
</div>
|
||||
<div className="version_line_one">
|
||||
<p style={{width:4}}> </p>
|
||||
|
||||
</div>
|
||||
<div className="versionrighe">
|
||||
<h5 style={{marginLeft:15,marginTop:10}}>{item.body} </h5>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<span style={{marginTop:5,marginRight:15}}></span>
|
||||
</div>
|
||||
<div className="version_line_tpw">
|
||||
<p style={{width:4}}> </p>
|
||||
</div>
|
||||
<div className="versionrighe">
|
||||
<h1 style={{marginLeft:15,marginTop:10}}>下载附件
|
||||
</h1>
|
||||
<a href={item.zipball_url} download="源代码(ZIP)" style={{color:'blue',marginLeft:15}}>源代码(ZIP)</a>
|
||||
<a href={item.tarball_url} download="源文件(TAR.GZ)" style={{color:'blue',marginLeft:15}}>源文件(TAR.GZ)</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{display:'flex'}}>
|
||||
<div className="versionleft">
|
||||
<span style={{marginTop:5,marginRight:15}}></span>
|
||||
</div>
|
||||
<div className="version_line_tpw">
|
||||
<p style={{width:4}}> </p>
|
||||
</div>
|
||||
<div className="versionrighe">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<NoneData />
|
||||
)
|
||||
}
|
||||
}
|
||||
return(
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="main">
|
||||
|
|
@ -149,12 +163,12 @@ class version extends Component{
|
|||
: ''
|
||||
}
|
||||
|
||||
</div>
|
||||
<div>
|
||||
{renderList()}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
{renderList()}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
export function truncateCommitId(str) {
|
||||
if (str.length > 11) {
|
||||
return str.substring(0, 10)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
.newMain{
|
||||
background-color: #fff;
|
||||
}
|
||||
.main{
|
||||
width: 1200px;
|
||||
margin:20px auto;
|
||||
|
|
@ -69,6 +71,20 @@
|
|||
background-color: #f4f4f4;
|
||||
line-height: 18px;
|
||||
}
|
||||
.none_panels{
|
||||
text-align: center;
|
||||
height: 400px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.none_panels img{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.none_p_title{
|
||||
font-size: 16px;
|
||||
color: #999;
|
||||
}
|
||||
@media screen and (max-width: 1000px){
|
||||
.main{
|
||||
width: 750px;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* @Description: 填空
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-06 09:02:29
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-02-05 10:44:01
|
||||
*/
|
||||
import Quill from 'quill';
|
||||
let Inline = Quill.import('blots/inline');
|
||||
class FillBlot extends Inline {
|
||||
static create(value) {
|
||||
const node = super.cerate(value);
|
||||
node.setAttribute('data_index', value.data_index);
|
||||
node.nodeValue = value.text;
|
||||
return node;
|
||||
}
|
||||
|
||||
static value(node) {
|
||||
return {
|
||||
// dataSet: node.getAttribute('data-fill'),
|
||||
data_index: node.getAttribute('data_index')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FillBlot.blotName = "fill";
|
||||
FillBlot.tagName = "span";
|
||||
|
||||
export default FillBlot;
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* @Description: 重写图片
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2019-12-16 15:50:45
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2019-12-31 13:59:02
|
||||
*/
|
||||
import Quill from "quill";
|
||||
|
||||
const BlockEmbed = Quill.import('blots/block/embed');
|
||||
|
||||
export default class ImageBlot extends BlockEmbed {
|
||||
|
||||
static create(value) {
|
||||
|
||||
const node = super.create();
|
||||
node.setAttribute('alt', value.alt);
|
||||
node.setAttribute('src', value.url);
|
||||
console.log('~~~~~~~~~~~', node, value);
|
||||
node.addEventListener('click', function () {
|
||||
try {
|
||||
value.onclick(value.url);
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
}, false);
|
||||
if (value.width) {
|
||||
node.setAttribute('width', value.width);
|
||||
}
|
||||
if (value.height) {
|
||||
node.setAttribute('height', value.height);
|
||||
}
|
||||
|
||||
if (value.id) {
|
||||
node.setAttribute('id', value.id);
|
||||
}
|
||||
// 宽度和高度都不存在时,
|
||||
if (!value.width && !value.height) {
|
||||
node.setAttribute('width', '100%');
|
||||
}
|
||||
|
||||
// node.setAttribute('style', { cursor: 'pointer' });
|
||||
|
||||
// if (node.onclick) {
|
||||
// console.log('image 有图片点击事件======》》》》》》');
|
||||
// // node.setAttribute('onclick', node.onCLick);
|
||||
// }
|
||||
// 给图片添加点击事件
|
||||
// node.onclick = () => {
|
||||
// value.onClick && value.onClick(value.url);
|
||||
// }
|
||||
return node;
|
||||
}
|
||||
|
||||
// 获取节点值
|
||||
static value(node) {
|
||||
|
||||
return {
|
||||
alt: node.getAttribute('alt'),
|
||||
url: node.getAttribute('src'),
|
||||
onclick: node.onclick,
|
||||
width: node.width,
|
||||
height: node.height,
|
||||
display: node.getAttribute('display'),
|
||||
id: node.id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
ImageBlot.blotName = 'image';
|
||||
ImageBlot.tagName = 'img';
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<!--
|
||||
* @Description:
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-06 16:20:03
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-01-09 09:45:29
|
||||
-->
|
||||
## QuillForEditor 使用 [https://quilljs.com/]
|
||||
|
||||
### 导入
|
||||
|
||||
- 目录 src/common/quillForEditor (默认加载当前文件夹下的 index.js 文件)
|
||||
|
||||
### 参数
|
||||
|
||||
| 字段 | 描述 |
|
||||
| ----- | ----- |
|
||||
| placeholder | 提示信息 |
|
||||
| readOnly | 只读(只读取模式时,没有 工具栏且内容不可编辑,通常用于展示quill内容) |
|
||||
| autoFocus | 自动获得焦点 |
|
||||
| options | 配置参数, 指定工具栏内容 |
|
||||
| value | 文本编辑器内容 |
|
||||
| imgAttrs | 指定上传图片的尺寸 { width: 'xxpx}, height: 'xxpx'|
|
||||
| style | 指定quill容器样式 |
|
||||
| wrapStyle | 指定包裹quill容器的样式|
|
||||
| onContentChange | 当编辑器内容变化时调用此回调函数(注: 此时返回的内容为对象,提交到后台时需要格式成 JSON 字符串: JSON.stringify(xx)) |
|
||||
| showUploadImage | 点击放大上传成功后的图片, 返回上传成功后的图片 url, (评论时点击图片这么大)|
|
||||
|
||||
|
||||
|
||||
### 添加工具栏
|
||||
|
||||
- 默认所有的
|
||||
|
||||
```
|
||||
const options = [
|
||||
'bold', // 加粗
|
||||
'italic', // 斜体
|
||||
'underline', // 下划线
|
||||
{size: ['12px', '14px', '16px', '18px', '20px']}, // 字体大小
|
||||
{align: []}, // 对齐方式
|
||||
{list: 'ordered'}, // 有序列表
|
||||
{list: 'bullet'}, // 无序列表
|
||||
{script: 'sub'}, // 下标 x2
|
||||
{script: 'super'}, // 上标 平方 (x2)
|
||||
{ 'color': [] }, // 字体颜色
|
||||
{ 'background': [] }, // 背景色
|
||||
{header: [1,2,3,4,5,false]}, // H1,H2 ...
|
||||
'blockquote', // 文件左边加一个边框样式
|
||||
'code-block', // 块内容
|
||||
'link', // 链接
|
||||
'image', // 图片
|
||||
'video', // 视频
|
||||
'formula', // 数学公式
|
||||
'clean' // 清除
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
### 使用
|
||||
|
||||
````
|
||||
编辑模式是放不大图片的
|
||||
import QuillForEditor from 'xxx';
|
||||
|
||||
// 指定需要显示的工具栏信息, 不指定加载全部
|
||||
const options = [
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* @description 获取编辑器返回的内容
|
||||
* @params [Object] value 编辑器内容
|
||||
*/
|
||||
const handleCtxChange = (value) => {
|
||||
// 编辑器内容非空判断
|
||||
const _text = quill.getText();
|
||||
const reg = /^[\s\S]*.*[^\s][\s\S]*$/;
|
||||
if (!reg.test(_text)) {
|
||||
// 处理编辑器内容为空
|
||||
} else {
|
||||
// 提交到后台的内容需要处理一下;
|
||||
value = JSON.stringify(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<QuillForEditor
|
||||
options={options}
|
||||
onContentChange={handleCtxChange}
|
||||
>
|
||||
</QuillForEditor>
|
||||
````
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
function deepEqual (prev, current) {
|
||||
if (prev === current) { // 基本类型比较,值,类型都相同 或者同为 null or undefined
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((!prev && current)
|
||||
|| (prev && !current)
|
||||
|| (!prev && !current)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Array.isArray(prev)) {
|
||||
if (!Array.isArray(current)) return false;
|
||||
if (prev.length !== current.length) return false;
|
||||
|
||||
for (let i = 0; i < prev.length; i++) {
|
||||
if (!deepEqual(current[i], prev[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof current === 'object') {
|
||||
if (typeof prev !== 'object') return false;
|
||||
const prevKeys = Object.keys(prev);
|
||||
const curKeys = Object.keys(current);
|
||||
|
||||
if (prevKeys.length !== curKeys.length) return false;
|
||||
|
||||
prevKeys.sort();
|
||||
curKeys.sort();
|
||||
|
||||
for (let i = 0; i < prevKeys.length; i++) {
|
||||
if (prevKeys[i] !== curKeys[i]) return false;
|
||||
const key = prevKeys[i];
|
||||
if (!deepEqual(prev[key], current[key])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export default deepEqual;
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
@charset "utf-8";
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
|
||||
content: "宋体";
|
||||
font-family:SimSun !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
|
||||
content: "黑体";
|
||||
font-family:SimHei !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
|
||||
content: "微软雅黑";
|
||||
font-family:Microsoft YaHei !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
|
||||
content: "楷体";
|
||||
font-family:KaiTi !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
|
||||
content: "仿宋";
|
||||
font-family:FangSong !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
|
||||
content: "Arial";
|
||||
font-family:Arial !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
|
||||
content: "Times New Roman";
|
||||
font-family:Times New Roman !important;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
|
||||
content: "sans-serif";
|
||||
font-family:sans-serif !important;
|
||||
}
|
||||
|
||||
.ql-font-SimSun {
|
||||
font-family:SimSun !important;
|
||||
}
|
||||
.ql-font-SimHei {
|
||||
font-family:SimHei !important;
|
||||
}
|
||||
.ql-font-Microsoft-YaHei {
|
||||
font-family:Microsoft YaHei !important;
|
||||
}
|
||||
.ql-font-KaiTi {
|
||||
font-family:KaiTi !important;
|
||||
}
|
||||
.ql-font-FangSong {
|
||||
font-family:FangSong !important;
|
||||
}
|
||||
.ql-font-Arial {
|
||||
font-family:Arial !important;
|
||||
}
|
||||
.ql-font-Times-New-Roman {
|
||||
font-family:Times New Roman !important;
|
||||
}
|
||||
.ql-font-sans-serif {
|
||||
font-family:sans-serif !important;
|
||||
}
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* @Description: quill 编辑器
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2019-12-18 08:49:30
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-02-05 11:23:03
|
||||
*/
|
||||
import './index.scss';
|
||||
import 'quill/dist/quill.core.css'; // 核心样式
|
||||
import 'quill/dist/quill.snow.css'; // 有工具栏
|
||||
import 'quill/dist/quill.bubble.css'; // 无工具栏
|
||||
import 'katex/dist/katex.min.css'; // katex 表达式样式
|
||||
import './font.css'
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import Quill from 'quill';
|
||||
import katex from 'katex';
|
||||
import deepEqual from './deepEqual.js'
|
||||
import { fetchUploadImage } from '../../services/ojService.js';
|
||||
import ImageBlot from './ImageBlot';
|
||||
import FillBlot from './FillBlot';
|
||||
import LinkBlot from './link-blot';
|
||||
import { getImageUrl } from 'educoder';
|
||||
var Size = Quill.import('attributors/style/size');
|
||||
Size.whitelist = ['14px', '16px', '18px', '20px', false];
|
||||
var fonts = ['Microsoft-YaHei', 'SimSun', 'SimHei', 'KaiTi', 'FangSong'];
|
||||
var Font = Quill.import('formats/font');
|
||||
Font.whitelist = fonts; //将字体加入到白名单
|
||||
window.Quill = Quill;
|
||||
window.katex = katex;
|
||||
Quill.register(ImageBlot);
|
||||
Quill.register(Size);
|
||||
Quill.register(LinkBlot);
|
||||
Quill.register(Font, true);
|
||||
// Quill.register({'modules/toolbar': Toolbar});
|
||||
Quill.register({
|
||||
'formats/fill': FillBlot
|
||||
});
|
||||
// Quill.register(Color);
|
||||
|
||||
|
||||
function QuillForEditor({
|
||||
placeholder,
|
||||
readOnly,
|
||||
autoFocus = false,
|
||||
options,
|
||||
value,
|
||||
imgAttrs = {}, // 指定图片的宽高
|
||||
style = {},
|
||||
wrapStyle = {},
|
||||
showUploadImage,
|
||||
onContentChange,
|
||||
addFill, // 点击填空成功的回调
|
||||
deleteFill // 删除填空,返回删除的下标
|
||||
}) {
|
||||
// toolbar 默认值
|
||||
const defaultConfig = [
|
||||
'bold', 'italic', 'underline',
|
||||
{ size: ['14px', '16px', '18px', '20px'] },
|
||||
{ align: [] }, { list: 'ordered' }, { list: 'bullet' }, // 列表
|
||||
{ script: 'sub' }, { script: 'super' },
|
||||
{ 'color': [] }, { 'background': [] },
|
||||
{ 'font': [] },
|
||||
{ header: [1, 2, 3, 4, 5, false] },
|
||||
'blockquote', 'code-block',
|
||||
'link', 'image', 'video',
|
||||
'formula',
|
||||
'clean'
|
||||
];
|
||||
|
||||
const editorRef = useRef(null);
|
||||
// quill 实例
|
||||
const [quill, setQuill] = useState(null);
|
||||
const [selection, setSelection] = useState(null);
|
||||
const [fillCount, setFillCount] = useState(0);
|
||||
const [quillCtx, setQuillCtx] = useState({});
|
||||
|
||||
// 文本内容变化时
|
||||
const handleOnChange = content => {
|
||||
onContentChange && onContentChange(content, quill);
|
||||
};
|
||||
|
||||
const renderOptions = options || defaultConfig;
|
||||
|
||||
const bindings = {
|
||||
tab: {
|
||||
key: 9,
|
||||
handler: function () { }
|
||||
},
|
||||
backspace: {
|
||||
key: 'Backspace',
|
||||
/**
|
||||
* @param {*} range
|
||||
* { index, // 删除元素的位置
|
||||
* length // 删除元素的个数, 当删除一个时, length=0, 其它等于删除的元素的个数
|
||||
* }
|
||||
* @param {*} context 上下文
|
||||
*/
|
||||
handler: function (range, context) {
|
||||
/**
|
||||
* index: 删除元素的位置
|
||||
* length: 删除元素的个数
|
||||
*/
|
||||
const { index, length } = range;
|
||||
const _start = length === 0 ? index - 1 : index;
|
||||
const _length = length || 1;
|
||||
let delCtx = this.quill.getText(_start, _length); // 删除的元素
|
||||
const reg = /▁/g;
|
||||
const delArrs = delCtx.match(reg);
|
||||
if (delArrs) {
|
||||
const r = window.confirm('确定要删除吗?');
|
||||
if (r) {
|
||||
let leaveCtx; // 获取删除元素之前的内容
|
||||
if (length === 0) {
|
||||
leaveCtx = this.quill.getText(0, index - 1);
|
||||
} else {
|
||||
leaveCtx = this.quill.getText(0, index);
|
||||
}
|
||||
const leaveArrs = leaveCtx.match(reg);
|
||||
const leaveLen = (leaveArrs || []).length;
|
||||
let delIndexs = [];
|
||||
// 获取删除元素的下标
|
||||
delArrs.forEach((item, i) => {
|
||||
leaveLen === 0 ? delIndexs.push(i) : delIndexs.push(leaveLen + i);
|
||||
});
|
||||
deleteFill && deleteFill(delIndexs); // 调用删除回调, 返回删除的元素下标[]
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
// quill 配置信息
|
||||
const quillOption = {
|
||||
modules: {
|
||||
toolbar: renderOptions,
|
||||
keyboard: {
|
||||
bindings: bindings
|
||||
}
|
||||
// toolbar: {
|
||||
// container: renderOptions
|
||||
// }
|
||||
},
|
||||
readOnly,
|
||||
placeholder,
|
||||
theme: readOnly ? 'bubble' : 'snow',
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const quillNode = document.createElement('div');
|
||||
editorRef.current.appendChild(quillNode);
|
||||
const _quill = new Quill(editorRef.current, quillOption);
|
||||
|
||||
setQuill(_quill);
|
||||
// 处理图片上传功能
|
||||
_quill.getModule('toolbar').addHandler('image', (e) => {
|
||||
const input = document.createElement('input');
|
||||
input.setAttribute('type', 'file');
|
||||
input.setAttribute('accept', 'image/*');
|
||||
input.click();
|
||||
|
||||
input.onchange = async (e) => {
|
||||
const file = input.files[0]; // 获取文件信息
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
const range = _quill.getSelection(true);
|
||||
let fileUrl = ''; // 保存上传成功后图片的url
|
||||
// 上传文件
|
||||
const result = await fetchUploadImage(formData);
|
||||
// 获取上传图片的url
|
||||
if (result.data && result.data.id) {
|
||||
fileUrl = (getImageUrl(`api/attachments/${result.data.id}`));
|
||||
}
|
||||
// 根据id获取文件路径
|
||||
const { width, height } = imgAttrs;
|
||||
// console.log('上传图片的url:', fileUrl);
|
||||
if (fileUrl) {
|
||||
_quill.insertEmbed(range.index, 'image', {
|
||||
url: fileUrl,
|
||||
alt: '图片信息',
|
||||
onClick: showUploadImage,
|
||||
width,
|
||||
height
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
// 处理填空
|
||||
_quill.getModule('toolbar').addHandler('fill', (e) => {
|
||||
// alert(1111);
|
||||
setFillCount(fillCount + 1);
|
||||
const range = _quill.getSelection(true);
|
||||
_quill.insertText(range.index, '▁');
|
||||
addFill && addFill(); // 调用添加回调
|
||||
});
|
||||
}, []);
|
||||
|
||||
// 设置值
|
||||
useEffect(() => {
|
||||
if (!quill) return
|
||||
|
||||
const previous = quill.getContents()
|
||||
|
||||
if (value && value.hasOwnProperty('ops')) {
|
||||
const ops = value.ops || [];
|
||||
ops.forEach((item, i) => {
|
||||
if (item.insert['image']) {
|
||||
item.insert['image'] = Object.assign({}, item.insert['image'], { style: { cursor: 'pointer' }, onclick: (url) => showUploadImage(url) });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const current = value
|
||||
if (!deepEqual(previous, current)) {
|
||||
setSelection(quill.getSelection())
|
||||
if (typeof value === 'string' && value) {
|
||||
// debugger
|
||||
quill.clipboard.dangerouslyPasteHTML(value, 'api');
|
||||
if (autoFocus) {
|
||||
quill.focus();
|
||||
} else {
|
||||
quill.blur();
|
||||
}
|
||||
} else {
|
||||
quill.setContents(value)
|
||||
if (autoFocus) quill.focus();
|
||||
}
|
||||
}
|
||||
}, [quill, value, setQuill, autoFocus]);
|
||||
|
||||
// 清除选择区域
|
||||
useEffect(() => {
|
||||
if (quill && selection) {
|
||||
quill.setSelection(selection)
|
||||
setSelection(null)
|
||||
}
|
||||
}, [quill, selection, setSelection]);
|
||||
|
||||
// 设置placeholder值
|
||||
useEffect(() => {
|
||||
if (!quill || !quill.root) return;
|
||||
quill.root.dataset.placeholder = placeholder;
|
||||
}, [quill, placeholder]);
|
||||
|
||||
// 处理内容变化
|
||||
useEffect(() => {
|
||||
if (!quill) return;
|
||||
if (typeof handleOnChange !== 'function') return;
|
||||
let handler;
|
||||
quill.on(
|
||||
'text-change',
|
||||
(handler = (delta, oldDelta, source) => {
|
||||
const _ctx = quill.getContents();
|
||||
setQuillCtx(_ctx);
|
||||
handleOnChange(quill.getContents()); // getContents: 检索编辑器内容
|
||||
})
|
||||
);
|
||||
return () => {
|
||||
quill.off('text-change', handler);
|
||||
}
|
||||
}, [quill, handleOnChange]);
|
||||
|
||||
// 返回结果
|
||||
return (
|
||||
<div className='quill_editor_for_react_area' style={wrapStyle}>
|
||||
<div ref={editorRef} style={style}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default QuillForEditor;
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
.quill_editor_for_react_area{
|
||||
// background: #fff;
|
||||
// margin: 0 15px;
|
||||
.ql-editing{
|
||||
left: 0 !important;
|
||||
}
|
||||
.ql-editor{
|
||||
img{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="12px"]::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="12px"]::before {
|
||||
content: '12px';
|
||||
font-size: 12px;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="14px"]::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {
|
||||
content: '14px';
|
||||
font-size: 14px;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="16px"]::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="16px"]::before {
|
||||
content: '16px';
|
||||
font-size: 16px;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="18px"]::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="18px"]::before {
|
||||
content: '18px';
|
||||
font-size: 18px;
|
||||
}
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="20px"]::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="20px"]::before {
|
||||
content: '20px';
|
||||
font-size: 20px;
|
||||
}
|
||||
//默认的样式
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
||||
content: '14px';
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
|
||||
content: "宋体";
|
||||
font-family: "SimSun";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
|
||||
content: "黑体";
|
||||
font-family: "SimHei";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
|
||||
content: "微软雅黑";
|
||||
font-family: "Microsoft YaHei";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
|
||||
content: "楷体";
|
||||
font-family: "KaiTi";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
|
||||
content: "仿宋";
|
||||
font-family: "FangSong";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
|
||||
content: "Arial";
|
||||
font-family: "Arial";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
|
||||
content: "Times New Roman";
|
||||
font-family: "Times New Roman";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
|
||||
content: "sans-serif";
|
||||
font-family: "sans-serif";
|
||||
}
|
||||
|
||||
.ql-font-SimSun {
|
||||
font-family: "SimSun";
|
||||
}
|
||||
.ql-font-SimHei {
|
||||
font-family: "SimHei";
|
||||
}
|
||||
.ql-font-Microsoft-YaHei {
|
||||
font-family: "Microsoft YaHei";
|
||||
}
|
||||
.ql-font-KaiTi {
|
||||
font-family: "KaiTi";
|
||||
}
|
||||
.ql-font-FangSong {
|
||||
font-family: "FangSong";
|
||||
}
|
||||
.ql-font-Arial {
|
||||
font-family: "Arial";
|
||||
}
|
||||
.ql-font-Times-New-Roman {
|
||||
font-family: "Times New Roman";
|
||||
}
|
||||
.ql-font-sans-serif {
|
||||
font-family: "sans-serif";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
||||
content: "微软雅黑";
|
||||
font-family: "Microsoft YaHei";
|
||||
}
|
||||
|
||||
// 填空图标
|
||||
.ql-snow .ql-fill{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
color: #05101A;
|
||||
// font-size: 18px;
|
||||
vertical-align: top;
|
||||
&::before{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: -1px;
|
||||
content: '\e709';
|
||||
font-family: 'iconfont';
|
||||
margin-left: -7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import Quill from "quill";
|
||||
const Inline = Quill.import('blots/inline');
|
||||
|
||||
export default class LinkBlot extends Inline {
|
||||
static create(value) {
|
||||
let node = super.create()
|
||||
let rs = value
|
||||
if (rs.indexOf('http://') < 0) {
|
||||
rs = 'http://' + rs
|
||||
}
|
||||
node.setAttribute('href', rs)
|
||||
node.setAttribute('target', '_blank')
|
||||
return node;
|
||||
}
|
||||
|
||||
static formats(node) {
|
||||
return node.getAttribute('href');
|
||||
}
|
||||
}
|
||||
LinkBlot.blotName = 'link'
|
||||
LinkBlot.tagName = 'a'
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
.ql-editor .ql-font-Microsoft-YaHei {
|
||||
font-family: "Microsoft YaHei";
|
||||
}
|
||||
.ql-editor .ql-font-SimSun {
|
||||
font-family: "SimSun";
|
||||
}
|
||||
.ql-editor .ql-font-SimHei {
|
||||
font-family: "SimHei";
|
||||
}
|
||||
.ql-editor .ql-font-KaiTi {
|
||||
font-family: "KaiTi";
|
||||
}
|
||||
.ql-editor .ql-font-Arial {
|
||||
font-family: "Arial";
|
||||
}
|
||||
.ql-editor .Times-New-Roman {
|
||||
font-family: "Times New Roman";
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
||||
content: '微软雅黑';
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
|
||||
content: "微软雅黑";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
|
||||
content: "宋体";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
|
||||
content: "黑体";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
|
||||
content: "楷体";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
|
||||
content: "Arial";
|
||||
}
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
|
||||
content: "Times New Roman";
|
||||
}
|
||||
|
|
@ -80,7 +80,7 @@ class EducoderInteresse extends Component {
|
|||
justifyContent: "center",
|
||||
width: "100%",
|
||||
}}>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} 国防科技大学<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -181,21 +181,21 @@ class EducoderLogin extends Component {
|
|||
justifyContent: "center",
|
||||
width: "100%",
|
||||
}}>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} 国防科技大学<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
</div>:
|
||||
this.props.mygetHelmetapi===undefined||this.props.mygetHelmetapi.main_site===null|| this.props.mygetHelmetapi.main_site===undefined? <div style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
}}>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} 湘ICP备17009477号<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
</div>:this.props.mygetHelmetapi.main_site===true?
|
||||
<div style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
width: "100%",
|
||||
}}>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} EduCoder<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
<div className="font-14 color-grey-9 " style={{marginTop:"20px"}}><span className="font-18">©</span> {moment().year()} 湘ICP备17009477号<span className="ml15 mr15">湘ICP备17009477号</span><a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside.</div>
|
||||
</div>
|
||||
:""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,17 +440,9 @@ class LoginDialog extends Component {
|
|||
this.setState({
|
||||
isRender: false
|
||||
})
|
||||
this.props.Modifyloginvalue();
|
||||
|
||||
|
||||
// this.setState({
|
||||
// isRender: false
|
||||
// })
|
||||
// try {
|
||||
// this.props.Modifyloginvalue();
|
||||
// }catch (e) {
|
||||
//
|
||||
// }
|
||||
this.props.Modifyloginvalue();
|
||||
console.log(this.props);
|
||||
// this.props.history.push("/login");
|
||||
}
|
||||
|
||||
loginEDU=()=>{
|
||||
|
|
@ -469,7 +461,7 @@ class LoginDialog extends Component {
|
|||
autologin:isGoingValue
|
||||
}
|
||||
).then((response) => {
|
||||
debugger;
|
||||
// debugger;
|
||||
if(response===undefined){
|
||||
return
|
||||
}
|
||||
|
|
@ -720,9 +712,12 @@ class LoginDialog extends Component {
|
|||
</span>
|
||||
|
||||
<span className="fr">
|
||||
<a onClick={(url) => this.getloginurl("/changepassword")}
|
||||
className="mr3 color-grey-9">找回密码</a><em className="vertical-line"></em>
|
||||
<a onClick={(url)=>this.getloginurl("/register")} className="color-grey-9">注册</a>
|
||||
<a href="https://www.trustie.net/account/lost_password" className="mr3 color-grey-9" target={"_blank"}>找回密码</a>
|
||||
{/*<a onClick={(url) => this.getloginurl("/changepassword")}*/}
|
||||
{/*className="mr3 color-grey-9">找回密码</a>*/}
|
||||
<em className="vertical-line"></em>
|
||||
{/*<a onClick={(url)=>this.getloginurl("https://www.trustie.net/login?login=false")} className="color-grey-9">注册</a>*/}
|
||||
<a href="https://www.trustie.net/login?login=false" target={"_blank"} className="color-grey-9">注册</a>
|
||||
</span>
|
||||
|
||||
</p>
|
||||
|
|
@ -782,4 +777,3 @@ class LoginDialog extends Component {
|
|||
}
|
||||
|
||||
export default LoginDialog ;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,37 +13,6 @@ import update from 'immutability-helper'
|
|||
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
// import { getUrl } from 'educoder'
|
||||
// let _url_origin = getUrl()
|
||||
// const $ = window.$
|
||||
// let prefix = '/react/build'
|
||||
// if (window.location.port == 3007) {
|
||||
// prefix = ''
|
||||
// } else {
|
||||
// }
|
||||
|
||||
// 下面这个加载方式有问题,改到html 写script标签
|
||||
// if (!window['TPIScriptLoaded']) {
|
||||
// // $('head').append($('<link rel="stylesheet" type="text/css" />')
|
||||
// // .attr('href', `${_url_origin}${prefix}/js/xterm/xterm.css`));
|
||||
|
||||
// $.when(
|
||||
// $.getScript( `${_url_origin}/assets/kindeditor/kindeditor.js` ),
|
||||
// $.getScript( `${_url_origin}${prefix}/js/create_kindeditor.js` ),
|
||||
// $.getScript( `${_url_origin}/javascripts/educoder/edu_application.js` ),
|
||||
// $.Deferred(function( deferred ){
|
||||
// $( deferred.resolve );
|
||||
// })
|
||||
// ).done(function(){
|
||||
// window.TPIScriptLoaded = true
|
||||
// //place your code here, the scripts are all loaded
|
||||
// // callback && callback()
|
||||
// });
|
||||
// } else {
|
||||
// // callback && callback()
|
||||
// }
|
||||
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
|
@ -53,31 +22,16 @@ class Index extends Component {
|
|||
styles += 'overflow: hidden !important;'
|
||||
window.$('body').attr('style', styles);
|
||||
window.$('#root').css('position', 'absolute')
|
||||
|
||||
// TPI浏览器缩放
|
||||
// setTimeout(() => {
|
||||
// const agent = navigator.userAgent;
|
||||
// if (agent.indexOf('Mac OS') == -1) {
|
||||
// window._initZoomCheck()
|
||||
// }
|
||||
// }, 800)
|
||||
|
||||
|
||||
this.onDrawerButtonClick = this.onDrawerButtonClick.bind(this)
|
||||
this.onStarChange = this.onStarChange.bind(this)
|
||||
this.saveChallengeStar = this.saveChallengeStar.bind(this)
|
||||
this.onChallengesDrawerClose = this.onChallengesDrawerClose.bind(this)
|
||||
|
||||
|
||||
this.starArray = [];
|
||||
|
||||
// 将原本放置在Header.js中的state上提到Index.js
|
||||
this.state = {
|
||||
challengesDrawerOpen: false,
|
||||
taskListLoading: true,
|
||||
challenges: [], // 任务列表
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +46,6 @@ class Index extends Component {
|
|||
return;
|
||||
}
|
||||
const { shixun, myshixun } = this.props;
|
||||
// var getChallengesUrl = `/api/v1/games/${this.props.game.identifier}/challenges`;
|
||||
var getChallengesUrl = `/myshixuns/${myshixun.identifier}/challenges.json`;
|
||||
|
||||
this.setState({
|
||||
|
|
@ -100,9 +53,7 @@ class Index extends Component {
|
|||
challengesDrawerOpen:true
|
||||
})
|
||||
|
||||
axios.get(getChallengesUrl, {
|
||||
// withCredentials: true,
|
||||
})
|
||||
axios.get(getChallengesUrl)
|
||||
.then((response) => {
|
||||
|
||||
if (response.data.status == -1) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import Tree, { TreeNode } from 'rc-tree';
|
|||
import 'rc-tree/assets/index.css';
|
||||
|
||||
import classNames from 'classnames'
|
||||
// import CodeMirror from 'react-codeMirror'
|
||||
// import CodeMirror from 'react-codemirror'
|
||||
|
||||
import axios from 'axios'
|
||||
import _ from 'lodash'
|
||||
|
|
@ -52,12 +52,12 @@ class CodeRepositoryView extends Component {
|
|||
}
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
const { game, challenge, hide_code, tabIndex, } = this.props
|
||||
|
||||
|
||||
if ( // 初始化 或者 game切换
|
||||
!this.treeExpanded && challenge.path && challenge.path.length && this.state.expandedKeys.length === 0 ||
|
||||
game && (!prevProps.game
|
||||
!this.treeExpanded && challenge.path && challenge.path.length && this.state.expandedKeys.length === 0 ||
|
||||
game && (!prevProps.game
|
||||
|| prevProps.game.identifier !== this.props.game.identifier) ) {
|
||||
|
||||
|
||||
if (!this.treeExpanded) {
|
||||
this.treeExpanded = true
|
||||
const _path = challenge.multiPath ? challenge.path[0] : challenge.path;
|
||||
|
|
@ -77,8 +77,8 @@ class CodeRepositoryView extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
if (game && (!prevProps.game
|
||||
|| prevProps.game.identifier !== this.props.game.identifier)) {
|
||||
if (game && (!prevProps.game
|
||||
|| prevProps.game.identifier !== this.props.game.identifier)) {
|
||||
// 切换关卡时切换到第一个tab
|
||||
// 如果隐藏code tab,就只有一个ssh tab了
|
||||
if (hide_code == true) {
|
||||
|
|
@ -90,12 +90,12 @@ class CodeRepositoryView extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
componentDidMount() {
|
||||
// 隐藏code tab,则显示ssh tab(81)
|
||||
if (this.props.hide_code === true) {
|
||||
this.tabIndexChange(81)
|
||||
}
|
||||
|
||||
|
||||
//显示所有代码文件
|
||||
$(".code-file-tab").hover(function(){
|
||||
// var ulwidth=$("#blacktab_nav").width();
|
||||
|
|
@ -119,22 +119,22 @@ class CodeRepositoryView extends Component {
|
|||
const expandedKeys = this.state.expandedKeys.slice(0)
|
||||
const _index = expandedKeys.indexOf(selectedKeys[0]);
|
||||
if (_index == -1) {
|
||||
expandedKeys.push(selectedKeys[0])
|
||||
expandedKeys.push(selectedKeys[0])
|
||||
} else {
|
||||
expandedKeys.splice( _index, 1)
|
||||
}
|
||||
this.setState({ expandedKeys })
|
||||
}
|
||||
|
||||
|
||||
this.props.onTreeSelect(selectedKeys, info)
|
||||
}
|
||||
}
|
||||
buildTree() {
|
||||
// TODO http://localhost:3007/tasks/xgffnuomytpj 这个实训没有文件树
|
||||
const { fileTreeData, onLoadData, fileTreeSelectedKeys } = this.props;
|
||||
if (!fileTreeData || fileTreeData.length === 0) {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
|
||||
const loop = (data) => {
|
||||
return data.map((item) => {
|
||||
|
|
@ -147,8 +147,8 @@ class CodeRepositoryView extends Component {
|
|||
});
|
||||
};
|
||||
const treeNodes = loop(fileTreeData);
|
||||
|
||||
|
||||
|
||||
|
||||
// selectable={false}
|
||||
return (
|
||||
<Tree
|
||||
|
|
@ -190,15 +190,15 @@ class CodeRepositoryView extends Component {
|
|||
var domArray = [];
|
||||
const pathArray = path.forEach ? path : [path]
|
||||
pathArray.forEach( (item, index) => {
|
||||
domArray.push(
|
||||
domArray.push(
|
||||
<p key={index} className={classNames({'blue-line': pathIndex == index})} onClick={ () => this.onPathChange(index, true) } >
|
||||
{item}
|
||||
{item}
|
||||
</p> )
|
||||
})
|
||||
|
||||
|
||||
return (
|
||||
<div className="codefile-all pl10">
|
||||
{domArray}
|
||||
{domArray}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -209,11 +209,11 @@ class CodeRepositoryView extends Component {
|
|||
axios.get(url,
|
||||
{
|
||||
// withCredentials: true
|
||||
}
|
||||
).then((response) => {
|
||||
}
|
||||
).then((response) => {
|
||||
tabIndex && $(`#codetab_con_${tabIndex}`).html('') // 清空 ‘正在连接命令行服务...’
|
||||
|
||||
if (response.data.game_id) {
|
||||
if (response.data.game_id) {
|
||||
// 重置ssh状态
|
||||
this.setSSHClosed(false);
|
||||
|
||||
|
|
@ -227,7 +227,7 @@ class CodeRepositoryView extends Component {
|
|||
var line_h = (navigator.userAgent.indexOf('Chrome') >= 0 ? 18 : 19);
|
||||
var rows = Math.round(h / line_h);
|
||||
var cols = parseInt(w / 9.9);
|
||||
|
||||
|
||||
response.data.width = w;
|
||||
response.data.height = h;
|
||||
response.data.line_h = line_h;
|
||||
|
|
@ -237,7 +237,7 @@ class CodeRepositoryView extends Component {
|
|||
// this.loadSshInIframe( response.data, tabIndex )
|
||||
|
||||
this.loadSshNormal(response.data, tabIndex, isReInit)
|
||||
|
||||
|
||||
}
|
||||
// console.log(response)
|
||||
}).catch((error) => {
|
||||
|
|
@ -257,7 +257,7 @@ class CodeRepositoryView extends Component {
|
|||
// $(".game_webssh").css({"min-height":h, "max-height":h});
|
||||
const container = $(`#codetab_con_${tabIndex}`);
|
||||
// ReactDOM.unmountComponentAtNode(container)
|
||||
// ReactDOM.render(<Webssh {...data}
|
||||
// ReactDOM.render(<Webssh {...data}
|
||||
// ></Webssh>, container);
|
||||
// this.setState({
|
||||
// sshData: data
|
||||
|
|
@ -273,7 +273,7 @@ class CodeRepositoryView extends Component {
|
|||
, height, width, line_h, rows, cols, } = data
|
||||
|
||||
let _domain = webssh_url || 'https://webssh.educoder.net';
|
||||
// window.location.host === "www.educoder.net" ?
|
||||
// window.location.host === "www.educoder.net" ?
|
||||
// 'https://webssh.educoder.net'
|
||||
// : 'https://testwebssh.educoder.net'
|
||||
const html = `<iframe src="${_domain}/?Host=${host}&Port=${port}&Username=${username}&Password=${password}&Gameid=${game_id}&Rows=${rows}&Tab=81&Columns=${cols}&Width=${width}&Height=${height}" style="width: 100%; border: 0px; min-height: 454px; max-height: 454px; " scrolling="no" id="game_webssh" class="game_webssh"></iframe>`
|
||||
|
|
@ -286,9 +286,9 @@ class CodeRepositoryView extends Component {
|
|||
if ($(`#codetab_con_${index} .terminal.xterm`).length === 1) { // 已经初始化过了
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.initSsh($, index);
|
||||
|
||||
|
||||
}
|
||||
/** multi ssh */
|
||||
setSSHClosed = (isClose) => {
|
||||
|
|
@ -318,7 +318,7 @@ class CodeRepositoryView extends Component {
|
|||
close_ssh_cocket_iframe = (id) => {
|
||||
/*
|
||||
关闭连接,清空tab content
|
||||
*/
|
||||
*/
|
||||
let _w = $(`.game_webssh_${id}`)[0].contentWindow
|
||||
_w && _w.postMessage({tp: 'close_ssh_cocket'}, "*");
|
||||
$(`#codetab_con_${id}`).html('')
|
||||
|
|
@ -326,7 +326,7 @@ class CodeRepositoryView extends Component {
|
|||
close_ssh_cocket_normal = (id) => {
|
||||
/*
|
||||
关闭连接,清空tab content
|
||||
*/
|
||||
*/
|
||||
// let _w = $(`.game_webssh_${id}`)[0].contentWindow
|
||||
// _w && _w.postMessage({tp: 'close_ssh_cocket'}, "*");
|
||||
// $(`#codetab_con_${id}`).html('')
|
||||
|
|
@ -338,7 +338,7 @@ class CodeRepositoryView extends Component {
|
|||
this.tabIndexChange(STABLE_SSH_TAB_ID)
|
||||
this.setState({ addtionalSSHArray })
|
||||
// game_webssh_${tabIndex} TODO
|
||||
|
||||
|
||||
this.close_ssh_cocket_normal(id)
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
|
@ -379,7 +379,7 @@ class CodeRepositoryView extends Component {
|
|||
|
||||
width={300}
|
||||
open={drawerOpen}
|
||||
|
||||
|
||||
onClose={() => showFilesDrawer( false )}
|
||||
>
|
||||
{ loadingFirstRepoFiles ? (
|
||||
|
|
@ -390,7 +390,7 @@ class CodeRepositoryView extends Component {
|
|||
</Drawer>
|
||||
|
||||
<ul id="blacktab_nav" className="">
|
||||
|
||||
|
||||
{ hide_code === false && <li id="codetab_nav_1" className={classNames('code-file-tab', 'eud-pointer', 'pr', 'blacktab_nomal', {'blacktab_hover':tabIndex===0 })} onClick={() => tabIndexChange(0)}>
|
||||
<a href="javascript:void(0);" className={classNames('tab_type', 'tab_color', {'fl': challenge.pathIndex === -1 || challenge.multiPath === true } )}>代码文件</a>
|
||||
|
||||
|
|
@ -402,23 +402,23 @@ class CodeRepositoryView extends Component {
|
|||
</div>
|
||||
</React.Fragment>
|
||||
: "" }
|
||||
|
||||
|
||||
</li> }
|
||||
|
||||
{shixun.webssh !== 0 &&
|
||||
<li id="codetab_nav_2" data-tab="2" className={classNames('add-webssh', 'blacktab_nomal', {'blacktab_hover':tabIndex===STABLE_SSH_TAB_ID })}
|
||||
{shixun.webssh !== 0 &&
|
||||
<li id="codetab_nav_2" data-tab="2" className={classNames('add-webssh', 'blacktab_nomal', {'blacktab_hover':tabIndex===STABLE_SSH_TAB_ID })}
|
||||
onClick={() => this.tabIndexChange(STABLE_SSH_TAB_ID)}>
|
||||
<a href="javascript:void(0);" className="tab_type tab_color">命令行</a>
|
||||
</li> }
|
||||
{
|
||||
{
|
||||
addtionalSSHArray.map( (item, index) => {
|
||||
return (<li id={`codetab_nav_${item}`} data-tab={item}
|
||||
className={classNames('add-webssh', 'blacktab_nomal', {'blacktab_hover':tabIndex===item })}
|
||||
return (<li id={`codetab_nav_${item}`} data-tab={item}
|
||||
className={classNames('add-webssh', 'blacktab_nomal', {'blacktab_hover':tabIndex===item })}
|
||||
onClick={() => this.tabIndexChange(item)}>
|
||||
<a href="javascript:void(0);" className="tab_type tab_color">命令行{index + 1}</a>
|
||||
<Tooltip title={ "关闭该命令行窗口"} disableFocusListener={true}>
|
||||
<i class="anticon anticon-close ant-tabs-close-x" onClick={(e) => this.onSSHTabClose(item, e)}>
|
||||
<svg viewBox="64 64 896 896" class="" data-icon="close" width="1em" height="1em"
|
||||
<svg viewBox="64 64 896 896" class="" data-icon="close" width="1em" height="1em"
|
||||
fill="currentColor" aria-hidden="true">
|
||||
<path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path>
|
||||
</svg>
|
||||
|
|
@ -429,7 +429,7 @@ class CodeRepositoryView extends Component {
|
|||
}
|
||||
|
||||
{/* */}
|
||||
{ shixun.webssh !== 0 && shixun.multi_webssh == true && addtionalSSHArray.length < totalAddtionalTabCount
|
||||
{ shixun.webssh !== 0 && shixun.multi_webssh == true && addtionalSSHArray.length < totalAddtionalTabCount
|
||||
&& sshIsClosed === false && <li id="codetab_nav_add" className="c_white" style={{paddingLeft:'10px'}}>
|
||||
<Tooltip title={ "新开命令行窗口"} disableFocusListener={true}>
|
||||
<a href="javascript:void(0);" className="tab_type tab_color"
|
||||
|
|
@ -437,32 +437,32 @@ class CodeRepositoryView extends Component {
|
|||
>+</a>
|
||||
</Tooltip>
|
||||
</li> }
|
||||
|
||||
|
||||
{ tabIndex === 0 && <h3 id="save_status" className="ml15 mt7 fl color-grey font-14" style={{fontWeight: 'normal'}}>
|
||||
{codeStatus === 0 ? '已修改' : (codeStatus === 1 ? '保存中...' : '已保存' ) }
|
||||
</h3> }
|
||||
<div className="fr -horizontal">
|
||||
|
||||
{ /**/ }
|
||||
{
|
||||
<WebSSHTimer game={game} showTimerProp={this.isSSHTabIndex()}
|
||||
{
|
||||
<WebSSHTimer game={game} showTimerProp={this.isSSHTabIndex()}
|
||||
reInitSsh={this.initSsh} setSSHClosed={this.setSSHClosed}></WebSSHTimer>
|
||||
}
|
||||
|
||||
{ showUpdateButton &&
|
||||
<React.Fragment>
|
||||
|
||||
|
||||
<a className="iconButton" onClick={()=>{ onShowUpdateDialog() }}>
|
||||
<Tooltip title={ "更新通知"} disableFocusListener={true}>
|
||||
<i className="iconfont icon-gonggao font-20 "></i>
|
||||
</Tooltip>
|
||||
</a>
|
||||
|
||||
|
||||
<span className="dot"></span>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
{ !shixun.code_hidden && tabIndex === 0 &&
|
||||
{ !shixun.code_hidden && tabIndex === 0 &&
|
||||
<a className="iconButton" onClick={showFilesDrawer.bind(this, true)} >
|
||||
<Tooltip title={ "文件目录"} disableFocusListener={true}>
|
||||
<i className="iconfont icon-wenjian font-18 "></i>
|
||||
|
|
@ -471,10 +471,10 @@ class CodeRepositoryView extends Component {
|
|||
}
|
||||
|
||||
<span id="return_last_code">
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{ challenge.pathIndex !== -1 && game.status === 2 && tabIndex === 0 &&
|
||||
this.props.readRepoTimeout !== true &&
|
||||
{ challenge.pathIndex !== -1 && game.status === 2 && tabIndex === 0 &&
|
||||
this.props.readRepoTimeout !== true &&
|
||||
<a href="javascript:void(0);" className="iconButton" id="reset_success_game_code" onClick={showResetPassedCodeDialog}>
|
||||
<Tooltip title={ "加载上次通过的代码"} disableFocusListener={true}>
|
||||
<i className="iconfont icon-fanhuishangcidaima font-20 "></i>
|
||||
|
|
@ -483,7 +483,7 @@ class CodeRepositoryView extends Component {
|
|||
}
|
||||
|
||||
{
|
||||
challenge.pathIndex !== -1 && tabIndex === 0 && this.props.readRepoTimeout !== true &&
|
||||
challenge.pathIndex !== -1 && tabIndex === 0 && this.props.readRepoTimeout !== true &&
|
||||
<a href="javascript:void(0);" className="iconButton" id="reset_game_code" onClick={showResetCodeDialog}>
|
||||
<Tooltip title={ "恢复初始代码"} disableFocusListener={true}>
|
||||
<i className="iconfont icon-zhongzhi font-20 "></i>
|
||||
|
|
@ -492,41 +492,41 @@ class CodeRepositoryView extends Component {
|
|||
}
|
||||
|
||||
{
|
||||
tabIndex === 0 && this.props.readRepoTimeout !== true &&
|
||||
tabIndex === 0 && this.props.readRepoTimeout !== true &&
|
||||
<a href="javascript:void(0);" className="iconButton" id="setting" onClick={() => showSettingDrawer(true)}>
|
||||
<Tooltip title={ "设置"} disableFocusListener={true}>
|
||||
<i className="iconfont icon-shezhi " style={{fontSize: '19px'}}></i>
|
||||
</Tooltip>
|
||||
</a>
|
||||
}
|
||||
|
||||
|
||||
<a href="javascript:void(0);" className="mr15 iconButton" onClick={onRepositoryViewExpand} id="extend_and_zoom">
|
||||
<Tooltip id="tooltip-icon-expand" title={ evaluateViewExpanded ? "收起" : "展开"}>
|
||||
{/*<i className="fa font-16 fa-expand"></i>*/}
|
||||
<i className={ evaluateViewExpanded ? "font-18 iconfont icon-shousuo" : "iconfont icon-zhankai font-18" }></i>
|
||||
</Tooltip>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
<div className="cl"></div>
|
||||
</ul>
|
||||
<div className="cl"></div>
|
||||
|
||||
|
||||
<div id="codetab_con_1" style={{display: 'block', flex: 'auto'}} style={ tabIndex === 0 ? {display: 'block'} : {display: 'none'} }>
|
||||
{/* 没必要显示这个,注释掉了 */}
|
||||
{/* { !isEditablePath &&
|
||||
{/* { !isEditablePath &&
|
||||
<Tooltip title={ "当前文件路径(只读)"}>
|
||||
<div className="codePath">
|
||||
{currentPath}
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
} */}
|
||||
{this.props.readRepoTimeout === true ? <div className="readRepoFailed">
|
||||
代码加载失败,<a className="retry"
|
||||
代码加载失败,<a className="retry"
|
||||
onClick={() => this.props.fetchRepositoryCode(this.props, null, null, true, true)}>重试</a>
|
||||
</div> :
|
||||
<React.Fragment>
|
||||
<div className="codemirrorBackground"
|
||||
<div className="codemirrorBackground"
|
||||
style={{ backgroundImage: `url('${notEditablePathImg}')`
|
||||
, display: (isEditablePath || this.props.shixun && this.props.shixun.code_edit_permission ? 'none' : 'block') }}></div>
|
||||
{/*<textarea className = "" id="extend-challenge-file-edit" name="content">{repositoryCode}</textarea>*/}
|
||||
|
|
@ -536,17 +536,17 @@ class CodeRepositoryView extends Component {
|
|||
</React.Fragment>
|
||||
}
|
||||
</div>
|
||||
<div id="codetab_con_81" className="undis -relative"
|
||||
<div id="codetab_con_81" className="undis -relative"
|
||||
style={ { color: '#fff', display: tabIndex === STABLE_SSH_TAB_ID ? 'block' : 'none', 'marginLeft': '2px'} }>
|
||||
{/* { tabIndex === STABLE_SSH_TAB_ID && this.state.sshData && <Webssh {...this.state.sshData} ></Webssh> } */}
|
||||
</div>
|
||||
<div id="codetab_con_82" className="undis -relative"
|
||||
<div id="codetab_con_82" className="undis -relative"
|
||||
style={ { color: '#fff', display: tabIndex === 82 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '30px' } }>
|
||||
</div>
|
||||
<div id="codetab_con_83" className="undis -relative"
|
||||
<div id="codetab_con_83" className="undis -relative"
|
||||
style={ { color: '#fff', display: tabIndex === 83 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '30px'} }>
|
||||
</div>
|
||||
<div id="codetab_con_84" className="undis -relative"
|
||||
<div id="codetab_con_84" className="undis -relative"
|
||||
style={ { color: '#fff', display: tabIndex === 84 ? 'block' : 'none', 'marginLeft': '2px', 'paddingBottom': '30px'} }>
|
||||
</div>
|
||||
<div id="codetab_con_3" className="undis -relative" style={{display: 'none'}}></div>
|
||||
|
|
@ -554,13 +554,13 @@ class CodeRepositoryView extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
/*
|
||||
/*
|
||||
<%= Redmine::CodesetUtil.replace_invalid_utf8(@content) %>
|
||||
, overflow: 'scroll' ref="editor"
|
||||
, overflow: 'scroll' ref="editor"
|
||||
<CodeMirror style={{height: '100%'}} value={repositoryCode} onChange={onRepositoryCodeUpdate} options={cmOptions} />
|
||||
|
||||
<iframe src="https://testwebssh.educoder.net/?Host=10.9.81.28&Port=44940&Username=root&Password=123123&Gameid=2618&Rows=24&Tab=2"
|
||||
<iframe src="https://testwebssh.educoder.net/?Host=10.9.81.28&Port=44940&Username=root&Password=123123&Gameid=2618&Rows=24&Tab=2"
|
||||
style={{width: '100%', border: '0px', minHeight: '440px', maxHeight: '440px'}} scrolling="no" id="game_webssh" className="game_webssh"></iframe>
|
||||
*/
|
||||
|
||||
export default CodeRepositoryView;
|
||||
export default CodeRepositoryView;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
import CodeMirror from 'react-codeMirror'
|
||||
import CodeMirror from 'react-codemirror'
|
||||
|
||||
require('codemirror/lib/codemirror.css');
|
||||
require('codemirror/mode/javascript/javascript');
|
||||
|
|
@ -28,13 +28,13 @@ class TestCodeMirror extends Component {
|
|||
|
||||
componentDidMount() {
|
||||
var readOnlyLines = [0,1,2,3,8];
|
||||
|
||||
|
||||
this.refs.editor.getCodeMirror().on('beforeChange',function(cm,change) {
|
||||
console.log('change.from.line', change.from.line)
|
||||
if ( readOnlyLines.indexOf(change.from.line) !== -1
|
||||
if ( readOnlyLines.indexOf(change.from.line) !== -1
|
||||
// 有问题:如果用回车将有内容的行挤到不可编辑的行,那么无法删除掉不可编辑行里的内容了
|
||||
// 解决办法:将所需的行数固定写好,禁用掉回车键。
|
||||
// || change.from.line > ( readOnlyLines[readOnlyLines.length -1] + 1 )
|
||||
// || change.from.line > ( readOnlyLines[readOnlyLines.length -1] + 1 )
|
||||
) {
|
||||
change.cancel();
|
||||
}
|
||||
|
|
@ -60,4 +60,4 @@ class TestCodeMirror extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default TestCodeMirror;
|
||||
export default TestCodeMirror;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,30 @@ import { Link } from 'react-router-dom';
|
|||
|
||||
|
||||
class NewFooter extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state={
|
||||
forge_footer: undefined
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
|
||||
//获取游览器地址
|
||||
try {
|
||||
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
|
||||
this.setState({
|
||||
forge_footer: chromesettingArray.footer
|
||||
})
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
showhtml=(htmlString)=>{
|
||||
var html = {__html:htmlString};
|
||||
return <div dangerouslySetInnerHTML={html}></div> ;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {forge_footer} = this.state;
|
||||
return (
|
||||
<div className="newFooter edu-txt-center ">
|
||||
<style>
|
||||
|
|
@ -21,30 +44,33 @@ class NewFooter extends Component {
|
|||
`
|
||||
}
|
||||
</style>
|
||||
{
|
||||
forge_footer && this.showhtml(forge_footer)
|
||||
}
|
||||
|
||||
<div className="inner-footer_con">
|
||||
<ul className="clearfix inner-footernav">
|
||||
<li><a href="/" className="fl" target="_blank">网站首页</a></li>
|
||||
<li><Link to="/help/about_us" className="fl" target="_blank">关于我们</Link></li>
|
||||
<li><Link to="/help/contact_us" className="fl" target="_blank">联系我们</Link></li>
|
||||
<li><Link to="/help/cooperatives" className="fl" target="_blank">合作伙伴</Link></li>
|
||||
<li><Link to="/help/agreement" className="fl" target="_blank">服务协议</Link></li>
|
||||
<li><Link to="/help/help_center" className="fl" target="_blank">帮助中心</Link></li>
|
||||
<li><Link to="/help/feedback" className="fl" target="_blank">意见反馈</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p className="footer_con-p inline lineh-30 font-14">
|
||||
<span className="font-18 fl">©</span> {moment().year()} EduCoder
|
||||
<a style={{"color":"#888"}} target="_blank" href="http://beian.miit.gov.cn/" className="ml15 mr15">湘ICP备17009477号</a>
|
||||
<a style={{"color":"#888"}} target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=43019002000962" className="mr15">
|
||||
<img className="vertical4" src={require('./beian.png')}/>湘公网安备43019002000962号
|
||||
</a>
|
||||
<a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside. <span
|
||||
className="mr15">版权所有 湖南智擎科技有限公司</span>
|
||||
</p>
|
||||
</div>
|
||||
<div className="cl"></div>
|
||||
{/*<div className="inner-footer_con">*/}
|
||||
{/*<ul className="clearfix inner-footernav">*/}
|
||||
{/*<li><a href="/" className="fl" target="_blank">网站首页</a></li>*/}
|
||||
{/*<li><Link to="/help/about_us" className="fl" target="_blank">关于我们</Link></li>*/}
|
||||
{/*<li><Link to="/help/contact_us" className="fl" target="_blank">联系我们</Link></li>*/}
|
||||
{/*<li><Link to="/help/cooperatives" className="fl" target="_blank">合作伙伴</Link></li>*/}
|
||||
{/*<li><Link to="/help/agreement" className="fl" target="_blank">服务协议</Link></li>*/}
|
||||
{/*<li><Link to="/help/help_center" className="fl" target="_blank">帮助中心</Link></li>*/}
|
||||
{/*<li><Link to="/help/feedback" className="fl" target="_blank">意见反馈</Link></li>*/}
|
||||
{/*</ul>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div>*/}
|
||||
{/*<p className="footer_con-p inline lineh-30 font-14">*/}
|
||||
{/*<span className="font-18 fl">©</span> {moment().year()} EduCoder*/}
|
||||
{/*<a style={{"color":"#888"}} target="_blank" href="http://beian.miit.gov.cn/" className="ml15 mr15">湘ICP备17009477号</a>*/}
|
||||
{/*<a style={{"color":"#888"}} target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=43019002000962" className="mr15">*/}
|
||||
{/*<img className="vertical4" src={require('./beian.png')}/>湘公网安备43019002000962号*/}
|
||||
{/*</a>*/}
|
||||
{/*<a href="https://team.trustie.net" style={{"color":"#888"}} target="_blank">Trustie</a> & IntelliDE inside. <span*/}
|
||||
{/*className="mr15">版权所有 湖南智擎科技有限公司</span>*/}
|
||||
{/*</p>*/}
|
||||
{/*</div>*/}
|
||||
{/*<div className="cl"></div>*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,21 +76,14 @@ class NewHeader extends Component {
|
|||
goshowqqgtounp:false,
|
||||
visiblemyss:false,
|
||||
}
|
||||
// console.log("176")
|
||||
// console.log(props);
|
||||
// console.log("NewHeader1234567890");
|
||||
// console.log(this.props);
|
||||
}
|
||||
componentDidUpdate = (prevProps) => {
|
||||
// console.log("componentDidMount2");
|
||||
// console.log(this.state.mygetHelmetapi2);
|
||||
if(this.state.mygetHelmetapi2===undefined){
|
||||
this.getAppdata();
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
// console.log("componentDidMount1");
|
||||
this.getAppdata();
|
||||
this.getAppdata();
|
||||
window._header_componentHandler = this;
|
||||
|
||||
//下拉框的显示隐藏
|
||||
|
|
@ -698,7 +691,7 @@ submittojoinclass=(value)=>{
|
|||
this.setState({
|
||||
mygetHelmetapi2: undefined
|
||||
});
|
||||
document.title = "EduCoder";
|
||||
// document.title = "Forge";
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
|
|
@ -737,21 +730,17 @@ submittojoinclass=(value)=>{
|
|||
try {
|
||||
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
|
||||
var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
|
||||
// console.log("NewHeaderNewHeaderNewHeader");
|
||||
// console.log(chromesettingArray);
|
||||
// console.log(chromesettingresponseArray);
|
||||
|
||||
this.setState({
|
||||
mygetHelmetapi2:chromesettingArray
|
||||
});
|
||||
if (chromesettingArray.tab_logo_url) {
|
||||
this.gettablogourldata(chromesettingresponseArray);
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
this.setState({
|
||||
mygetHelmetapi2:chromesettingArray
|
||||
});
|
||||
if (chromesettingArray.tab_logo_url) {
|
||||
this.gettablogourldata(chromesettingresponseArray);
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
}catch (e) {
|
||||
console.log("head获取游览器配置失败 重新请求开始读取配置");
|
||||
this.geturlsdata();
|
||||
// console.log("head获取游览器配置失败 重新请求开始读取配置");
|
||||
this.geturlsdata();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -798,25 +787,40 @@ submittojoinclass=(value)=>{
|
|||
|
||||
matchpaths=(url)=>{
|
||||
const {match} = this.props;
|
||||
if (url=== '/forums'&&match.path === '/forums') {
|
||||
return true
|
||||
} else if (url.startsWith('/shixuns')&&match.path.startsWith('/shixuns')) {
|
||||
return true
|
||||
if (url=== '/forums'&&match.path === '/forums') {
|
||||
return true
|
||||
} else if (url.startsWith('/projects')&&match.path.startsWith('/projects')) {
|
||||
return true
|
||||
}else if (url.startsWith('/paths')&&match.path.startsWith('/paths')) {
|
||||
return true
|
||||
return true
|
||||
} else if (url.startsWith('/courses')&&match.path.startsWith('/courses')) {
|
||||
return true
|
||||
return true
|
||||
}else if (url.startsWith('/competitions')&&match.path.startsWith('/competitions')) {
|
||||
return true
|
||||
}else if (url.startsWith('/crowdsourcing')&&match.path.startsWith('/crowdsourcing')) {
|
||||
return true
|
||||
}else if(url.startsWith('/moop_cases')&&match.path.startsWith('/moop_cases')){
|
||||
return true
|
||||
}else if(url.startsWith('/developer')&&match.path.startsWith('/developer')){
|
||||
return true
|
||||
}else {
|
||||
return false
|
||||
return true
|
||||
}else if (url.startsWith('/statistics')&&match.path.startsWith('/statistics')) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
// if (url=== '/forums'&&match.path === '/forums') {
|
||||
// return true
|
||||
// } else if (url.startsWith('/shixuns')&&match.path.startsWith('/shixuns')) {
|
||||
// return true
|
||||
// }else if (url.startsWith('/paths')&&match.path.startsWith('/paths')) {
|
||||
// return true
|
||||
// } else if (url.startsWith('/courses')&&match.path.startsWith('/courses')) {
|
||||
// return true
|
||||
// }else if (url.startsWith('/competitions')&&match.path.startsWith('/competitions')) {
|
||||
// return true
|
||||
// }else if (url.startsWith('/crowdsourcing')&&match.path.startsWith('/crowdsourcing')) {
|
||||
// return true
|
||||
// }else if(url.startsWith('/moop_cases')&&match.path.startsWith('/moop_cases')){
|
||||
// return true
|
||||
// }else if(url.startsWith('/developer')&&match.path.startsWith('/developer')){
|
||||
// return true
|
||||
// }else {
|
||||
// return false
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -830,6 +834,7 @@ submittojoinclass=(value)=>{
|
|||
const isLogin = true; // 这里不会出现未登录的情况,服务端在服务端路由时发现如果是未登录,则跳转到登录页了。
|
||||
const {match} = this.props;
|
||||
|
||||
|
||||
let {Addcoursestypes,
|
||||
tojoinitemtype,
|
||||
tojoinclasstitle,
|
||||
|
|
@ -878,14 +883,9 @@ submittojoinclass=(value)=>{
|
|||
|
||||
let headtypes='/';
|
||||
|
||||
// console.log("mygetHelmetapi2");
|
||||
// console.log(mygetHelmetapi2);
|
||||
if(mygetHelmetapi2) {
|
||||
if (mygetHelmetapi2.navbar) {
|
||||
if (mygetHelmetapi2.navbar.length > 0) {
|
||||
// console.log("mygetHelmetapi2.navbar.length>0====-=-=--=-=-=-=");
|
||||
//
|
||||
// console.log(match.path);
|
||||
if (match.path === '/') {
|
||||
if (headtypesonClickbool === false) {
|
||||
headtypes = undefined;
|
||||
|
|
@ -904,10 +904,6 @@ submittojoinclass=(value)=>{
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(mygetHelmetapi2);
|
||||
// console.log("NewHeadermygetHelmetapi123123123123");
|
||||
|
||||
let shixuntype=false;
|
||||
let pathstype=false;
|
||||
let coursestypes=false;
|
||||
|
|
@ -1005,30 +1001,42 @@ submittojoinclass=(value)=>{
|
|||
mygetHelmetapi2!==undefined&&mygetHelmetapi2.navbar!==null&&mygetHelmetapi2.navbar!==undefined&&mygetHelmetapi2.navbar.length>0?
|
||||
<div className="head-nav pr" id={"head-navpre1"}>
|
||||
<ul id="header-nav">
|
||||
{/*<li className={`${activeIndex === true ? 'active' : ''}`}><a href="/">首页</a></li>*/}
|
||||
{/*<li><a href={this.props.Headertop===undefined?"":this.props.Headertop.shixun_paths_url}>实训路径</a></li>*/}
|
||||
{
|
||||
mygetHelmetapi2.navbar && mygetHelmetapi2.navbar.map((item,key)=>{
|
||||
// console.log("headtypes");
|
||||
// console.log(headtypes);hidden
|
||||
var str=new RegExp("http");
|
||||
var strbool=false;
|
||||
//test方法返回值为(true或者false)
|
||||
if(item.link){
|
||||
if(str.test(item.link)===true){
|
||||
strbool=true
|
||||
}else{
|
||||
strbool=false
|
||||
}
|
||||
}
|
||||
// console.log(item.hidden);
|
||||
var new_link = item.link;
|
||||
var user_login = this.props.user && this.props.user.login;
|
||||
var is_hidden = item.hidden
|
||||
|
||||
if(new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1){
|
||||
if(user_login){
|
||||
if(new_link.indexOf("courses") > -1){
|
||||
new_link = new_link.replace(/courses/g,"users/"+user_login + "/courses")
|
||||
}else if(new_link.indexOf("contests") > -1){
|
||||
new_link = new_link.replace(/contests/g,"users/"+user_login + "/contests")
|
||||
}
|
||||
|
||||
}else{
|
||||
is_hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
var str=new RegExp("projects");
|
||||
var strbool=false;
|
||||
if(item.link){
|
||||
if(str.test(item.link)===true){
|
||||
strbool=true
|
||||
}else{
|
||||
strbool=false
|
||||
}
|
||||
}
|
||||
return(
|
||||
<li key={key} onClick={()=>this.headtypesonClick(item.link,true)} className={`${this.matchpaths(item.link)===true?'pr active':'pr'}`} style={item.hidden==false?{display: 'block'}:{display: 'none'}}>
|
||||
<li key={key} onClick={()=>this.headtypesonClick(item.link,true)} className={`${this.matchpaths(item.link)===true?'pr active':'pr'}`} style={!is_hidden?{display: 'block'}:{display: 'none'}}>
|
||||
{
|
||||
strbool===true?
|
||||
<a href={item.link}>{item.name}</a>
|
||||
strbool?
|
||||
<Link to={item.link}>{item.name}</Link>
|
||||
|
||||
:
|
||||
<Link to={item.link}>{item.name}</Link>
|
||||
<a href={new_link} target='_blank'>{item.name}</a>
|
||||
}
|
||||
</li>
|
||||
)
|
||||
|
|
@ -1047,63 +1055,21 @@ submittojoinclass=(value)=>{
|
|||
`
|
||||
}
|
||||
</style>
|
||||
{/*<li className={`pr questionbanks`}>*/}
|
||||
{/* <Popover placement="bottom" content={contents} trigger="click" >*/}
|
||||
{/* <div className=" sortinxdirection mr10">*/}
|
||||
{/* <div style={{*/}
|
||||
{/* color:"#fff"*/}
|
||||
{/* }}>*/}
|
||||
{/* 题库*/}
|
||||
{/* </div>*/}
|
||||
{/* </div>*/}
|
||||
{/* </Popover>*/}
|
||||
{/*</li>*/}
|
||||
|
||||
<li
|
||||
style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth === null ? 'none' : 'block'}}
|
||||
><a href={this.props.Headertop === undefined ? "" : this.props.Headertop.auth}>工程认证</a></li>
|
||||
|
||||
<li className="fl edu-menu-panel careershover "
|
||||
style={{display: this.props.Headertop === undefined ?'none' : this.props.Headertop.career_url.length > 0 ? 'block' : 'none'}}>
|
||||
<a>职业路径</a>
|
||||
<div
|
||||
style={{display: this.props.Headertop === undefined ?'none' : this.props.Headertop.career_url.length > 0 ? 'block' : 'none'}}>
|
||||
<ul className="edu-menu-list edu-menu-listnew " style={{top:'60px'}}>
|
||||
{this.props.Headertop === undefined ? "" : this.props.Headertop.career_url.map((item, key) => {
|
||||
return(
|
||||
<li key={key}><i className="iconfont icon-java left careersiconfont"
|
||||
style={{color: '#000 important'}}
|
||||
></i><a style={{width: '83%'}}
|
||||
href={item.url}>{item.name}</a></li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li><Link to={`/projects`}>开源项目</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
:
|
||||
<div className="head-nav pr" id={"head-navpre3"}>
|
||||
|
||||
<ul id="header-nav">
|
||||
{/*<li className={`${activeIndex === true ? 'active' : ''}`}><a href="/">首页</a></li>*/}
|
||||
<li className={`${activePaths === true ? 'pr active' : 'pr'}`}>
|
||||
<Link to={'/projects'}>开源项目</Link>
|
||||
</li>
|
||||
|
||||
{/*<li><a href={this.props.Headertop===undefined?"":this.props.Headertop.shixun_paths_url}>实训路径</a></li>*/}
|
||||
<li className={`${activePaths === true ? 'pr active' : 'pr'}`}>
|
||||
<Link to={this.props.Headertop===undefined?"":'/paths'}>实践课程</Link>
|
||||
</li>
|
||||
|
||||
{/*<li><a href={this.props.Headertop===undefined?"":'/courses'}>课堂</a></li>*/}
|
||||
<li className={`${coursestype === true ? 'pr active' : 'pr'}`}>
|
||||
{/*<a href={this.props.Headertop===undefined?"":this.props.Headertop.course_url}>课堂</a>*/}
|
||||
<Link to={this.props.Headertop===undefined?"":'/courses'}>翻转课堂</Link>
|
||||
</li>
|
||||
<li className={`${activeShixuns === true ? 'pr active' : 'pr'}`}>
|
||||
<Link to="/shixuns">实训项目</Link>
|
||||
{/*<img src={getImageUrl("images/educoder/hot-h.png")} className="nav-img">*/}
|
||||
{/*</img>*/}
|
||||
</li>
|
||||
|
||||
<li className="fl edu-menu-panel careershover "
|
||||
|
|
@ -1125,17 +1091,10 @@ submittojoinclass=(value)=>{
|
|||
</div>
|
||||
</li>
|
||||
|
||||
{/*<li className=""><a href={"/libraries"}>教学案例</a></li>*/}
|
||||
<li className={`${activeCompetitions === true ? 'pr active' : 'pr'}`}>
|
||||
<a href={this.props.Headertop===undefined?"":this.props.Headertop.competitions_url}>在线竞赛</a>
|
||||
{/*<img className="roundedRectangles"*/}
|
||||
{/* src={require('./roundedRectangle.png')}*/}
|
||||
{/*/>*/}
|
||||
</li>
|
||||
<li className={`${activeMoopCases === true ? 'pr active' : 'pr'}`}> <Link to={`/moop_cases`}>教学案例</Link></li>
|
||||
{/*<li className={`${activePackages === true ? 'pr active' : 'pr'}`}>*/}
|
||||
{/*<Link to={'/crowdsourcing'}>众包创新</Link>*/}
|
||||
{/*</li>*/}
|
||||
<li className={`${activeForums === true ? 'active' : ''}`}> <Link to={this.props.Headertop===undefined?"":this.props.Headertop.topic_url}>交流问答</Link></li>
|
||||
<li
|
||||
style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.auth===null? 'none' : 'block'}}
|
||||
|
|
@ -1144,11 +1103,6 @@ submittojoinclass=(value)=>{
|
|||
</div>
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
{
|
||||
`
|
||||
|
|
@ -1165,7 +1119,6 @@ submittojoinclass=(value)=>{
|
|||
</style>
|
||||
<div className="posi-searchs" >
|
||||
<div className="search-all clearfix">
|
||||
{/*<!--<a href="javascript:void(0)" className="search-clear fl" onclick="closeSearch();">×</a>-->*/}
|
||||
<div className="fl pr search-clear edu-menu-panel" style={{display: 'none'}}>
|
||||
<input type="hidden" id="search_type" value="1"></input>
|
||||
<span className="searchkey">实训</span>
|
||||
|
|
@ -1176,9 +1129,6 @@ submittojoinclass=(value)=>{
|
|||
<li><a>用户</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{/*<input type="text" className="search-input fl" id="search-input" */}
|
||||
{/*onKeyDown={this.onKeywordSearchKeyDown} name="search_keyword" placeholder="搜索实训项目"/>*/}
|
||||
{/*搜索框*/}
|
||||
{showSearchOpentype===true?<div
|
||||
className={"HeaderSearch"}
|
||||
onBlur={(e)=>this.hideshowSearchOpen(e)} onMouseLeave={()=>this.setevaluatinghides()}>
|
||||
|
|
@ -1192,35 +1142,21 @@ submittojoinclass=(value)=>{
|
|||
autoFocus={true}
|
||||
/>
|
||||
</div>:""}
|
||||
|
||||
{/*<a className="search-icon fl" id="header_keyword_search" onClick={this.onKeywordSearch}>*/}
|
||||
{/*/!*<i className="fa fa-search font-16 mt23 color-grey-6"></i>*!/*/}
|
||||
{/*<i className="iconfont icon-sousuo color-blue"></i>*/}
|
||||
|
||||
{/*</a>*/}
|
||||
{/* TODO 需要服务端接口提供最近搜索
|
||||
<div className="search-content none" style="width: 86%;left: 0px;">
|
||||
<div className="search-title">最近搜索</div>
|
||||
<div><a href="javascript:void(0)" className="search_history">绿盟</a></div>
|
||||
<div><a href="javascript:void(0)" className="search_history">qwe</a></div>
|
||||
</div>*/}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/*<span className="font-15 fr mt17">
|
||||
<%= link_to '登录', signin_path, :className => "mr5" %>
|
||||
<em className="vertical-line"></em>
|
||||
<%= link_to '注册', user_join_path, :className => "ml5" %>
|
||||
</span>*/}
|
||||
{ user===undefined?
|
||||
<span className="font-15 fr mt17 ml5 mr25">
|
||||
<a onClick={()=>this.educoderlogin()} className="mr5 color-white">登录</a>
|
||||
<em className="vertical-line"></em>
|
||||
<a href={"/register"} className="mr5 color-white">注册</a>
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.register_url &&
|
||||
<span><em className="vertical-line"></em><a className="mr5 color-white" href={`${mygetHelmetapi2.new_course.register_url}`} target="_blank">注册</a></span>
|
||||
}
|
||||
</span> :user.login===""?<span className="font-15 fr mt17 ml5 mr25">
|
||||
<a onClick={()=>this.educoderlogin()} className="mr5 color-white">登录</a>
|
||||
<em className="vertical-line"></em>
|
||||
<a href={"/register"} className="mr5 color-white">注册</a>
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.register_url &&
|
||||
<span><em className="vertical-line"></em><a className="mr5 color-white" href={`${mygetHelmetapi2.new_course.register_url}`} target="_blank">注册</a></span>
|
||||
}
|
||||
</span>:
|
||||
<div className="fr edu-menu-panel mr25" style={{height:'60px'}}>
|
||||
<a href={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/courses`} className="fl ml15">
|
||||
|
|
@ -1228,150 +1164,75 @@ submittojoinclass=(value)=>{
|
|||
src={getImageUrl(`images/`+user.image_url)} width="34">
|
||||
</img>
|
||||
</a>
|
||||
<ul className="edu-menu-list" style={{top:'60px'}}>
|
||||
{/*<span className="bor-bottom-greyE currentName task-hide">{user.username}</span>*/}
|
||||
<li><Link to={`/users/${this.props.current_user.login}/courses`}>我的个人主页</Link></li>
|
||||
{coursestypes===true?"":<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/courses`}>{this.props.user&&this.props.user.main_site===false?"我的课堂":"我的翻转课堂"}</Link></li>}
|
||||
{/* p 老师 l 学生 */}
|
||||
{shixuntype===true?"":<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/shixuns`}>我的实训项目</Link></li>}
|
||||
{pathstype===true?"":<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/paths`}>{this.props.user&&this.props.user.main_site===false?"我的课程":"我的实践课程"}</Link></li>}
|
||||
{this.props.user&&this.props.user.main_site===true?<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/projects`}>我的开发项目</Link></li>:""}
|
||||
{/*<li><Link to={`/users/${this.props.current_user===undefined?"":this.props.current_user.login}/package`}>我的众包</Link></li>*/}
|
||||
<li style={{display: this.props.Headertop === undefined ? 'none' : this.props.Headertop.customer_management_url===null || this.props.Headertop.customer_management_url===""? 'none' : 'block'}}>
|
||||
<a href={this.props.Headertop === undefined ? '' : this.props.Headertop.customer_management_url}>客户管理</a>
|
||||
</li>
|
||||
<ul className="edu-menu-list" style={{top:'60px', 'text-align': 'center'}}>
|
||||
{
|
||||
this.props.Headertop && this.props.Headertop.college_identifier &&
|
||||
<li><a href={`/colleges/${this.props.Headertop.college_identifier}/statistics`}>学院统计</a></li>
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.edit_account &&
|
||||
<li><a href={`${mygetHelmetapi2.new_course.edit_account}`} target="_blank">修改资料</a></li>
|
||||
}
|
||||
{
|
||||
this.props.Headertop && this.props.Headertop.laboratory_user &&
|
||||
<li><a href={this.props.Headertop.laboratory_admin_url}>后台管理</a></li>
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.my_courses &&
|
||||
<li><a href={`${mygetHelmetapi2.new_course.my_courses}`} target="_blank">我的课程</a></li>
|
||||
}
|
||||
{/*{*/}
|
||||
{/*mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.my_projects &&*/}
|
||||
{/*<li><a href={`${mygetHelmetapi2.new_course.my_projects}`} target="_blank">我的项目</a></li>*/}
|
||||
{/*}*/}
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.my_projects &&
|
||||
<li><Link to={`/users/${this.props.current_user.login}/projects`} >我的项目</Link></li>
|
||||
}
|
||||
|
||||
<li><a href={`/account/profile`}>账号管理</a></li>
|
||||
{/*<li><a onClick={()=>this.educoderlogin()} >登入测试接口</a></li>*/}
|
||||
{/*<li><a onClick={()=>this.trialapplications()} >试用申请</a> </li>*/}
|
||||
{/*<li><Link to={`/interest`}>兴趣页</Link></li>*/}
|
||||
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.my_organ &&
|
||||
<li><a href={`${mygetHelmetapi2.new_course.my_organ}`} target="_blank">我的组织</a></li>
|
||||
}
|
||||
<li className="bor-top-greyE">
|
||||
|
||||
{/*<a onClick={()=>this.educoderlogin()} >登录</a>*/}
|
||||
<a onClick={()=>this.educoderloginysl()}>退出</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
{/*href="https://www.educoder.net/login"*/}
|
||||
<div className="fr head-right">
|
||||
{/*{ loadHeader()}*/}
|
||||
{showSearchOpentype===true?"":this.props.user&&this.props.user.main_site===true?<a id="search-open" className="fl mr30 headIcon" onClick={(e)=>this.showSearchOpen(e)}>
|
||||
{/*"/images/educoder/icon/search.svg"
|
||||
<img src={getImageUrl(`images/educoder/icon/search.svg`)} /> */}
|
||||
|
||||
|
||||
<i className="iconfont icon-sousuo color-white"></i>
|
||||
</a>:""}
|
||||
|
||||
{/*</div>*/}
|
||||
<div className="fl mr30 edu-menu-panel headIcon">
|
||||
{
|
||||
this.props.user&&this.props.user.login ?
|
||||
<div className="fl mr30 edu-menu-panel headIcon">
|
||||
|
||||
|
||||
<i className="iconfont icon-tianjiafangda color-white"></i>
|
||||
<i className="iconfont icon-tianjiafangda color-white"></i>
|
||||
|
||||
<div className="edu-menu-list" style={{top: '60px',width:"240px"}}>
|
||||
<div className="overPart"></div>
|
||||
<ul className={coursestypes===true&&this.props.user&&this.props.user.main_site===false?"fl headwith100b edu-txt-center pr ul-leftline":"fl with50 edu-txt-center pr ul-leftline"}>
|
||||
{this.props.current_user&&this.props.current_user.user_identity==="学生"?"":coursestypes===false?
|
||||
<li><a onClick={(url)=>this.getUser("/courses/new")}>{this.props.user&&this.props.user.main_site===false?"新建课堂":"新建翻转课堂"}</a></li>:""
|
||||
}
|
||||
{shixuntype===true?"":
|
||||
<li><a onClick={(url)=>this.getUser("/shixuns/new","newshixuns")}>新建实训项目</a></li>
|
||||
}
|
||||
{this.props.user&&this.props.user.main_site===false?"":this.props.Headertop===undefined?"":<li><a onClick={(url)=>this.getUser("/paths/new")} >新建实践课程</a></li>}
|
||||
{this.props.user&&this.props.user.main_site===true?"":this.props.Headertop===undefined?"":
|
||||
pathstype===true?"":this.props.user&&this.props.user.admin===true||this.props.user&&this.props.user.is_teacher===true||this.props.user&&this.props.user.business===true?<li><a onClick={(url)=>this.getUser("/paths/new")} >新建实践课程</a></li>:""
|
||||
}
|
||||
{this.props.user&&this.props.user.main_site===true?<li><a onClick={(url)=>this.getUser("/projects/new","projects")} target="_blank">新建开发项目</a></li>:""}
|
||||
</ul>
|
||||
{coursestypes===true&&this.props.user&&this.props.user.main_site===false?"":<ul className="fl with50 edu-txt-center">
|
||||
|
||||
{coursestypes===true?"":<li>
|
||||
<a onClick={this.tojoinclass}>{this.props.user&&this.props.user.main_site===false?"加入课堂":"加入翻转课堂"}</a>
|
||||
</li>}
|
||||
|
||||
{Addcoursestypes===true?<Addcourses
|
||||
Addcoursestype={Addcoursestypes}
|
||||
hideAddcoursestype={this.hideAddcoursestypes}
|
||||
HideAddcoursestypess={(i)=>this.HideAddcoursestypess(i)}
|
||||
/>:""}
|
||||
<Certifiedprofessional {...this.props} {...this.state} ModalCancelsy={this.ModalCancelsy}/>
|
||||
<div className="edu-menu-list" style={{top: '60px',width:"240px"}}>
|
||||
<div className="overPart"></div>
|
||||
<ul className={coursestypes===true&&this.props.user&&this.props.user.main_site===false?"fl headwith100b edu-txt-center pr ul-leftline":"fl with50 edu-txt-center pr ul-leftline"}>
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.new_syllabuses &&
|
||||
<li><a href={`${mygetHelmetapi2.new_course.new_syllabuses}`} target="_blank">新建课程</a></li>
|
||||
}
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.new_course &&
|
||||
<li><a href={`${mygetHelmetapi2.new_course.new_course}`} target="_blank">新建班级</a></li>
|
||||
}
|
||||
</ul>
|
||||
{coursestypes===true&&this.props.user&&this.props.user.main_site===false?"":<ul className="fl with50 edu-txt-center">
|
||||
<li><Link to={"/projects/mirror/new"}>新建镜像项目</Link></li>
|
||||
<li><Link to={"/projects/deposit/new"}>新建托管项目</Link></li>
|
||||
</ul>}
|
||||
</div>
|
||||
</div>
|
||||
: ""
|
||||
}
|
||||
|
||||
|
||||
{/* /courses/join_course_multi_role */}
|
||||
{this.props.user&&this.props.user.main_site===true?<li>
|
||||
<a onClick={this.tojoinitem}>加入开发项目</a>
|
||||
</li>:""}
|
||||
{tojoinitemtype===true?<Modal
|
||||
keyboard={false}
|
||||
title="加入项目"
|
||||
visible={tojoinitemtype}
|
||||
closable={false}
|
||||
footer={null}
|
||||
>
|
||||
<div className="task_popup_con">
|
||||
<div className="mr15">
|
||||
<ul>
|
||||
<li className="clearfix mb10">
|
||||
<label className="panel-form-label fl">项目邀请码:</label>
|
||||
<Input type="text" className="input-60-40 fl mt5" name="invite_code"
|
||||
style={{width: '275px'}}
|
||||
placeholder="请输入6位开发项目邀请码" value={tojoinclasstitle} onInput={this.inputjoinclassvalue}/>
|
||||
</li>
|
||||
|
||||
<p id="none_invite_code_notice"
|
||||
className="color-orange none f12"
|
||||
style={{marginLeft: '90px',display:code_notice===true?'block':"none"}}>请输入6位项目邀请码</p>
|
||||
|
||||
<li className="clearfix ">
|
||||
|
||||
<label className="panel-form-label fl">身份:</label>
|
||||
<RadioGroup className="mt10" onChange={this.onChangeRadioGroup}>
|
||||
<Radio value={"manager"}>管理人员</Radio>
|
||||
<Radio value={"developer"}>开发人员</Radio>
|
||||
<Radio value={"reporter"}>报告人员</Radio>
|
||||
</RadioGroup>
|
||||
|
||||
</li>
|
||||
|
||||
<p id="none_checked_notice" className="color-orange none f12"
|
||||
style={{marginLeft: '90px',display:checked_notice===true?'block':"none"}}>请选择一个身份</p>
|
||||
|
||||
<li className="clearfix mt10 edu-txt-center">
|
||||
<a className="task-btn mr10"
|
||||
onClick={()=>this.hidetojoinclass(1)}>取消</a>
|
||||
<a
|
||||
className="task-btn task-btn-orange ml20"
|
||||
onClick={()=>this.submittojoinclass(1)}>确定</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>:""}
|
||||
</ul>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{this.props.user&&this.props.user.main_site===true? <div className="fl mr30 edu-menu-panel headIcon">
|
||||
{this.props.user&&this.props.user.login? <div className="fl mr30 edu-menu-panel headIcon">
|
||||
{ user===undefined?"":user.login===""?"": <a
|
||||
href={`/messages/${user.login}/user_tidings`}
|
||||
style={{position:'relative'}}
|
||||
href={`${mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.tiding_url}`}
|
||||
style={{position:'relative'}} target="_blank"
|
||||
>
|
||||
<i className="iconfont icon-xiaoxilingdang color-white"></i>
|
||||
<span className="newslight" style={{display:this.props.Headertop===undefined?"none":this.props.Headertop.new_message===true?"block":"none"}}>
|
||||
{/*{this.props.Headertop===undefined?"":this.props.Headertop.unread_message_count > 99 ? '99+'*/}
|
||||
{/*: this.props.Headertop===undefined?"":this.props.Headertop.unread_message_count}*/}
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import React, { Component } from 'react';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
// import PropTypes from 'prop-types';
|
||||
|
||||
import NewHeader from './NewHeader'
|
||||
import NewFooter from './NewFooter'
|
||||
import SiderBar from './SiderBar'
|
||||
import { getUrl, downloadFile } from 'educoder'
|
||||
import { downloadFile } from 'educoder'
|
||||
import axios from 'axios';
|
||||
import { Spin } from 'antd';
|
||||
import './TPMIndex.css';
|
||||
import LoginDialog from '../login/LoginDialog';
|
||||
import AccountProfile from '../user/AccountProfile';
|
||||
import AccountPhoneemail from '../user/AccountPhoneemail';
|
||||
import Trialapplication from "../login/Trialapplication";
|
||||
// import Trialapplication from "../login/Trialapplication";
|
||||
// import "antd/dist/antd.css";
|
||||
// import '../../css/educoder/edu-common.css'
|
||||
// import '../../css/educoder/edu-all.css'
|
||||
|
|
@ -20,49 +20,20 @@ import Trialapplication from "../login/Trialapplication";
|
|||
|
||||
const $ = window.$;
|
||||
const versionNum = '0001';
|
||||
// let _url_origin = getUrl()
|
||||
let _url_origin='';
|
||||
let _url_origin='';
|
||||
if(window.location.port === "3007"){
|
||||
_url_origin="https://test-newweb.educoder.net";
|
||||
_url_origin="https://testforgeplus.trustie.net";
|
||||
}
|
||||
|
||||
// let _url_origin=`https://www.educoder.net`;
|
||||
|
||||
if (!window['indexHOCLoaded']) {
|
||||
window.indexHOCLoaded = true;
|
||||
//解决首屏加载问题
|
||||
|
||||
// $('head').append($('<link rel="stylesheet" type="text/css" />')
|
||||
// .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`));
|
||||
$('head').append($('<link rel="stylesheet" type="text/css" />')
|
||||
.attr('href', `${_url_origin}/stylesheets/css/edu-common.css?3`));
|
||||
|
||||
$('head').append($('<link rel="stylesheet" type="text/css" />')
|
||||
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?3`));
|
||||
|
||||
// index.html有加载
|
||||
.attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css`));
|
||||
$('head').append($('<link rel="stylesheet" type="text/css" />')
|
||||
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?3`));
|
||||
|
||||
|
||||
// $('head').append($('<link rel="stylesheet" type="text/css" />')
|
||||
// .attr('href', `${_url_origin}/stylesheets/educoder/css_min_all.css?1525440977`));
|
||||
// 加timeout 为了覆盖掉antd的样式
|
||||
// setTimeout(() => {
|
||||
// $('head').append( $('<link rel="stylesheet" type="text/css" />')
|
||||
// .attr('href', `${_url_origin}/stylesheets/css/edu-common.css?1525440977`) );
|
||||
|
||||
// $('head').append( $('<link rel="stylesheet" type="text/css" />')
|
||||
// .attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?1525440977`) );
|
||||
// $('head').append( $('<link rel="stylesheet" type="text/css" />')
|
||||
// .attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?1525440977`) );
|
||||
// }, 1000);
|
||||
|
||||
.attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css`));
|
||||
$("script").append('<script></script>')
|
||||
.attr('src', `${_url_origin}/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js?_t=${versionNum}`);
|
||||
|
||||
}
|
||||
// `${_url_origin}/javascripts/jquery-1.8.3-ui-1.9.2-ujs-2.0.3.js?_t=${versionNum}`
|
||||
// TODO css加载完成后再打开页面,行为和tpm其他页面一致
|
||||
export function TPMIndexHOC(WrappedComponent) {
|
||||
// 这里如果extends WrappedComponent 会出现 WrappedComponent mount twice的问题
|
||||
|
|
@ -149,44 +120,24 @@ export function TPMIndexHOC(WrappedComponent) {
|
|||
|
||||
componentDidMount() {
|
||||
// console.log("TPMIndexHOC========");
|
||||
// console.log(this.props);
|
||||
window.addEventListener('keyup', this.keyupListener)
|
||||
// console.log("match",this.props);
|
||||
window.addEventListener('keyup', this.keyupListener);
|
||||
|
||||
if(this.props.match.path==="/"){
|
||||
// document.title="创新源于实践";
|
||||
}else if(this.props.match.path==="/403"){
|
||||
document.title="你没有权限访问";
|
||||
}else if(this.props.match.path==="/nopage"){
|
||||
document.title="没有找到该页面";
|
||||
}else if(this.props.match.path==="/shixuns"){
|
||||
document.title="实训项目";
|
||||
}else if(this.props.match.path==="/paths"){
|
||||
document.title="实践课程";
|
||||
}else if(this.props.match.path==="/courses"){
|
||||
document.title="翻转课堂";
|
||||
}
|
||||
|
||||
// if(this.props.match.path==="/"){
|
||||
// document.title="EduCoder-IT实践教学平台_信息技术类精品课程网_大学生MOOC平台";
|
||||
// }else if(this.props.match.path==="/403"){
|
||||
// document.title="你没有权限访问";
|
||||
// }else if(this.props.match.path==="/nopage"){
|
||||
// document.title="没有找到该页面";
|
||||
// }else if(this.props.match.path==="/shixuns"){
|
||||
// document.title="EduCoder-IT实践教学平台_信息技术类精品课程网_大学生MOOC平台";
|
||||
// }else if(this.props.match.path==="/paths"){
|
||||
// document.title="实践课程_项目实战开发_web前端开发实训_web后端开发实战_人工智能技术-EduCoder";
|
||||
// }else if(this.props.match.path==="/courses"){
|
||||
// document.title="实训项目_php后端开发_app前端开发_java_python实训_C语言入门课程-EduCoder";
|
||||
// }else if(this.props.match.path==="/competitions"){
|
||||
// document.title="在线竞赛_计算机应用大赛_编程大赛_大学生设计大赛_全国高校绿色计算大赛-EduCoder";
|
||||
// }else if(this.props.match.path==="/moop_cases"){
|
||||
// document.title="教学案例-EduCoder";
|
||||
// }else if(this.props.match.path==="/forums"){
|
||||
// document.title="交流问答-EduCoder";
|
||||
// }else if(this.props.match.path==="/forums"){
|
||||
// document.title="交流问答-EduCoder";
|
||||
// }
|
||||
if(this.props.match.path==="/"){
|
||||
document.title="Forge";
|
||||
}else if(this.props.match.path==="/403"){
|
||||
document.title="你没有权限访问";
|
||||
}else if(this.props.match.path==="/nopage"){
|
||||
document.title="没有找到该页面";
|
||||
}else if(this.props.match.path==="/shixuns"){
|
||||
document.title="实训项目";
|
||||
}else if(this.props.match.path==="/paths"){
|
||||
document.title="实践课程";
|
||||
}else if(this.props.match.path==="/courses"){
|
||||
document.title="翻转课堂";
|
||||
}else if(this.props.match.path==="/projects"){
|
||||
document.title="开源项目";
|
||||
}
|
||||
|
||||
$.ajaxSetup({
|
||||
cache: true
|
||||
|
|
@ -194,10 +145,6 @@ export function TPMIndexHOC(WrappedComponent) {
|
|||
|
||||
//帮助后台传参数
|
||||
const query = this.props.location.search;
|
||||
// const type = query.split('?chinaoocTimestamp=');
|
||||
// console.log("Eduinforms12345");
|
||||
// console.log(this.foo(query));
|
||||
// console.log(JSON.stringify(this.foo(query)));
|
||||
var dataqueryss={}
|
||||
try {
|
||||
var foqus=this.foo(query);
|
||||
|
|
@ -218,23 +165,23 @@ export function TPMIndexHOC(WrappedComponent) {
|
|||
}
|
||||
this.fetchUsers(dataqueryss);
|
||||
|
||||
let url=`/users/get_navigation_info.json`;
|
||||
axios.get(url, {
|
||||
// let url=`/users/get_navigation_info.json`;
|
||||
// axios.get(url, {
|
||||
|
||||
}).then((response) => {
|
||||
// console.log("开始请求/get_navigation_info.json");
|
||||
// console.log(response);
|
||||
if(response!=undefined){
|
||||
if(response.status===200){
|
||||
this.setState({
|
||||
Headertop:response.data.top,
|
||||
Footerdown:response.data.down
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
// }).then((response) => {
|
||||
// // console.log("开始请求/get_navigation_info.json");
|
||||
// // console.log(response);
|
||||
// if(response!=undefined){
|
||||
// if(response.status===200){
|
||||
// this.setState({
|
||||
// Headertop:response.data.top,
|
||||
// Footerdown:response.data.down
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
///请求定制化的信息
|
||||
this.getAppdata();
|
||||
// this.getAppdata();
|
||||
}
|
||||
/**
|
||||
课堂权限相关方法,暂时写这里了 ----------------------------------------START
|
||||
|
|
@ -309,7 +256,7 @@ export function TPMIndexHOC(WrappedComponent) {
|
|||
this.setState({
|
||||
mygetHelmetapi: undefined
|
||||
});
|
||||
document.title = "EduCoder";
|
||||
// document.title = "Forge";
|
||||
var link = document.createElement('link'),
|
||||
oldLink = document.getElementById('dynamic-favicon');
|
||||
link.id = 'dynamic-favicon';
|
||||
|
|
@ -335,67 +282,67 @@ export function TPMIndexHOC(WrappedComponent) {
|
|||
document.head.appendChild(link);
|
||||
}
|
||||
//获取当前定制信息
|
||||
getAppdata = () => {
|
||||
try {
|
||||
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
|
||||
var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
|
||||
// console.log("TPMLNdexHOC");
|
||||
// console.log(chromesettingArray);
|
||||
// console.log(chromesettingresponseArray);
|
||||
this.setState({
|
||||
mygetHelmetapi:chromesettingArray
|
||||
});
|
||||
if (chromesettingArray.tab_logo_url) {
|
||||
this.gettablogourldata(chromesettingresponseArray);
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
}catch (e) {
|
||||
console.log("hoc获取游览器配置失败 重新请求开始读取配置");
|
||||
this.getAppdatausr();
|
||||
}
|
||||
// getAppdata = () => {
|
||||
// try {
|
||||
// var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
|
||||
// var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
|
||||
// // console.log("TPMLNdexHOC");
|
||||
// // console.log(chromesettingArray);
|
||||
// // console.log(chromesettingresponseArray);
|
||||
// this.setState({
|
||||
// mygetHelmetapi:chromesettingArray
|
||||
// });
|
||||
// if (chromesettingArray.tab_logo_url) {
|
||||
// this.gettablogourldata(chromesettingresponseArray);
|
||||
// } else {
|
||||
// this.gettablogourlnull();
|
||||
// }
|
||||
// }catch (e) {
|
||||
// console.log("hoc获取游览器配置失败 重新请求开始读取配置");
|
||||
// this.getAppdatausr();
|
||||
// }
|
||||
|
||||
};
|
||||
getAppdatausr=()=>{
|
||||
let url = "/setting.json";
|
||||
axios.get(url).then((response) => {
|
||||
// console.log("app.js开始请求/setting.json");
|
||||
// console.log("获取当前定制信息");
|
||||
if (response) {
|
||||
if (response.data) {
|
||||
this.setState({
|
||||
mygetHelmetapi: response.data.setting
|
||||
});
|
||||
localStorage.setItem('chromesetting',JSON.stringify(response.data.setting));
|
||||
localStorage.setItem('chromesettingresponse',JSON.stringify(response));
|
||||
try {
|
||||
if (response.data.setting.tab_logo_url) {
|
||||
this.gettablogourldata(response);
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
} catch (e) {
|
||||
this.gettablogourlnull();
|
||||
}
|
||||
// };
|
||||
// getAppdatausr=()=>{
|
||||
// let url = "/setting.json";
|
||||
// axios.get(url).then((response) => {
|
||||
// // console.log("app.js开始请求/setting.json");
|
||||
// // console.log("获取当前定制信息");
|
||||
// if (response) {
|
||||
// if (response.data) {
|
||||
// this.setState({
|
||||
// mygetHelmetapi: response.data.setting
|
||||
// });
|
||||
// localStorage.setItem('chromesetting',JSON.stringify(response.data.setting));
|
||||
// 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();
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
} else {
|
||||
this.gettablogourlnull();
|
||||
// } else {
|
||||
// this.gettablogourlnull();
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
}).catch((error) => {
|
||||
this.gettablogourlnull();
|
||||
// }).catch((error) => {
|
||||
// this.gettablogourlnull();
|
||||
|
||||
});
|
||||
// });
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
fetchUser = () => {
|
||||
let url = `/users/get_user_info.json`
|
||||
|
|
|
|||
|
|
@ -995,7 +995,10 @@ class LoginRegisterComponent extends Component {
|
|||
<div>
|
||||
{weixinlogin===false&&this.props.weixinlogin===undefined?<Menu mode="horizontal" selectedKeys={tab} onClick={this.changeTab} className="mt20">
|
||||
<Menu.Item key="0" className={tab===0?"active font-18":"font-18"} > 登录</Menu.Item>
|
||||
<Menu.Item key="1" className={tab===1?"active font-18 ":"font-18 "} style={{marginLeft:"10px"}} >注册</Menu.Item>
|
||||
<Menu.Item key="1" className={tab===1?"active font-18 ":"font-18 "} style={{marginLeft:"10px"}}>
|
||||
<a href="https://www.trustie.net/login?login=false" target={"_blank"}>注册</a>
|
||||
{/*注册*/}
|
||||
</Menu.Item>
|
||||
</Menu>:""}
|
||||
|
||||
{
|
||||
|
|
@ -1078,9 +1081,9 @@ class LoginRegisterComponent extends Component {
|
|||
|
||||
<div className="left_right font-12 " style={{color: '#676767'}}>
|
||||
<Checkbox onChange={this.onAutoLoginChange} checked={autoLogin}>下次自动登录</Checkbox>
|
||||
|
||||
<a onClick={()=>this.StudyMakeMoney()}
|
||||
className="mr3 color-grey-9 mt3 font-12">找回密码</a>
|
||||
<a href="https://www.trustie.net/account/lost_password" className="mr3 color-grey-9 mt3 font-12" target={"_blank"}>找回密码</a>
|
||||
{/*<a onClick={()=>this.StudyMakeMoney()}*/}
|
||||
{/*className="mr3 color-grey-9 mt3 font-12">找回密码</a>*/}
|
||||
</div>
|
||||
|
||||
<Button className="login_btn font-16" type="primary" style={{height:"46px"}} onClick={() => this.postLogin()}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ const InfosTopics=Loadable({
|
|||
loader: () => import('./InfosTopics'),
|
||||
loading:Loading,
|
||||
})
|
||||
const UserProjects = Loadable({
|
||||
loader: () => import('./Projects'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const $ = window.$;
|
||||
class Infos extends Component{
|
||||
|
|
@ -60,7 +64,7 @@ class Infos extends Component{
|
|||
type:0,
|
||||
login:undefined,
|
||||
isRenders:false,
|
||||
moduleName:"courses",
|
||||
moduleName:"projects",
|
||||
next_gold:undefined
|
||||
}
|
||||
}
|
||||
|
|
@ -109,8 +113,8 @@ class Infos extends Component{
|
|||
data:result.data,
|
||||
followed:result.data.followed,
|
||||
sign:result.data.brief_introduction,
|
||||
id:result.data.id,
|
||||
next_gold:result.data.tomorrow_attendance_gold
|
||||
// id:result.data.id,
|
||||
// next_gold:result.data.tomorrow_attendance_gold
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -295,11 +299,16 @@ class Infos extends Component{
|
|||
></Route>
|
||||
|
||||
{/* 开发项目 */}
|
||||
<Route exact path="/users/:username/projects"
|
||||
render={
|
||||
(props) => (<InfosProject {...this.props} {...props} {...this.state} {..._commonProps}/>)
|
||||
}
|
||||
></Route>
|
||||
{/*<Route exact path="/users/:username/projects"*/}
|
||||
{/*render={*/}
|
||||
{/*(props) => (<InfosProject {...this.props} {...props} {...this.state} {..._commonProps}/>)*/}
|
||||
{/*}*/}
|
||||
{/*></Route>*/}
|
||||
<Route exact path="/users/:username/projects"
|
||||
render={
|
||||
(props) => (<UserProjects {...this.props} {...props} {...this.state} {..._commonProps}/>)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* 众包 */}
|
||||
{/* http://localhost:3007/courses/1309/homework/9300/setting */}
|
||||
|
|
|
|||
|
|
@ -27,39 +27,48 @@ class InfosBanner extends Component{
|
|||
let {pathname}=this.props.location;
|
||||
moduleName=pathname.split("/")[3];
|
||||
|
||||
let user_id=this.props.current_user&&this.props.current_user.user_id;
|
||||
let user_type=this.props.current_user&&this.props.current_user.user_identity;
|
||||
let targetuserid=this.props.data&&this.props.data.id;
|
||||
// let user_id=this.props.current_user&&this.props.current_user.user_id;
|
||||
// let user_type=this.props.current_user&&this.props.current_user.user_identity;
|
||||
// let targetuserid=this.props.data&&this.props.data.id;
|
||||
|
||||
// console.log(is_current)
|
||||
// console.log(current_user)
|
||||
// console.log(current_user.is_teacher)
|
||||
let shixuntype=false;
|
||||
let pathstype=false;
|
||||
let coursestypes=false;
|
||||
if(this.props&&this.props.mygetHelmetapi!=null){
|
||||
let shixun="/shixuns";
|
||||
let paths="/paths";
|
||||
let courses="/courses";
|
||||
this.props.mygetHelmetapi.navbar.map((item,key)=>{
|
||||
var reg = RegExp(item.link);
|
||||
if(shixun.match(reg)){
|
||||
if(item.hidden===true){
|
||||
shixuntype=true
|
||||
}
|
||||
}
|
||||
if(paths.match(reg)){
|
||||
if(item.hidden===true){
|
||||
pathstype=true
|
||||
}
|
||||
}
|
||||
if(courses.match(reg)){
|
||||
if(item.hidden===true){
|
||||
coursestypes=true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// let shixuntype=false;
|
||||
// let pathstype=false;
|
||||
// let coursestypes=false;
|
||||
// let projectstypes=false;
|
||||
|
||||
// if(this.props&&this.props.mygetHelmetapi!=null){
|
||||
// console.log("this.props", this.props.mygetHelmetapi)
|
||||
// let shixun="/shixuns";
|
||||
// let paths="/paths";
|
||||
// let courses="/courses";
|
||||
// let projects = "/projects";
|
||||
// this.props.mygetHelmetapi.navbar.map((item,key)=>{
|
||||
// var reg = RegExp(item.link);
|
||||
// if(shixun.match(reg)){
|
||||
// if(item.hidden===true){
|
||||
// shixuntype=true
|
||||
// }
|
||||
// }
|
||||
// if(paths.match(reg)){
|
||||
// if(item.hidden===true){
|
||||
// pathstype=true
|
||||
// }
|
||||
// }
|
||||
// if(courses.match(reg)){
|
||||
// if(item.hidden===true){
|
||||
// coursestypes=true
|
||||
// }
|
||||
// }
|
||||
// if(projects.match(reg)){
|
||||
// if(item.hidden===true){
|
||||
// projectstypes=true
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
return(
|
||||
<div className="bannerPanel mb60">
|
||||
|
|
@ -68,94 +77,86 @@ class InfosBanner extends Component{
|
|||
<p className="myPhoto mr20 fl"><img alt="头像" src={data && `${getImageUrl('images/'+data.avatar_url)}`}/></p>
|
||||
<div className="fl">
|
||||
<p className="clearfix mt20">
|
||||
<span className="username task-hide" style={{"maxWidth":'370px'}}>{data && data.name}</span>
|
||||
<span className="username task-hide" style={{"maxWidth":'370px'}}>
|
||||
{data && data.name}
|
||||
</span>
|
||||
{/*{*/}
|
||||
{/*data && is_current == false && data.identity =="学生" ? "" : */}
|
||||
{/*data && data.identity &&*/}
|
||||
{/*<span className="userpost"><label>{data && data.identity}</label></span>*/}
|
||||
{/*}*/}
|
||||
</p>
|
||||
<p className="mt15">
|
||||
<Tooltip placement='bottom' title={ data && data.professional_certification ?"已职业认证":"未职业认证"}>
|
||||
<i className={ data && data.professional_certification ? "iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-blue mr20 ml2":"iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-B8 mr20 ml2"}></i>
|
||||
</Tooltip>
|
||||
<Tooltip placement='bottom' title={ data && data.authentication ?"已实名认证":"未实名认证"}>
|
||||
<i className={ data && data.authentication ? "iconfont icon-renzhengshangjia font-18 user-colorgrey-blue":"iconfont icon-renzhengshangjia font-18 user-colorgrey-B8"}></i>
|
||||
</Tooltip>
|
||||
</p>
|
||||
{/*{*/}
|
||||
{/*data && data.brief_introduction &&*/}
|
||||
{/*<p className="mt15 text-grey-e">{data.brief_introduction}</p>*/}
|
||||
{/*}*/}
|
||||
{/*<p className="mt15">*/}
|
||||
{/*<Tooltip placement='bottom' title={ data && data.professional_certification ?"已职业认证":"未职业认证"}>*/}
|
||||
{/*<i className={ data && data.professional_certification ? "iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-blue mr20 ml2":"iconfont icon-shenfenzhenghaomaguizheng font-18 user-colorgrey-B8 mr20 ml2"}></i>*/}
|
||||
{/*</Tooltip>*/}
|
||||
{/*<Tooltip placement='bottom' title={ data && data.authentication ?"已实名认证":"未实名认证"}>*/}
|
||||
{/*<i className={ data && data.authentication ? "iconfont icon-renzhengshangjia font-18 user-colorgrey-blue":"iconfont icon-renzhengshangjia font-18 user-colorgrey-B8"}></i>*/}
|
||||
{/*</Tooltip>*/}
|
||||
{/*</p>*/}
|
||||
</div>
|
||||
<div className="fr">
|
||||
<div class="fl headtab mt20">
|
||||
<span>{is_current ? "我":"TA"}的经验值</span>
|
||||
<a style={{"cursor":"default"}}>{data && data.experience}</a>
|
||||
</div>
|
||||
<div class="fl headtab mt20 pr leftTransform pl20">
|
||||
<span>{is_current ? "我":"TA"}的金币</span>
|
||||
<a style={{"cursor":"default"}}>{data && data.grade}</a>
|
||||
</div>
|
||||
{
|
||||
is_current ?
|
||||
<span className="fl mt35 ml60">
|
||||
{
|
||||
data && data.attendance_signed ?
|
||||
<span className="user_default_btn user_grey_btn font-18">已签到</span>
|
||||
:
|
||||
<a herf="javascript:void(0);" onClick={this.props.signFor} className="user_default_btn user_yellow_btn fl font-18">签到</a>
|
||||
}
|
||||
</span>
|
||||
:
|
||||
<span className="fl mt35 ml60">
|
||||
<LinkAfterLogin
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
className="user_default_btn user_yellow_btn fl font-18"
|
||||
to={`/messages/${login}/message_detail?target_ids=${id}`}
|
||||
>
|
||||
私信
|
||||
</LinkAfterLogin>
|
||||
</span>
|
||||
}
|
||||
<div className="fl headtab mt20">
|
||||
<span>全部项目数</span>
|
||||
<a style={{"cursor": "default"}}>{data && data.projects_count}</a>
|
||||
</div>
|
||||
{/*<div class="fl headtab mt20">*/}
|
||||
{/*<span>{is_current ? "我":"TA"}的经验值</span>*/}
|
||||
{/*<a style={{"cursor":"default"}}>{data && data.experience}</a>*/}
|
||||
{/*</div> */}
|
||||
{/*<div class="fl headtab mt20 pr leftTransform pl20">*/}
|
||||
{/*<span>{is_current ? "我":"TA"}的金币</span>*/}
|
||||
{/*<a style={{"cursor":"default"}}>{data && data.grade}</a>*/}
|
||||
{/*</div> */}
|
||||
{/*{*/}
|
||||
{/*is_current ? */}
|
||||
{/*<span className="fl mt35 ml60">*/}
|
||||
{/*{*/}
|
||||
{/*data && data.attendance_signed ? */}
|
||||
{/*<span className="user_default_btn user_grey_btn font-18">已签到</span>*/}
|
||||
{/*:*/}
|
||||
{/*<a herf="javascript:void(0);" onClick={this.props.signFor} className="user_default_btn user_yellow_btn fl font-18">签到</a>*/}
|
||||
{/*}*/}
|
||||
{/*</span> */}
|
||||
{/*:*/}
|
||||
{/*<span className="fl mt35 ml60">*/}
|
||||
{/*<LinkAfterLogin */}
|
||||
{/*{...this.props} */}
|
||||
{/*{...this.state} */}
|
||||
{/*className="user_default_btn user_yellow_btn fl font-18" */}
|
||||
{/*to={`/messages/${login}/message_detail?target_ids=${id}`}*/}
|
||||
{/*>*/}
|
||||
{/*私信*/}
|
||||
{/*</LinkAfterLogin>*/}
|
||||
{/*</span>*/}
|
||||
{/*}*/}
|
||||
</div>
|
||||
</div>
|
||||
<div className="userNav">
|
||||
{coursestypes===true?"":<li className={`${moduleName == 'courses' ||moduleName == undefined ? 'active' : '' }`}>
|
||||
<Link
|
||||
onClick={() => this.setState({moduleName: 'courses'})}
|
||||
to={`/users/${username}/courses`}>翻转课堂</Link>
|
||||
</li>}
|
||||
{shixuntype===true?"":<li className={`${moduleName == 'shixuns' ? 'active' : '' }`}>
|
||||
<Link
|
||||
onClick={() => this.setState({moduleName: 'shixuns'})}
|
||||
to={`/users/${username}/shixuns`}>实训项目</Link>
|
||||
</li>}
|
||||
{pathstype===true?"":<li className={`${moduleName == 'paths' ? 'active' : '' }`}>
|
||||
<Link
|
||||
onClick={() => this.setState({moduleName: 'paths'})}
|
||||
to={`/users/${username}/paths`}>实践课程</Link>
|
||||
</li>}
|
||||
{this.props.user&&this.props.user.main_site===true?<li className={`${moduleName == 'projects' ? 'active' : '' }`}>
|
||||
{/*{coursestypes===true?"":<li className={`${moduleName == 'courses' ||moduleName == undefined ? 'active' : '' }`}>*/}
|
||||
{/*<Link*/}
|
||||
{/*onClick={() => this.setState({moduleName: 'courses'})}*/}
|
||||
{/*to={`/users/${username}/courses`}>翻转课堂</Link>*/}
|
||||
{/*</li>}*/}
|
||||
{/*{shixuntype===true?"":<li className={`${moduleName == 'shixuns' ? 'active' : '' }`}>*/}
|
||||
{/*<Link*/}
|
||||
{/*onClick={() => this.setState({moduleName: 'shixuns'})}*/}
|
||||
{/*to={`/users/${username}/shixuns`}>实训项目</Link>*/}
|
||||
{/*</li>}*/}
|
||||
{/*{pathstype===true?"":<li className={`${moduleName == 'paths' ? 'active' : '' }`}>*/}
|
||||
{/*<Link */}
|
||||
{/*onClick={() => this.setState({moduleName: 'paths'})}*/}
|
||||
{/*to={`/users/${username}/paths`}>实践课程</Link>*/}
|
||||
{/*</li>}*/}
|
||||
<li className={`${moduleName === 'projects' ? 'active' : '' }`}>
|
||||
<Link
|
||||
onClick={() => this.setState({moduleName: 'projects'})}
|
||||
to={`/users/${username}/projects`}>开发项目</Link>
|
||||
</li>:""}
|
||||
{/*<li className={`${moduleName == 'package' ? 'active' : '' }`}>*/}
|
||||
{/* <Link*/}
|
||||
{/* onClick={() => this.setState({moduleName: 'package'})}*/}
|
||||
{/* to={`/users/${username}/package`}>众包</Link>*/}
|
||||
{/*</li>*/}
|
||||
{this.props.user&&this.props.user.main_site===true?((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
|
||||
&& <li className={`${moduleName == 'videos' ? 'active' : '' }`}>
|
||||
<Link
|
||||
onClick={() => this.setState({moduleName: 'videos'})}
|
||||
to={`/users/${username}/videos`}>视频</Link>
|
||||
</li>:""}
|
||||
</li>
|
||||
|
||||
{/*自己的主页且不是学生显示题库按钮*/}
|
||||
{this.props.user&&this.props.user.main_site===true?(is_current && current_user&& current_user.is_teacher )
|
||||
&&<li className={`${moduleName == 'topics' ? 'active' : '' }`}>
|
||||
<Link
|
||||
onClick={() => this.setState({moduleName: 'topics'})}
|
||||
to={`/users/${username}/topics/personal`}>题库</Link>
|
||||
</li>:""}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,408 @@
|
|||
import React, { Component } from 'react';
|
||||
import { SnackbarHOC } from 'educoder';
|
||||
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
|
||||
import {Tooltip, Pagination, Spin, Dropdown, Menu} from 'antd';
|
||||
import axios from 'axios';
|
||||
import NoneData from '../../courses/coursesPublic/NoneData'
|
||||
import {getImageUrl} from 'educoder';
|
||||
import "./usersInfo.css"
|
||||
import Create from './publicCreatNew'
|
||||
|
||||
class Projects extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state={
|
||||
category:undefined,
|
||||
status:undefined,
|
||||
page:1,
|
||||
per_page:16,
|
||||
sort_by: "updated_on",
|
||||
sort_direction: "desc",
|
||||
totalCount:undefined,
|
||||
data:undefined,
|
||||
isSpin:false
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
this.setState({
|
||||
isSpin:true
|
||||
})
|
||||
let {category, status, page, sort_by, sort_direction} = this.state;
|
||||
this.getCourses(category, status, page, sort_by, sort_direction);
|
||||
}
|
||||
|
||||
getCourses = (category, status, page, sort_by, sort_direction) => {
|
||||
let url=`/users/${this.props.match.params.username}/projects.json`;
|
||||
axios.get((url),{params:{
|
||||
category,
|
||||
status,
|
||||
page,
|
||||
sort_by,
|
||||
sort_direction,
|
||||
per_page:this.props.is_current && category && page ==1?17:16
|
||||
}}).then((result)=>{
|
||||
if(result){
|
||||
if (result.data.status === 403||result.data.status === 401||result.data.status === 500||result.data.status === 404) {
|
||||
this.setState({
|
||||
isSpin:false,
|
||||
totalCount:0
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
totalCount:result.data.count,
|
||||
data:result.data,
|
||||
sort_by: sort_by,
|
||||
sort_direction: sort_direction,
|
||||
isSpin:false
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
this.setState({
|
||||
isSpin: false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
//切换种类
|
||||
changeCategory=(cate)=>{
|
||||
this.setState({
|
||||
category:cate,
|
||||
page:1,
|
||||
isSpin:true
|
||||
})
|
||||
let {status, sort_by, sort_direction} = this.state;
|
||||
this.getCourses(cate, status, 1, sort_by,
|
||||
sort_direction);
|
||||
}
|
||||
//切换状态
|
||||
changeStatus=(status)=>{
|
||||
this.setState({
|
||||
status:status,
|
||||
page:1,
|
||||
isSpin:true
|
||||
})
|
||||
let {
|
||||
category, sort_by,
|
||||
sort_direction
|
||||
} = this.state;
|
||||
this.getCourses(category, status, 1, sort_by,
|
||||
sort_direction);
|
||||
}
|
||||
//切换页数
|
||||
changePage=(page)=>{
|
||||
this.setState({
|
||||
page,
|
||||
isSpin:true
|
||||
})
|
||||
let {
|
||||
category, status, sort_by,
|
||||
sort_direction
|
||||
} = this.state;
|
||||
this.getCourses(category, status, page, sort_by,
|
||||
sort_direction);
|
||||
}
|
||||
|
||||
// 进入项目
|
||||
turnToCourses=(url,flag)=>{
|
||||
if(flag){
|
||||
window.location.href=url;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//切换种类
|
||||
updatedlist(sort_by) {
|
||||
//按照什么样子排序
|
||||
this.setState({
|
||||
isSpin: true
|
||||
});
|
||||
let {category, status, page, sort_direction} = this.state;
|
||||
this.getCourses(category, status, 1, sort_by, "desc");
|
||||
}
|
||||
|
||||
//排序
|
||||
updatedlists(sort_directions) {
|
||||
//是否是倒序
|
||||
this.setState({
|
||||
isSpin: true
|
||||
});
|
||||
let {category, status, page, sort_by, sort_direction} = this.state;
|
||||
let sort_directiony = sort_directions;
|
||||
if (sort_directions === "asc") {
|
||||
if (sort_directions === sort_direction) {
|
||||
sort_directiony = "desc"
|
||||
}
|
||||
} else if (sort_directions === "desc") {
|
||||
if (sort_directions === sort_direction) {
|
||||
sort_directiony = "asc"
|
||||
}
|
||||
}
|
||||
this.getCourses(category, status, page, sort_by, sort_directiony);
|
||||
}
|
||||
|
||||
render(){
|
||||
let{
|
||||
category,
|
||||
status,
|
||||
page,
|
||||
data,
|
||||
totalCount,
|
||||
isSpin,
|
||||
sort_by,
|
||||
sort_direction
|
||||
} = this.state;
|
||||
let isStudent = this.props.isStudent();
|
||||
let is_current=this.props.is_current;
|
||||
const {current_user} = this.props
|
||||
|
||||
const menu = (
|
||||
<Menu>
|
||||
<Menu.Item onClick={() => this.updatedlist("updated_on")}>
|
||||
最新动态
|
||||
</Menu.Item>
|
||||
<Menu.Item onClick={() => this.updatedlist("created_on")}>
|
||||
最新创建
|
||||
</Menu.Item>
|
||||
|
||||
</Menu>
|
||||
);
|
||||
return(
|
||||
<div className="educontent">
|
||||
<Spin size="large" spinning={isSpin}>
|
||||
<style>
|
||||
{
|
||||
`
|
||||
.whitepanelyslli {
|
||||
width: 32px !important;
|
||||
height: 48px !important;
|
||||
line-height: 46px !important;
|
||||
}
|
||||
.whitepanelyslliss {
|
||||
width: 32px !important;
|
||||
height: 48px !important;
|
||||
line-height: 46px !important;
|
||||
}
|
||||
|
||||
.whitepanelysllis {
|
||||
width: 66px !important;
|
||||
height: 48px !important;
|
||||
line-height: 46px !important;
|
||||
margin-left: 40px !important;
|
||||
}
|
||||
|
||||
.whitepanelysllisyt {
|
||||
width: 60px !important;
|
||||
height: 48px !important;
|
||||
line-height: 46px !important;
|
||||
margin-left: 40px !important;
|
||||
}
|
||||
|
||||
|
||||
.white-panel li.active {
|
||||
border-radius: 24px;
|
||||
border: none !important;
|
||||
color: #4CACFF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
`
|
||||
}
|
||||
</style>
|
||||
<div className="white-panel edu-back-white pt20 pb20 clearfix ">
|
||||
<li className={category ? " font-16 whitepanelyslli" : "active font-16 whitepanelyslli"}><a
|
||||
href="javascript:void(0)" onClick={() => this.changeCategory()} className="font-16 w32">全部</a></li>
|
||||
<li className={category == "manage" ? "active font-16 whitepanelysllis" : "font-16 whitepanelysllis"}><a
|
||||
href="javascript:void(0)" onClick={() => this.changeCategory("manage")}
|
||||
className={is_current ? "font-16 w66" : "font-16 w80"}>{is_current ? "我" : "TA"}管理的</a></li>
|
||||
<li className={category == "study" ? "active font-16 whitepanelysllis" : "font-16 whitepanelysllis"}><a
|
||||
href="javascript:void(0)" onClick={() => this.changeCategory("study")}
|
||||
className={is_current ? "font-16 w66" : "font-16 w80"}>{is_current ? "我" : "TA"}参与的</a></li>
|
||||
</div>
|
||||
<style>
|
||||
{
|
||||
` .secondNavs li {
|
||||
color: #676767;
|
||||
/* margin: 0px 20px; */
|
||||
float: left;
|
||||
}
|
||||
.secondNavs li a:hover{
|
||||
color: #4CACFF
|
||||
}
|
||||
.secondNavs li.active a{
|
||||
color: #4CACFF
|
||||
}
|
||||
`
|
||||
}
|
||||
</style>
|
||||
{
|
||||
is_current &&
|
||||
<div className="edu-back-white padding10-30 clearfix secondNavs bor-top-greyE">
|
||||
<li className={status ? "whitepanelyslliss" : "active whitepanelyslliss"}><a href="javascript:void(0)"
|
||||
onClick={() => this.changeStatus()}
|
||||
className=" w32">全部</a></li>
|
||||
<li className={status == "publicly" ? "active whitepanelysllisyt" : "whitepanelysllisyt"}><a
|
||||
href="javascript:void(0)" onClick={() => this.changeStatus("publicly")} className=" w60">公开</a></li>
|
||||
<li className={status == "personal" ? "active whitepanelysllisyt" : "whitepanelysllisyt"}><a
|
||||
href="javascript:void(0)" onClick={() => this.changeStatus("personal")} className=" w60">私有</a></li>
|
||||
</div>
|
||||
}
|
||||
<p className="clearfix font-12 " style={{
|
||||
lineHeight: "41px",
|
||||
marginTop: "10px",
|
||||
}}>
|
||||
<span className="fl color-grey-9">共参与{totalCount}个{category?category=="manage"?"发布":"学习":"项目"}</span>
|
||||
<sapn className="relativef color-grey-9 fr"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height: "40px",
|
||||
lineHeight: "40px",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
textAlign: "center",
|
||||
height: "10px",
|
||||
lineHeight: "10px",
|
||||
display: "table",
|
||||
marginTop: "9px",
|
||||
}}
|
||||
>
|
||||
<i className={sort_direction === "asc" ?
|
||||
"iconfont icon-sanjiaoxing-up font-12 color-blue h10 " : "iconfont icon-sanjiaoxing-up font-12 h10"}
|
||||
onClick={() => this.updatedlists("asc")}></i>
|
||||
|
||||
</span>
|
||||
|
||||
<span
|
||||
style={{
|
||||
flexDirection: "column",
|
||||
height: "10px",
|
||||
lineHeight: "10px",
|
||||
textAlign: "center",
|
||||
display: "table",
|
||||
}}
|
||||
>
|
||||
<i className={sort_direction === "desc" ?
|
||||
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue h10" : "iconfont icon-sanjiaoxing-down font-12 yslbottomsj h10"}
|
||||
onClick={() => this.updatedlists("desc")}></i>
|
||||
</span>
|
||||
</sapn>
|
||||
<Dropdown overlay={menu}>
|
||||
<span className="fr color-grey-9 mr10 pointer " style={{
|
||||
display: "flex",
|
||||
flexDirection: "initial",
|
||||
}}>
|
||||
<span>{sort_by === "updated_on" ? '最近更新' : sort_by === "created_on" ? '最新创建' : ""}</span>
|
||||
|
||||
</span>
|
||||
</Dropdown>
|
||||
</p>
|
||||
<style>
|
||||
{
|
||||
`
|
||||
.square-list{width: 100%;box-sizing: border-box;margin-top:10px}
|
||||
`
|
||||
}
|
||||
</style>
|
||||
<div className="square-list clearfix">
|
||||
{/* 289 */}
|
||||
{
|
||||
page == 1 && is_current ?
|
||||
<Create href={`/projects/deposit/new`} name={"新建开发项目"} index="4" Createtype={"projects"}
|
||||
{...this.props} {...this.state}
|
||||
></Create>:""
|
||||
}
|
||||
{
|
||||
(!data || (data && data.projects.length==0)) && category && <NoneData></NoneData>
|
||||
|
||||
}
|
||||
{
|
||||
data===undefined||data.projects.length===0?category=="manage"||category=="study"?"":<NoneData></NoneData>:""
|
||||
}
|
||||
{
|
||||
data && data.projects && data.projects.map((item,key)=>{
|
||||
return(
|
||||
<div className="square-Item" onClick={()=>this.turnToCourses(`/projects/${item.id}`,item.can_visited)} style={{"cursor": "pointer","height":"289px"}}>
|
||||
{
|
||||
item.is_public==1 &&
|
||||
<React.Fragment>
|
||||
<div className="publicpart"></div>
|
||||
<span className="smalltrangle"></span>
|
||||
<span className="publicword">公开</span>
|
||||
</React.Fragment>
|
||||
}
|
||||
{
|
||||
item.can_visited ==false?
|
||||
<div className="closeSquare">
|
||||
<img src={getImageUrl("images/educoder/icon/lockclose.svg")} className="mt80 mb25"/>
|
||||
<p className="font-14 color-white">非成员不能访问</p>
|
||||
</div>:""
|
||||
}
|
||||
<div className="substance">
|
||||
<p className="subName font-16">
|
||||
<span>{item.name}</span>
|
||||
</p>
|
||||
<span><img alt="用户" className="radius mt15" height="60" src={getImageUrl(`images/${item.owner.avatar_url}`)} width="60"/></span>
|
||||
<p className="font-14 mt10 task-hide"><span>{item.owner.real_name}</span></p>
|
||||
<p className="font-16 mb15 mt10 task-hide">
|
||||
{
|
||||
item.category && item.category.name && <span className="projectTag categoryTag">{item.category.name}</span>
|
||||
}
|
||||
{
|
||||
item.language && item.language.name && <span className="projectTag languageTag">{item.language.name}</span>
|
||||
}
|
||||
{/*<span className="color-grey-9">{item.category.school_name}</span>*/}
|
||||
</p>
|
||||
</div>
|
||||
<div className="edu-txt-center course-bottom">
|
||||
<div className="inline color-grey-6">
|
||||
{
|
||||
item.members_count > 0 &&
|
||||
<Tooltip placement="bottom" title={"成员数"}>
|
||||
<span className="mr10 ml10 fl squareIconSpan">
|
||||
<i className="iconfont icon-chengyuan fl mr3"></i>{item.members_count}</span>
|
||||
</Tooltip>
|
||||
|
||||
}
|
||||
{
|
||||
item.issues_count > 0 &&
|
||||
<Tooltip placement="bottom" title={"任务数"}>
|
||||
<span className="mr10 ml10 fl squareIconSpan">
|
||||
<i className="iconfont icon-issue fl mr3"></i>{item.issues_count}</span>
|
||||
</Tooltip>
|
||||
|
||||
}
|
||||
{
|
||||
item.changesets_count > 0 &&
|
||||
<Tooltip placement="bottom" title={"版本库"}>
|
||||
<span className="mr10 ml10 fl squareIconSpan">
|
||||
<i className="iconfont icon-banbenku fl mr3"></i>{item.changesets_count}</span>
|
||||
</Tooltip>
|
||||
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
{
|
||||
totalCount > 15 &&
|
||||
<div className="mt30 mb50 edu-txt-center">
|
||||
<Pagination showQuickJumper total={totalCount} onChange={this.changePage} pageSize={16} current={page}/>
|
||||
</div>
|
||||
}
|
||||
</Spin>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Projects;
|
||||
|
|
@ -457,3 +457,14 @@
|
|||
.w80 {
|
||||
width: 80px !important;
|
||||
}
|
||||
.projectTag{
|
||||
padding: 3px 10px;
|
||||
border-radius: 15px;
|
||||
color: #333;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.categoryTag{background: #FFF3DC;}
|
||||
.languageTag{margin-left: 10px;background: #EBF4FE}
|
||||
.text-grey-e{color: #eee;}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ let _path = isDev() ? 'public' : 'build'
|
|||
|
||||
let _testHost = '' ; // 'http://192.168.2.63:3001/api' ; // '' ;
|
||||
let login = 'innov'
|
||||
// 工单注释
|
||||
// 任务注释
|
||||
// https://workorder.console.aliyun.com/console.htm#/ticket/detail/?ticketId=FLASELR
|
||||
// https://workorder.console.aliyun.com/console.htm#/ticket/detail/?ticketId=1FB4APN
|
||||
// https://help.aliyun.com/document_detail/52204.html?spm=5176.2020520165.120.d52204.19a47029YWhro7#%E4%B8%8A%E4%BC%A0%E5%9C%B0%E5%9D%80%E5%92%8C%E5%87%AD%E8%AF%81%E6%96%B9%E5%BC%8F(%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8)
|
||||
|
|
|
|||
Loading…
Reference in New Issue