diff --git a/package-lock.json b/package-lock.json
index 6f4ada7d..267c0020 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5075,6 +5075,11 @@
"zrender": "4.3.2"
}
},
+ "echarts-wordcloud": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npm.taobao.org/echarts-wordcloud/download/echarts-wordcloud-2.0.0.tgz?cache=0&sync_timestamp=1610779172014&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fecharts-wordcloud%2Fdownload%2Fecharts-wordcloud-2.0.0.tgz",
+ "integrity": "sha1-Uu+BeJWAH/6emd0brKt2hrLewEo="
+ },
"editor.md": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/editor.md/-/editor.md-1.5.0.tgz",
diff --git a/package.json b/package.json
index f69e3af9..2e61175b 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"echarts": "^4.9.0",
+ "echarts-wordcloud": "^2.0.0",
"editor.md": "^1.5.0",
"eslint": "4.10.0",
"eslint-config-react-app": "^2.1.0",
diff --git a/public/css/edu-purge.css b/public/css/edu-purge.css
index 4d59fc11..c8f7c907 100644
--- a/public/css/edu-purge.css
+++ b/public/css/edu-purge.css
@@ -3912,7 +3912,6 @@ html>body #ajax-indicator {
text-align: center;
height: 70px;
box-sizing: border-box;
- min-width: 780px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
diff --git a/public/css/iconfont.css b/public/css/iconfont.css
index 3d27dfda..7035af05 100644
--- a/public/css/iconfont.css
+++ b/public/css/iconfont.css
@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2340181 */
- src: url('iconfont.woff2?t=1620900836917') format('woff2'),
- url('iconfont.woff?t=1620900836917') format('woff'),
- url('iconfont.ttf?t=1620900836917') format('truetype');
+ src: url('iconfont.woff2?t=1622517296245') format('woff2'),
+ url('iconfont.woff?t=1622517296245') format('woff'),
+ url('iconfont.ttf?t=1622517296245') format('truetype');
}
.iconfont {
@@ -13,6 +13,58 @@
-moz-osx-font-smoothing: grayscale;
}
+.icon-youxiang:before {
+ content: "\e8b2";
+}
+
+.icon-danwei:before {
+ content: "\e8a7";
+}
+
+.icon-daibanshixiang:before {
+ content: "\e8a8";
+}
+
+.icon-gailan:before {
+ content: "\e8ab";
+}
+
+.icon-nan:before {
+ content: "\e8ac";
+}
+
+.icon-nv:before {
+ content: "\e8ad";
+}
+
+.icon-gongzuoliu1:before {
+ content: "\e8ae";
+}
+
+.icon-shujutongji:before {
+ content: "\e8b1";
+}
+
+.icon-xiangmu:before {
+ content: "\e8b3";
+}
+
+.icon-zuzhi:before {
+ content: "\e8b4";
+}
+
+.icon-arrowRight:before {
+ content: "\e863";
+}
+
+.icon-jiantouloukong-zuo:before {
+ content: "\e861";
+}
+
+.icon-jiantouloukong-you:before {
+ content: "\e862";
+}
+
.icon-fenxiang1:before {
content: "\e89c";
}
@@ -2441,7 +2493,7 @@
content: "\e7f3";
}
-.icon-dianzan1:before {
+.icon-dianzaned:before {
content: "\e639";
}
diff --git a/public/css/iconfont.js b/public/css/iconfont.js
index bb4188cd..068c8e0a 100644
--- a/public/css/iconfont.js
+++ b/public/css/iconfont.js
@@ -1 +1 @@
-!function(c){var l,a,h,i,o,z,t='',p=(p=document.getElementsByTagName("script"))[p.length-1].getAttribute("data-injectcss");if(p&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}function s(){o||(o=!0,h())}l=function(){var c,l,a;(a=document.createElement("div")).innerHTML=t,t=null,(l=a.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",c=l,(a=document.body).firstChild?(l=a.firstChild).parentNode.insertBefore(c,l):a.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(a=function(){document.removeEventListener("DOMContentLoaded",a,!1),l()},document.addEventListener("DOMContentLoaded",a,!1)):document.attachEvent&&(h=l,i=c.document,o=!1,(z=function(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(z,50)}s()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,s())})}(window);
\ No newline at end of file
+!function(c){var l,a,h,i,o,z,t='',p=(p=document.getElementsByTagName("script"))[p.length-1].getAttribute("data-injectcss");if(p&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}function v(){o||(o=!0,h())}l=function(){var c,l,a;(a=document.createElement("div")).innerHTML=t,t=null,(l=a.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",c=l,(a=document.body).firstChild?(l=a.firstChild).parentNode.insertBefore(c,l):a.appendChild(c))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(a=function(){document.removeEventListener("DOMContentLoaded",a,!1),l()},document.addEventListener("DOMContentLoaded",a,!1)):document.attachEvent&&(h=l,i=c.document,o=!1,(z=function(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(z,50)}v()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,v())})}(window);
\ No newline at end of file
diff --git a/public/css/iconfont.json b/public/css/iconfont.json
index ab6ae325..877958d7 100644
--- a/public/css/iconfont.json
+++ b/public/css/iconfont.json
@@ -5,6 +5,97 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
+ {
+ "icon_id": "21936935",
+ "name": "邮箱",
+ "font_class": "youxiang",
+ "unicode": "e8b2",
+ "unicode_decimal": 59570
+ },
+ {
+ "icon_id": "21936924",
+ "name": "单位",
+ "font_class": "danwei",
+ "unicode": "e8a7",
+ "unicode_decimal": 59559
+ },
+ {
+ "icon_id": "21936925",
+ "name": "待办事项",
+ "font_class": "daibanshixiang",
+ "unicode": "e8a8",
+ "unicode_decimal": 59560
+ },
+ {
+ "icon_id": "21936928",
+ "name": "概览",
+ "font_class": "gailan",
+ "unicode": "e8ab",
+ "unicode_decimal": 59563
+ },
+ {
+ "icon_id": "21936929",
+ "name": "男",
+ "font_class": "nan",
+ "unicode": "e8ac",
+ "unicode_decimal": 59564
+ },
+ {
+ "icon_id": "21936930",
+ "name": "女",
+ "font_class": "nv",
+ "unicode": "e8ad",
+ "unicode_decimal": 59565
+ },
+ {
+ "icon_id": "21936931",
+ "name": "工作流",
+ "font_class": "gongzuoliu1",
+ "unicode": "e8ae",
+ "unicode_decimal": 59566
+ },
+ {
+ "icon_id": "21936934",
+ "name": "数据统计",
+ "font_class": "shujutongji",
+ "unicode": "e8b1",
+ "unicode_decimal": 59569
+ },
+ {
+ "icon_id": "21936936",
+ "name": "项目",
+ "font_class": "xiangmu",
+ "unicode": "e8b3",
+ "unicode_decimal": 59571
+ },
+ {
+ "icon_id": "21936937",
+ "name": "组织",
+ "font_class": "zuzhi",
+ "unicode": "e8b4",
+ "unicode_decimal": 59572
+ },
+ {
+ "icon_id": "14835599",
+ "name": "右箭头",
+ "font_class": "arrowRight",
+ "unicode": "e863",
+ "unicode_decimal": 59491
+ },
+ {
+ "icon_id": "21151489",
+ "name": "箭头镂空-左",
+ "font_class": "jiantouloukong-zuo",
+ "unicode": "e861",
+ "unicode_decimal": 59489
+ },
+ {
+ "icon_id": "21151557",
+ "name": "箭头镂空-右",
+ "font_class": "jiantouloukong-you",
+ "unicode": "e862",
+ "unicode_decimal": 59490
+ },
{
"icon_id": "21568989",
"name": "分享",
@@ -4257,7 +4348,7 @@
{
"icon_id": "1004630",
"name": "点赞2",
- "font_class": "dianzan1",
+ "font_class": "dianzaned",
"unicode": "e639",
"unicode_decimal": 58937
},
diff --git a/public/css/iconfont.ttf b/public/css/iconfont.ttf
index 23ebbd47..9507b420 100644
Binary files a/public/css/iconfont.ttf and b/public/css/iconfont.ttf differ
diff --git a/public/css/iconfont.woff b/public/css/iconfont.woff
index 6b353baa..5bb7cb80 100644
Binary files a/public/css/iconfont.woff and b/public/css/iconfont.woff differ
diff --git a/public/css/iconfont.woff2 b/public/css/iconfont.woff2
index 3ec15ab0..3f6b8561 100644
Binary files a/public/css/iconfont.woff2 and b/public/css/iconfont.woff2 differ
diff --git a/src/forge/Component/AddMember.jsx b/src/forge/Component/AddMember.jsx
index 0548e52d..f927850c 100644
--- a/src/forge/Component/AddMember.jsx
+++ b/src/forge/Component/AddMember.jsx
@@ -4,7 +4,7 @@ import axios from 'axios';
import { getImageUrl } from 'educoder';
const { Option } = AutoComplete;
-function AddMember({getID,login}){
+function AddMember({getID,login,showNotification}){
const [ id , setID ] = useState(undefined);
const [ source , setSource ] = useState(undefined);
const [ searchKey , setSearchKey ] = useState(undefined);
@@ -45,7 +45,7 @@ function AddMember({getID,login}){
src={getImageUrl(`/${item && item.image_url}`)}
alt=""
/>
-
+
{item.username}
({item.login})
@@ -66,7 +66,12 @@ function AddMember({getID,login}){
};
function addCollaborator(){
- getID && getID(id);
+ if(source && source.length>0){
+ getID && getID(id);
+ setSearchKey(undefined);
+ }else{
+ showNotification("请选择存在的用户!");
+ }
}
return(
diff --git a/src/forge/Component/layout.jsx b/src/forge/Component/layout.jsx
index 57b20c1e..adaf4dbf 100644
--- a/src/forge/Component/layout.jsx
+++ b/src/forge/Component/layout.jsx
@@ -28,6 +28,11 @@ export const AlignTop = styled.div`{
display:flex;
align-items: flex-start;
}`
+export const AlignAJBottom = styled.div`{
+ display:flex;
+ justify-content: space-between;
+ align-items: flex-end;
+}`
// 左右结构
export const Box = styled.div`{
display:flex;
diff --git a/src/forge/Head/AddProjectModal.jsx b/src/forge/Head/AddProjectModal.jsx
new file mode 100644
index 00000000..8e3073e3
--- /dev/null
+++ b/src/forge/Head/AddProjectModal.jsx
@@ -0,0 +1,84 @@
+import React, { useState , forwardRef, useEffect } from 'react';
+import { Form , Modal , Input , Radio } from 'antd';
+import Axios from 'axios';
+
+export default Form.create()(
+ forwardRef((props)=>{
+ const { getFieldDecorator, validateFields , setFieldsValue } = props && props.form;
+ const [ visible , setVisible ] = useState(false);
+
+ useEffect(()=>{
+ if(!visible){
+ setFieldsValue({
+ code:undefined,
+ role:"developer"
+ })
+ }
+ },[visible])
+
+ function onOk() {
+ validateFields((error,values)=>{
+ if(!error){
+ const url = `/applied_projects.json`;
+ Axios.post(url,{
+ applied_project:{
+ ...values
+ }
+ }).then(result=>{
+ if(result && result.data){
+ setVisible(false);
+ props.showNotification("申请加入项目成功,等待审核!");
+ }
+ }).catch(error=>{})
+ }
+ })
+ }
+ function checkValue(rule, value, callback){
+ if(!value){
+ callback();
+ }
+ if(value.length < 6 || value.length > 6){
+ callback("请输入6位数的邀请码");
+ }
+ callback();
+ }
+
+ return(
+
-
+
-
-
-
{project && project.author &&
@@ -434,15 +435,7 @@ class Detail extends Component {
/
{project && project.name}
- {
- projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
-
+ {i.user && i.user.name} + {i.time_ago} +
+申请以【{i.role === "developer" ?"开发者":i.role === "manager" ? "管理者":"报告者"}】身份加入【{i.project && i.project.name}】项目。是否同意?
+ { + i.status === "common" && + +取消转移【{project && project.name}】仓库
case 'common': return正在将【{project && project.name}】仓库转移给【{owner && owner.name}】
- case 'successed': + case 'successed': return【{project && project.name}】仓库成功转移给【{owner && owner.name}】
default: return拒绝转移【{project && project.name}】仓库
} + }else{ + return "" + } + } + function renderApplyStatus(status,applied) { + let { project } = applied; + if(status){ + switch(status){ + case 'successed': + return已通过你加入【{project && project.name}】项目的申请
+ default: + return已拒绝你加入【{project && project.name}】项目的申请
+ } }else{ return "" } @@ -53,38 +73,40 @@ function Notify(props){ return(- {i.applied_user && i.applied_user.name} - {i.time_ago} -
- {renderStatus(i.status,i.applied)} -+ {i.applied_user && i.applied_user.name} + {i.time_ago} +
+ { i.applied_type === "AppliedProject" ? renderApplyStatus(i.status,i.applied):renderStatus(i.status,i.applied)} +请求将仓库【{i.project && i.project.name}】 - 转移给【{i.owner && i.owner.name}】,是否接受?
+ 转移给【{i.owner && i.owner.name}】,是否接受? { i.status === "common" && @@ -101,10 +105,11 @@ function UndoEvent(props){ }) }- +
{i.action_type}:{i.name}
+最多可选取6个公开仓库
+{i.description}
+近期活动统计
+this.undo_link()}> - - - 待办事项 - - - {undo_events} - -
-- 开源托管项目 - - {user && user.common_projects_count} - -
-- 开源镜像项目 - - {user && user.mirror_projects_count} - -
-- 镜像托管项目 - - {user && user.sync_mirror_projects_count} - -
-- CI服务 -
-- CD服务 - - {user && user.common_projects_count} - -
-this.organize_link()} > - - - 组织 - - - {user && user.user_org_count} - -
-从五个维度刻画你的开发能力:语言能力、影响力、贡献度、活跃度、项目经验,同时可以查看社区平均数据。
+根据你在项目开发过程中的工作,对你在项目中扮演的角色进行定位,包括:创建者、管理者、开发者、测试者、文档工作者等。
+展示你擅长、关注、感兴趣的专业范围,通过你参与项目、收藏项目、关注项目、复刻项目等数据来统计。
+
- 新建组织
+ 新建组织
{userType === "watchers" ? `${title_type}关注的` : `关注${title_type}的`}
+ {userType === "watch_users" ? `${title_type}关注的` : `关注${title_type}的`}