Compare commits

...

271 Commits

Author SHA1 Message Date
hc1913847458 a89688402a 'save' 2021-08-27 17:22:49 +08:00
hc1913847458 8626e93a86 Merge branch 'master' of https://git.trustie.net/hc1913847458/forgeplus-react 2021-08-27 17:00:49 +08:00
hc1913847458 09457d058f 'local-update' 2021-08-27 16:56:58 +08:00
hc1913847458 b7fd51ea45 'update' 2021-08-25 15:04:16 +08:00
caishi 1296167532 组织团队设置:增加可选访问单元wiki 2021-08-24 16:14:49 +08:00
caishi 0523dc2b0b 组织团队设置:可以设置版本库权限,允许设置访问项目单元 2021-08-24 15:02:04 +08:00
caishi 5bf40402c8 issue 49808 :tab页鼠标悬停规范调整 2021-08-23 14:43:09 +08:00
caishi 0d0b164370 Merge branch 'develop' of https://git.trustie.net/jasder/forgeplus-react into develop 2021-08-23 10:15:55 +08:00
caishi ec84ed56b0 reset 2021-08-23 10:15:32 +08:00
caishi 466ed1fe1b Merge branch 'pre_develop' into develop
# Conflicts:
#	public/css/iconfont.css
#	public/css/iconfont.js
#	public/css/iconfont.ttf
#	public/css/iconfont.woff
#	public/css/iconfont.woff2
2021-08-23 10:09:00 +08:00
caishi 9b101403a1 里程碑-切换分页需要带上状态参数 2021-08-23 10:08:04 +08:00
jasder fb872f3a3d change request url 2021-08-20 09:06:57 +08:00
何童崇 19ef012a0e 修改指向路径 2021-08-20 09:01:40 +08:00
jasder b3d62b9cf1 FIX bug 2021-08-19 21:54:56 +08:00
何童崇 d988c4ea5f 兼容页面刷新时的id新增 2021-08-19 21:23:48 +08:00
caishi 313f1edc71 镜像问题websocket传值
镜像问题websocket传值
2021-08-19 17:44:13 +08:00
caishi 8adc662e9b wiki功能分支合并
wiki功能分支合并
2021-08-19 17:31:36 +08:00
何童崇 ff75065a0a 新增wiki模块 2021-08-19 17:21:18 +08:00
何童崇 6e74f88d9e 紧急修复镜像bug 2021-08-19 10:40:44 +08:00
caishi 6beb4c2c8a 修复镜像项目时的展示问题
修复镜像项目时的展示问题
2021-08-18 14:43:28 +08:00
何童崇 e8dadb187b 紧急修复镜像bug 2021-08-18 14:38:11 +08:00
caishi 3a1fd14e7c 代码库-样式 2021-08-13 17:12:56 +08:00
caishi 20f64bdf81 md fullscreen 2021-08-12 17:36:37 +08:00
caishi 2347d04710 同上-细节修改 2021-08-12 15:24:45 +08:00
caishi d13d94e9cf 代码库样式整改 2021-08-12 11:45:56 +08:00
caishi 3294d99516 href 2021-08-09 11:03:49 +08:00
caishi 00402ef13d Merge branch 'master' of https://git.trustie.net/jasder/forgeplus-react
# Conflicts:
#	src/forge/Main/sub/UpdateDescModal.jsx
2021-08-09 10:37:23 +08:00
caishi 8f2df90555 代码style 2021-08-09 10:36:15 +08:00
caishi 7530d3f9c4 Merge branch 'develop' 2021-08-06 17:07:54 +08:00
caishi 001cb8da53 issue 2021-08-06 15:06:23 +08:00
caishi d09e6e2bc6 issue 2021-08-06 14:07:59 +08:00
caishi e2ad3b1308 issue-同步镜像项目不能对仓库进行操作(新建合并请求、新建发行版等) 2021-08-05 17:13:57 +08:00
caishi 14f80d56ad Merge branch 'develop' of https://git.trustie.net/jasder/forgeplus-react into develop 2021-08-05 11:12:11 +08:00
caishi 65e7025035 Merge branch 'develop' of https://git.trustie.net/jasder/forgeplus-react into develop
# Conflicts:
#	src/forge/Main/sub/UpdateDescModal.jsx
2021-08-05 11:11:51 +08:00
hc1913847458 aa786f0cf0 限制字符 2021-08-05 10:57:43 +08:00
hc1913847458 2aad9c67f5 限制字符 2021-08-05 10:53:29 +08:00
hc1913847458 b7869e5203 Merge branch 'develop' of https://git.trustie.net/jasder/forgeplus-react 2021-08-05 10:48:43 +08:00
hc1913847458 b238bb51ca 限制字符 2021-08-05 10:47:22 +08:00
hc1913847458 de636eed6d 限制字符 2021-08-05 10:42:08 +08:00
caishi 4bde5da97c markdown-issue 2021-08-05 10:30:04 +08:00
caishi f944ebad6f issue 2021-08-04 17:12:29 +08:00
hc1913847458 ad7ab189b1 限制字符 2021-08-04 14:42:08 +08:00
caishi 5140bfbe77 issue修改 2021-08-03 17:37:14 +08:00
caishi affbe87dfd 新增流水线弹框z-index 2021-08-03 10:38:39 +08:00
caishi dd1beb3116 合并请求-已拒绝的不能编辑 2021-08-03 09:34:11 +08:00
caishi d67862156c update issue 2021-08-02 15:32:51 +08:00
caishi c9802c26a4 Merge branch 'develop' 2021-08-02 10:35:49 +08:00
caishi 47365c0bed webhook-修改一版 2021-08-02 10:35:36 +08:00
caishi 4ec840f252 Merge branch 'develop' 2021-07-30 20:13:49 +08:00
caishi b1ec068663 webhook自动填充 2021-07-30 20:13:34 +08:00
caishi 44a8f806e0 Merge branch 'develop' 2021-07-30 17:44:17 +08:00
caishi 51d34a7667 同上-password-webhook 2021-07-30 17:35:53 +08:00
caishi 9408ad7dcb Merge branch 'develop' 2021-07-30 17:03:19 +08:00
caishi 2b47c1ff9a 同上-修改bug 2021-07-30 17:02:44 +08:00
caishi f7698334ab webhook上线测试版-1 2021-07-30 15:06:32 +08:00
caishi 810ea37bed Merge branch 'develop' 2021-07-26 09:38:44 +08:00
caishi f100875b0f ssh翻页 2021-07-26 09:38:21 +08:00
caishi 6679fe8a48 Merge branch 'develop' 2021-07-22 17:44:30 +08:00
caishi 4f9f5649a9 设置模块-测试版第一版 2021-07-22 17:44:12 +08:00
caishi d31b932efe Merge branch 'develop' 2021-07-21 10:10:53 +08:00
caishi f90243243f 新建项目跳转后的地址 2021-07-21 10:09:48 +08:00
caishi 7a5db58a03 appconfig 2021-07-15 14:46:22 +08:00
caishi 0889ee69c5 未登录时:路由/不显示顶部和底部 2021-07-13 10:42:56 +08:00
caishi 876ee66a05 详情:复刻按钮不能连续点击 2021-07-13 09:58:08 +08:00
caishi cb514315a6 新建合并请求:切换目标分支或者源分支时不用调用check_can_merge接口 2021-07-12 18:22:36 +08:00
caishi c5b729038c 邀请码位置,页面整体的加载 2021-07-09 17:10:55 +08:00
caishi a6d713d1f6 代码库:增加文件类型submodule 不允许点击 2021-07-09 11:28:51 +08:00
caishi ee1217e171 本地版:replaceAll无替换时报错 2021-07-09 11:05:19 +08:00
caishi 967ff385aa 代码库根目录:点击readme文件的编辑按钮时要显示编辑状态 2021-07-07 11:16:07 +08:00
caishi e6e0546e27 permission有为空的情况 2021-07-06 14:40:23 +08:00
caishi 1bb339bfb1 新建:拥有者默认选中当前登录用户,默认路由 2021-07-06 11:54:57 +08:00
caishi 07852b204c Merge branch 'develop' 2021-07-05 20:35:59 +08:00
caishi 275b7d2015 数据为0时不显示 2021-07-05 20:35:29 +08:00
caishi 9e9e4c07bf 合并请求详情:发布合并请求者跳转链接错误 2021-07-05 15:04:17 +08:00
caishi 934ac61b77 Merge branch 'develop' 2021-07-02 18:19:02 +08:00
caishi f854d2164c 工作流-构建列表-头像地址错误 2021-07-02 18:18:49 +08:00
caishi 95091d0e08 Merge branch 'develop' 2021-07-02 15:37:43 +08:00
caishi e48628389e 镜像地址增加跳转链接 2021-07-02 15:35:43 +08:00
caishi e31ff9bdf3 Merge branch 'develop' 2021-07-01 17:00:43 +08:00
caishi 62b9abedbb index.html lang="zh-cN"禁止浏览器翻译 2021-07-01 16:45:47 +08:00
caishi f97ca92e41 update 2021-07-01 15:48:04 +08:00
caishi 84bbf5fd52 易修批量修改:非项目协作者不能操作 2021-07-01 13:56:09 +08:00
caishi ff60cf11e1 update issue 2021-06-30 10:43:22 +08:00
caishi 45f188e6f4 fork项目不能修改可见性(公有私有) 2021-06-29 17:29:35 +08:00
caishi 4b832f40c0 项目详情:顶部信息排版调整,修改显示bug 2021-06-29 14:03:53 +08:00
caishi eba6ed0876 搜索的接口改用正式版对应的服务器地址 2021-06-28 10:44:42 +08:00
caishi db682ace86 Merge branch 'develop' 2021-06-25 18:34:19 +08:00
caishi 1cdf316852 合并请求:冲突文件的显示换行 2021-06-25 18:33:54 +08:00
caishi 777dbd0f43 Merge branch 'develop' 2021-06-25 18:21:48 +08:00
caishi 79996bd185 权限:易修和合并请求的新建修改等操作权限 2021-06-25 18:21:31 +08:00
caishi 2d312b6176 路由:tree后面的参数branch内容含有/ 2021-06-25 14:10:13 +08:00
caishi b44b6530e5 Merge branch 'develop' 2021-06-25 09:14:50 +08:00
caishi bad4f79a0c 易修:批量删除和批量修改issue状态要更新数量 2021-06-22 10:22:00 +08:00
caishi fad42414dc 代码库:提交信息的显示和隐藏 2021-06-21 17:52:48 +08:00
caishi c10799b6d0 Merge branch 'develop_search' into develop 2021-06-21 10:00:35 +08:00
caishi b808bcee99 Merge branch 'develop' 2021-06-18 16:56:18 +08:00
caishi cb95e50a82 代码库:从文件详情切换到文件列表时,上传文件和新建文件的按钮没有显示 2021-06-18 16:55:52 +08:00
caishi 5eaebd4e42 上传文件显示: ADD file via upload
创建新文件显示: Add 文件名
修改文件: Update 文件名
2021-06-18 14:23:46 +08:00
caishi e9badf0d7c 合并请求默认选中开启中的 2021-06-18 09:59:33 +08:00
caishi e72e817bb1 复刻自,如果是组织要跳转到组织界面 2021-06-17 16:28:27 +08:00
caishi b5835145f7 个人中心性别icon不显示 2021-06-17 11:38:53 +08:00
caishi d4e1b2f414 详情banner数量,显示开启中的数量,且执行关闭或者拒绝等修改状态的操作时要更新数量 2021-06-16 15:51:47 +08:00
caishi f4b3afde6a 项目详情和个人中心的项目列表,增加私有标识 2021-06-16 11:17:46 +08:00
caishi 5806f60491 右侧按钮-帮助弹框 2021-06-16 09:17:33 +08:00
caishi 8298aef72f forked from 文案 2021-06-15 11:36:42 +08:00
caishi 7ed8d1c8c3 合并全局搜索 2021-06-15 09:21:56 +08:00
何童崇 1d274985ca 解决冲突并提交 2021-06-11 19:03:17 +08:00
caishi c0f7c489fb Merge branch 'develop' 2021-06-11 18:11:43 +08:00
何童崇 71d1eb57cc 还原代理的配置 2021-06-11 17:51:54 +08:00
caishi 56434a9714 Merge branch 'draft' into develop 2021-06-11 17:21:27 +08:00
caishi 8b161630c3 添加成员--随便输入不存在的用户时的提示 2021-06-11 16:46:59 +08:00
何童崇 405053696c 修改头部搜索框高度和代理服务路径 2021-06-11 15:28:40 +08:00
caishi 3dffbce8d9 头部导航栏-搜索小改 2021-06-11 11:01:46 +08:00
caishi 63e9cfe394 项目邀请码-第一版测试版上线 2021-06-11 09:25:59 +08:00
何童崇 b38cdd4bb3 修改search校验,同页搜索问题 2021-06-10 17:05:49 +08:00
何童崇 681d0b17e3 修改搜索的功能及图标 2021-06-09 19:47:14 +08:00
caishi b5fa231adf 小修 2021-06-09 18:00:31 +08:00
caishi 39f0a165b6 issue 2021-06-09 18:00:09 +08:00
caishi 2157f2ffe5 merge 2021-06-09 18:00:06 +08:00
caishi 7c40f9be36 merge 冲突 2021-06-09 17:59:07 +08:00
caishi 93694594c4 冲突 2021-06-09 17:58:11 +08:00
caishi 32299252ad 详情+邀请码的显示 2021-06-09 17:37:04 +08:00
caishi a12ab04ec0 小修 2021-06-09 11:52:36 +08:00
何童崇 f93df6069c 修改搜索placeplaceholder 2021-06-08 16:08:58 +08:00
何童崇 ff2586f5b9 注释众包/帖子等tab 2021-06-08 16:05:32 +08:00
caishi b7613584f9 添加成员后要清除选中的成员 2021-06-08 15:09:52 +08:00
caishi bc64cbb415 Merge branch 'develop' 2021-06-08 14:56:20 +08:00
caishi 0b7d6ab5fd issue 2021-06-08 14:56:00 +08:00
caishi 3d764d3075 issue+新建组织-未登录没有弹出登录框 2021-06-08 10:44:44 +08:00
caishi 3cd51d1c72 修改-个人主页 2021-06-07 11:13:38 +08:00
caishi 40f8f5d872 数据统计三个时间筛选参数值必须是时间戳 2021-06-04 14:29:55 +08:00
caishi e185ae6484 同上+样式 2021-06-04 13:58:42 +08:00
caishi 0bfa7572a5 bug 2021-06-04 10:55:05 +08:00
caishi fd19a43168 修改资料+密码管理 2021-06-04 09:43:38 +08:00
何童崇 dd9c11dbd9 上传搜索的页面 2021-06-03 10:37:03 +08:00
何童崇 695d5e4f50 Merge remote-tracking branch 'upstream/develop' into dev-search 2021-06-03 10:01:51 +08:00
何童崇 b88c5b1faf 修改导航的搜索 2021-06-03 10:00:24 +08:00
caishi 975d49b80b 同上=issue修改 2021-06-02 18:22:29 +08:00
caishi 4b6592dfb3 同上-修改细节 2021-05-31 18:39:30 +08:00
caishi 1432afebfd 个人中心整体上线 2021-05-31 17:44:30 +08:00
caishi a9285f37e7 概览页数据绑定完成,只差数据统计页 2021-05-31 09:48:30 +08:00
caishi d41dce26b1 year 2021-05-28 17:02:54 +08:00
caishi 7bbda5f65d 概览+用户画像 2021-05-28 16:19:40 +08:00
caishi fa169b27cd Merge branch 'develop' 2021-05-26 16:48:35 +08:00
caishi 0274cf84ee 上一版+update 2021-05-26 16:48:18 +08:00
caishi 8e419e63da 上一版-update 2021-05-26 16:00:55 +08:00
caishi 1378ba5c93 代码库-无默认分支时调用entries接口未传ref参数,+个人主页的三个echart 2021-05-26 15:25:21 +08:00
caishi 3e0814344f Merge branch 'develop' 2021-05-25 11:25:04 +08:00
caishi ae9b48953e markdown定位问题 2021-05-25 10:05:14 +08:00
caishi eb58f91dbf Merge branch 'develop' 2021-05-21 19:21:32 +08:00
caishi 3453aa31eb readme下拉 2021-05-21 19:21:16 +08:00
caishi ebf75ed433 issue 2021-05-21 18:58:17 +08:00
caishi a1bd41795a 分享功能(仅微信)+ 合并请求增加状态的显示,合并请求详情增加(冲突情况下的提示) 2021-05-21 16:44:40 +08:00
caishi 513255428c Merge branch 'develop'
# Conflicts:
#	package-lock.json
2021-05-14 17:04:57 +08:00
caishi 09bf75c6c3 右侧按钮-帮助列表超出没有隐藏 2021-05-14 17:03:27 +08:00
caishi 70af7dae5f 右侧按钮-帮助和返回顶部 2021-05-14 14:37:59 +08:00
caishi d029840874 头部导航栏无logo是nav也要显示 2021-05-14 11:30:08 +08:00
caishi 303e06586e 新增icon+添加右侧的返回顶部等按钮(接口没有,先隐藏、需要合并到其它分支,上一个提交也一样) 2021-05-14 09:32:23 +08:00
caishi 7ccc1221ef style 2021-05-11 14:22:01 +08:00
caishi 6a6f0ca784 组件之间进行页面跳转时,滚动条未返回至顶部 2021-05-10 17:24:49 +08:00
caishi b70dd5928e details 2021-05-10 11:34:30 +08:00
caishi 8baf2cb49c install babel-polyfill 2021-05-08 17:28:14 +08:00
caishi 705bfb07bd Merge branch 'develop' 2021-05-08 16:53:26 +08:00
caishi 202081bbeb 样式 2021-05-08 16:53:16 +08:00
caishi d783d998fc 编辑合并请求-url地址错误 2021-05-08 14:36:12 +08:00
caishi af8872176c 编辑合并请求-url地址错误 2021-05-08 14:24:02 +08:00
caishi 037a79de67 detail+同步镜像type=2的才不需要合并请求 2021-05-07 17:33:41 +08:00
caishi 51925542b8 Merge branch 'develop'
# Conflicts:
#	public/css/edu-purge.css
2021-05-07 16:37:21 +08:00
caishi a408d435f3 统一项目简介、项目概览 2021-05-07 16:26:50 +08:00
caishi 016f7f1a7e 去掉Markdown代码块的间隔色、编号等+issue 2021-05-07 16:00:57 +08:00
caishi ff06efe109 merge develop 2021-05-06 17:15:43 +08:00
caishi c33561c212 新建项目-maxlength 2021-05-06 17:14:42 +08:00
caishi 2deb6f8f9d 设置所有标签的marginbottom为0 2021-05-06 17:14:30 +08:00
caishi 63d69a955e 代码库-提交描述未换行 2021-05-06 17:14:19 +08:00
caishi e7eceb5b23 issue-字符限制 2021-05-06 17:12:42 +08:00
caishi c28ae9adb3 Revert "设置所有标签的marginbottom为0"
This reverts commit 227b686046.
2021-05-06 15:15:02 +08:00
caishi 870fbaa2a9 新建项目-maxlength 2021-05-06 14:59:54 +08:00
caishi 227b686046 设置所有标签的marginbottom为0 2021-05-06 10:56:09 +08:00
caishi 582f7a39b3 代码库-提交描述未换行 2021-05-06 10:14:06 +08:00
caishi ac4b7542e2 撤销隐藏-资源库 2021-04-28 20:22:54 +08:00
caishi 3a3a0251aa Merge branch 'undo' into develop
# Conflicts:
#	src/forge/Component/SearchUser.jsx
2021-04-28 20:17:59 +08:00
caishi 2fcb645d42 04-28休假期修改issue --需合并至其它分支(合并请求相关) 2021-04-28 20:17:30 +08:00
caishi 93a53e2c7f 转移项目-bug 2021-04-27 18:44:40 +08:00
caishi 79d8f4e5ad 清空弹窗里的内容 2021-04-27 18:27:56 +08:00
caishi ae34240bfb 通知-跳转 2021-04-27 17:46:05 +08:00
caishi 4d652d238d 不能修改组织账号 2021-04-27 17:25:00 +08:00
caishi efaf0c29b5 不能修改组织账号 2021-04-27 17:24:48 +08:00
caishi 81ad2358f5 不能修改组织账号 2021-04-27 17:23:58 +08:00
caishi 605d5a047d merge undo 2021-04-27 17:15:07 +08:00
caishi 1474f5d3fe 转移项目-bug和修改需求 2021-04-27 17:12:00 +08:00
caishi 8d509f1473 组织地址、website的问题,可合并至develop 2021-04-27 17:11:37 +08:00
caishi 4ba63fd8fa 项目转移-转移权限 2021-04-27 13:50:05 +08:00
caishi e10f9893e0 组织团队-无数据显示错误 2021-04-27 09:46:39 +08:00
caishi 63d7045444 组织团队-无数据显示错误 2021-04-27 09:46:29 +08:00
caishi 6da4dbc165 组织团队-无数据显示错误 2021-04-27 09:45:14 +08:00
caishi c0ddd6eaee 组织-项目列表显示name 2021-04-26 17:20:54 +08:00
caishi f65f4c273a 组织基本设置-正则和新建的页面不一致 2021-04-26 16:32:12 +08:00
caishi 0cdb491433 组织基本设置-正则和新建的页面不一致 2021-04-26 16:32:03 +08:00
caishi ac47ba1b29 组织基本设置-正则和新建的页面不一致 2021-04-26 16:31:26 +08:00
caishi 2bd6f9cb1e 组织-新增地址和网址的显示 2021-04-26 16:17:21 +08:00
caishi 0636e0a925 转移项目-修改1 2021-04-26 16:17:04 +08:00
caishi 631b05dfd6 代码库编辑文件-切换到其它目录后要重新将编辑状态改为显示状态 2021-04-26 15:00:31 +08:00
caishi 4e48b0b363 项目转移--整体数据绑定 2021-04-26 14:59:19 +08:00
caishi 1af504825c 代码库编辑文件-切换到其它目录后要重新将编辑状态改为显示状态 2021-04-25 18:00:05 +08:00
caishi fb41baacc1 代码库编辑文件-切换到其它目录后要重新将编辑状态改为显示状态 2021-04-25 17:46:38 +08:00
caishi 09065383c1 转移项目-前端页面已画完 2021-04-25 17:38:47 +08:00
caishi e94cf68cc5 样式覆盖 2021-04-23 18:04:49 +08:00
caishi c32e215b27 样式覆盖 2021-04-23 18:04:07 +08:00
caishi 5fa2fd99b9 Merge branch 'develop' 2021-04-23 14:51:04 +08:00
caishi 2f6597355c +上 关注后不需要提示 2021-04-23 14:50:52 +08:00
caishi 20ab8a6683 Merge branch 'develop' 2021-04-23 14:47:50 +08:00
caishi 1eb3c20af4 +上 贡献者悬浮框里增加的跳转链接不要新开页 2021-04-23 14:47:32 +08:00
caishi afb599f5be 贡献者-悬浮内容增加跳转链接 2021-04-23 14:46:11 +08:00
caishi a7f709a663 Merge branch 'develop' 2021-04-23 14:16:30 +08:00
caishi d6d6df806d imageUrl + / 2021-04-23 14:14:06 +08:00
caishi 6cc97bd039 个人中心关注-关注或者取消关注未更新状态 2021-04-23 11:49:56 +08:00
caishi 037150a63c 贡献者-悬浮卡片-测试版1 2021-04-23 11:15:14 +08:00
caishi 63c2cfed70 Merge branch 'develop' 2021-04-22 10:58:30 +08:00
caishi 52dc63362b 发布评论者头像路径错误 2021-04-22 10:58:11 +08:00
caishi 29e3f0d59d 新建组织-组织账号正则 2021-04-21 16:55:10 +08:00
caishi 233e6a8226 底部样式+新建组织账号正则 2021-04-21 16:54:47 +08:00
caishi 80cd6fbae0 md文件要用Markdown渲染 2021-04-20 15:33:21 +08:00
caishi 8fa31edaae md文件要用Markdown渲染 2021-04-20 15:31:49 +08:00
caishi 49d3db6746 合并请求-提出申请者头像显示问题 2021-04-20 11:18:44 +08:00
caishi ffbb5ba34e 合并请求-提出申请者头像显示问题 2021-04-20 11:17:54 +08:00
caishi bc11ec68e3 注释 2021-04-20 10:57:46 +08:00
caishi 2d2deec224 Merge branch 'develop' 2021-04-20 10:56:50 +08:00
caishi a67cabbfb4 团队项目-团队项目管理-显示的name和跳转的login 2021-04-20 10:54:20 +08:00
caishi ceb1915939 切换左侧目录,选择不同的文件时,文件详情没有更新 2021-04-20 10:30:47 +08:00
caishi 4c65e1981e all-默认头像(首字母加背景颜色) 2021-04-20 09:36:49 +08:00
caishi 09598d0e2c 个人主页头像url 2021-04-19 19:54:57 +08:00
caishi e09490d424 上线后的getImageURL也不用在前面加/ + 一些小样式修改 2021-04-19 18:19:21 +08:00
caishi a42a670146 头像url--接口会返回所有带images的字段值,所以前端不用加固定的内容了 2021-04-19 17:52:01 +08:00
caishi b8d40259e5 readme-文件增加一个目录下拉icon 2021-04-19 16:58:30 +08:00
caishi 487a2f0495 组织团队-新增一个团队标识 2021-04-19 11:53:19 +08:00
caishi ab34369642 新建团队板块无边框 2021-04-19 10:54:02 +08:00
caishi f12228aa51 组织详情显示nickname 2021-04-19 10:35:20 +08:00
caishi 5477c41f78 资源库不需要按引用次数排序 2021-04-14 10:31:33 +08:00
caishi dc05f9ce35 组织-项目-切换协作者管理和团队管理时会重复调用增加成员接口 2021-04-13 17:12:37 +08:00
caishi b601582d15 资源库数量显示错误 2021-04-13 11:14:04 +08:00
caishi 832b18e7f5 组织-团队列表的头像login为undefined 2021-04-13 11:06:09 +08:00
caishi 8c58f77afb 去掉右侧悬浮手册按钮 2021-04-09 14:18:44 +08:00
caishi 2c363965dd 去掉悬浮手册按钮 2021-04-09 13:58:58 +08:00
caishi 60a7f39c16 forge项目暂时不显示命令行功能 2021-04-09 11:45:04 +08:00
caishi 9811276a7c ssh-3(前端固定参数已调通) 2021-04-09 10:12:39 +08:00
caishi a27c74b9aa ssh-2 2021-04-08 18:14:19 +08:00
caishi 80cae93045 ssh-初步 2021-04-08 17:44:31 +08:00
caishi 78aba67917 项目详情右侧增加实践课程链接的显示 2021-04-08 15:37:01 +08:00
caishi 43223c7787 为2时不支持在线创建、在线上传、在线修改、在线删除、创建合并请求等功能 2021-04-08 14:21:35 +08:00
caishi 961587921a projectDetail.type:0是托管项目,1是镜像项目,2是同步镜像项目(为2时不能上传新建文件、下载zip等) 2021-04-08 10:07:55 +08:00
caishi 2f595d750a entries接口传的branch值为undefined 2021-04-07 18:44:20 +08:00
caishi bcaec7a2db 新增组织账号,组织名称增加新的check条件 2021-04-06 18:40:01 +08:00
caishi 70ea6259ae 仓库设置页面增加资源库配置项 2021-04-06 17:34:37 +08:00
caishi 5d6953f2b3 资源库模块测试版第一次上线 2021-04-06 17:17:01 +08:00
caishi c8eda704e5 列表的type字段为头像跳转到个人中心或者组织的判断依据 2021-04-06 11:45:03 +08:00
caishi 5d6b95ab8f 资源库部分接口调试 2021-04-06 11:36:38 +08:00
caishi 426ea3fece 合并请求分页 2021-04-02 18:55:26 +08:00
caishi ab052ebace 第三方登录-修改邮箱和密码 2021-04-02 18:40:59 +08:00
caishi 648c6e235b 第三方账号密码重置 2021-04-02 17:39:13 +08:00
caishi 96253f3f58 列表接口、上传资源 2021-04-02 17:31:15 +08:00
caishi 101478d924 协作者管理删除按钮没显示 2021-04-02 14:08:59 +08:00
caishi dccbd6735d 构建列表里的提交信息,作者头像错误 2021-04-02 11:57:48 +08:00
caishi a0ebba839e tips 2021-04-01 19:03:56 +08:00
caishi 171f14bd2a noticeurl 2021-04-01 16:25:53 +08:00
caishi c3e09f2672 第三方登录-educoder 2021-04-01 15:35:45 +08:00
caishi 6296434527 清理appconfig文件
资源库所有页面排版、数据未绑
2021-04-01 14:41:13 +08:00
caishi e2dbda3083 工作流author 2021-03-31 17:12:31 +08:00
caishi 02f382e6fb 登录框中的找回密码、注册的url 2021-03-31 11:15:41 +08:00
caishi b568aef34e issue 2021-03-30 15:01:25 +08:00
caishi 2c83221376 按钮 2021-03-30 11:50:25 +08:00
caishi 6a4fe4d277 左侧抽屉 2021-03-30 10:26:02 +08:00
282 changed files with 16456 additions and 5339 deletions

View File

@ -1,294 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="9830c5da-176a-4c72-a301-9f6ce98c82fe" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/build/LICENSE" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/README.md" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/asset-manifest.json" beforeDir="false" afterPath="$PROJECT_DIR$/build/asset-manifest.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build/service-worker.js" beforeDir="false" afterPath="$PROJECT_DIR$/build/service-worker.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/0.b4e2ef10.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/1.68949f00.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/10.1be71b42.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/100.41f2a409.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/101.8c9ebcb9.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/102.ae5e7930.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/103.71e1260c.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/104.6010b0d8.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/105.d97473e3.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/106.a18d9295.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/107.e4fa8da8.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/108.cb5fa18c.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/109.728021f4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/11.1e6e3f2f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/110.4d60f060.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/111.00847641.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/112.dff32e36.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/113.9321d650.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/114.ab44c57c.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/115.16bc2b0d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/116.acb34db4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/117.c12032ae.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/118.06ac0c97.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/119.09fe7ab0.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/12.c388554b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/120.712692c0.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/121.5542a234.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/122.5434414a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/123.56b5aa50.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/124.4fa3c025.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/125.e90a0e54.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/126.6ac902e8.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/127.382109ca.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/128.f5cab6ce.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/129.a97defb5.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/13.5f9dd754.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/130.dc6cfef3.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/131.e36c51f6.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/132.e86e6598.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/133.cd5b0e41.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/134.a45157f4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/135.219cca2d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/136.792455ab.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/137.d98f1f26.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/138.537d528f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/139.f968f8da.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/14.ae36f994.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/140.d2937c5d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/141.41414563.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/142.085bcaac.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/143.7c7bdefd.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/144.2734eeac.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/145.0567a7a7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/146.6f118df0.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/147.8ad6802f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/148.1509b466.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/149.5a32ad42.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/15.63726bf5.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/150.67b85412.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/151.80c1ff31.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/152.a8ce322f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/153.eb7d58a7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/154.4378c4dc.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/155.fd685811.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/156.2b59a7a3.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/157.2d1b2b40.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/158.809809fb.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/159.6b94727b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/16.cd292edc.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/160.5c01b4fe.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/161.2e3c0cf9.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/162.87f4e888.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/163.0a540ffa.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/164.b22433aa.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/165.2670f91b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/166.ba688344.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/167.c636b766.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/168.96ee0643.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/169.59c6e595.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/17.9b37107f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/170.a0e40916.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/171.c5e14617.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/172.aa2c6247.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/173.f234f2ec.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/174.23eb263b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/175.978237cd.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/176.6a70c7ca.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/177.babfb8a0.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/178.ca78bfb7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/179.d209043e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/18.59166b96.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/180.34e55d7e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/181.dd0e9427.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/182.c133a270.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/183.f43e4007.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/184.3abba332.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/185.c61d56af.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/186.5ca9f085.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/187.99889df3.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/188.9a0c959d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/189.98f6f431.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/19.e9122038.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/190.a972b289.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/191.91c8d4dd.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/192.09b656bb.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/193.2db797e4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/194.570ec7dc.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/195.8bafb8cc.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/196.ebf790e4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/197.e98bbe5e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/198.59eec2cd.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/199.f7a6cf5d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/2.2225a575.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/20.ea1b83ca.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/200.64c98b62.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/201.4dcc10b4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/202.4e8c6091.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/203.d93d18f4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/204.0919cf31.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/205.1d636166.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/206.5c119f09.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/207.147ba6db.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/208.25081b68.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/209.784c19f9.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/21.66ea1441.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/210.ebc5386b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/211.ca304f55.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/212.b5fc6346.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/213.9e5a8f54.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/214.471a7c4b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/215.cf8d392b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/216.8ce08d4e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/217.03e5cde4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/218.c3b4a63d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/219.df96a008.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/22.69d33500.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/220.83a4b3b7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/221.0e7c7b15.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/222.ae23590f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/223.6e1a4ddc.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/224.66c696e0.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/225.86f6de74.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/226.334eacdf.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/227.fded1c54.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/228.081121a3.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/229.fbecdb8f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/23.f3d3a190.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/230.54214923.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/231.78c978ac.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/232.65715f0f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/233.892f3048.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/234.9aa182e7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/235.d81ddb83.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/236.69cf4cf6.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/237.71ab4f1f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/238.8572225b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/239.fcae5847.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/24.2f9ea72c.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/240.e2238e45.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/241.83f72690.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/242.d3cb57dd.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/243.99af0ef6.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/244.38603408.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/245.2d35733a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/246.e8bec9f4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/247.c9b742e0.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/248.9f3a7f5e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/249.a235bfb8.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/25.3253bb14.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/250.89a0ec2e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/251.f94f4795.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/252.614475d7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/253.16b76954.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/254.64d033a9.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/255.d2823d40.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/256.1eca44ce.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/257.7dd534ae.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/258.03522780.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/259.073dfc4a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/26.9902b511.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/260.35044602.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/261.617c2c29.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/262.031490eb.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/263.0713aea5.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/264.72a7fa9b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/265.8136f3c3.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/266.5c84b920.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/267.56ebb248.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/268.21a4574f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/269.28226efe.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/27.4304d4c5.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/270.c5d4fa4b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/271.78c89e20.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/272.c46f7455.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/273.aa76ad67.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/274.42a38d5c.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/275.eab35d6d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/276.ba152567.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/277.8ad1fd18.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/278.82ce41b4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/279.92f86639.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/28.3836fc1f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/280.d787fd18.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/281.8bdfd9de.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/282.2f9ff948.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/283.40367bdd.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/29.b7147766.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/3.31787e19.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/30.a574d03f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/31.df24e028.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/32.c4d7bbea.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/33.a4469f83.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/34.a525a713.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/35.991c6b3a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/36.ca30f366.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/37.b67239f9.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/38.d6220035.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/39.8bbe7e4b.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/4.3c8412d9.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/42.b16613be.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/46.41f6ac73.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/47.b0fb496a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/48.0f00b572.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/49.8b9d29ee.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/5.2b2c8a26.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/50.b42a5752.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/51.37761187.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/52.550fc073.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/53.86605c6d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/54.e91a419f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/55.c6646d9f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/56.b701b846.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/57.7796d2c0.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/58.865fc1eb.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/59.b58d70cd.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/6.625bd454.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/60.f785cede.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/61.f63d91e7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/62.b83b97dc.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/63.5d9d4d43.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/64.d1514b70.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/65.67458d6c.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/66.ab5a4b68.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/67.24cbd43e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/68.26be36d2.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/69.d34e03a8.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/7.45c119ae.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/70.71f3f5e9.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/71.3e0e22a5.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/72.58d589d7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/73.38beeb0e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/74.f0ac65fe.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/75.9f0bfe3e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/76.7bf08411.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/77.cc859ed7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/78.1e7b969f.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/79.d68cadb4.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/8.ce3f8347.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/80.3633279d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/81.13af2c38.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/82.dfb68271.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/83.a2cc3c51.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/84.284aff4a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/85.41f3159a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/86.4e688009.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/87.90d54fab.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/88.03076a1d.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/89.0d2f2ee8.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/9.562a7877.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/90.3b84e0a5.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/91.ad92675e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/92.6abb40b8.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/93.e5666aea.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/94.149f3765.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/95.36a069b7.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/96.c09dc12e.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/97.8ff3af84.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/98.cd3f899c.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/99.07307f5a.chunk.js" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/build/static/js/main.dda56577.js" beforeDir="false" />
<list default="true" id="9830c5da-176a-4c72-a301-9f6ce98c82fe" name="Default Changelist" comment="色值修改">
<change beforePath="$PROJECT_DIR$/src/forge/Branch/branch.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Branch/branch.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/Component/Component.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Component/Component.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/Main/Index.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Main/Index.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/Main/list.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Main/list.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/Main/sub/sub.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Main/sub/sub.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/Wiki/Index.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Wiki/Index.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/Wiki/components/Login/index.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Wiki/components/Login/index.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/Wiki/components/ModalFun/index.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/Wiki/components/ModalFun/index.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/forge/css/index.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/forge/css/index.css" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@ -525,6 +251,7 @@
<option name="width" value="1440" />
<option name="height" value="900" />
</component>
<component name="ProjectId" id="1xHteQnKsYu4IEUm8tEsYIEEC5E" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectView">
<navigator proportions="" version="1">
@ -550,18 +277,30 @@
<pane id="Scope" />
</panes>
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/src/forge/Main" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.selected.package.eslint" value="$PROJECT_DIR$/node_modules/eslint" />
<property name="node.js.path.for.package.tslint" value="project" />
<property name="node.js.selected.package.eslint" value="E:\file\forgeplus-react\node_modules\eslint" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="nodejs_package_manager_path" value="npm" />
<property name="ts.external.directory.path" value="$APPLICATION_HOME_DIR$/plugins/JavaScriptLanguage/jsLanguageServicesImpl/external" />
<property name="vue.rearranger.settings.migration" value="true" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="E:\file\forgeplus-react\src\forge\Main" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
<recent name="$PROJECT_DIR$/src/modules/user/usersInfo" />
@ -576,18 +315,7 @@
</list>
</option>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="SpringUtil" SPRING_PRE_LOADER_OPTION="true" />
<component name="SvnConfiguration">
<configuration />
@ -636,6 +364,8 @@
<workItem from="1587870344748" duration="138000" />
<workItem from="1587882941476" duration="4365000" />
<workItem from="1587891008299" duration="390000" />
<workItem from="1630023942152" duration="459000" />
<workItem from="1630024424307" duration="17223000" />
</task>
<servers />
</component>
@ -668,7 +398,7 @@
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
<option name="version" value="3" />
</component>
<component name="Vcs.Log.History.Properties">
<option name="COLUMN_ORDER">
@ -685,22 +415,7 @@
<map>
<entry key="MAIN">
<value>
<State>
<option name="RECENTLY_FILTERED_USER_GROUPS">
<collection />
</option>
<option name="RECENTLY_FILTERED_BRANCH_GROUPS">
<collection />
</option>
<option name="COLUMN_ORDER">
<list>
<option value="0" />
<option value="1" />
<option value="2" />
<option value="3" />
</list>
</option>
</State>
<State />
</value>
</entry>
</map>
@ -719,6 +434,19 @@
</entry>
</map>
</option>
<option name="oldMeFiltersMigrated" value="true" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="javascript">
<url>file://$PROJECT_DIR$/src/forge/Main/CoderDepot.jsx</url>
<line>409</line>
<properties lambdaOrdinal="-1" />
<option name="timeStamp" value="1" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/modules/user/usersInfo/usersInfo.css">

539
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "forge",
"version": "0.1.0",
"version": "3.0.0",
"private": true,
"dependencies": {
"@monaco-editor/react": "^2.3.0",
@ -14,6 +14,7 @@
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-polyfill": "^6.26.0",
"babel-preset-react-app": "^3.1.1",
"babel-runtime": "6.26.0",
"bizcharts": "^3.5.8",
@ -29,7 +30,8 @@
"dompurify": "^2.0.15",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"echarts": "^4.7.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",
@ -46,6 +48,7 @@
"install": "^0.12.2",
"jest": "20.0.4",
"js-base64": "^2.5.2",
"js2wordcloud": "^1.1.12",
"katex": "^0.11.1",
"lodash": "^4.17.15",
"loglevel": "^1.6.8",
@ -62,7 +65,7 @@
"postcss-loader": "2.0.8",
"promise": "8.0.1",
"prop-types": "^15.6.1",
"qrcode.react": "^1.0.0",
"qrcode.react": "^1.0.1",
"qs": "^6.9.3",
"quill": "^1.3.7",
"quill-delta-to-html": "^0.11.0",
@ -92,6 +95,7 @@
"react-resizable": "^1.10.1",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-slick": "^0.28.1",
"react-split-pane": "^0.1.91",
"react-url-query": "^1.5.0",
"react-zmage": "^0.8.5-beta.31",
@ -102,6 +106,7 @@
"scroll-into-view": "^1.14.2",
"showdown": "^1.9.1",
"showdown-katex": "^0.8.0",
"slick-carousel": "^1.8.1",
"store": "^2.0.12",
"style-loader": "0.19.0",
"styled-components": "^4.4.1",
@ -111,7 +116,9 @@
"webpack-dev-server": "^3.10.3",
"webpack-manifest-plugin": "^2.2.0",
"whatwg-fetch": "2.0.3",
"wrap-md-editor": "^0.2.20"
"wrap-md-editor": "^0.2.20",
"xterm": "4.8.1",
"xterm-addon-fit": "0.4.0"
},
"scripts": {
"start": "node --max_old_space_size=15360 scripts/start.js",
@ -186,6 +193,7 @@
"babel-core": "^6.26.0",
"babel-plugin-import": "^1.13.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
@ -196,6 +204,7 @@
"node-sass": "^4.12.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"purgecss": "^2.1.2",
"react-json-view": "^1.21.3",
"reqwest": "^2.0.5",
"resize-observer-polyfill": "^1.5.1",
"terser-webpack-plugin": "^2.3.5",

File diff suppressed because one or more lines are too long

View File

@ -38,78 +38,6 @@
box-sizing: border-box;
}
.head-nav ul#header-nav li {
float: left;
height: 60px;
line-height: 60px;
margin-right: 30px;
cursor: pointer;
position: relative;
font-size: 16px
}
.head-nav ul#header-nav li a {
display: block;
height: 100%;
width: 100%;
color: #fff
}
.head-nav ul#header-nav li a:hover {
color: #cccccc;
}
.head-nav ul#header-nav li:last-child {
margin-right: 0px
}
.head-nav ul#header-nav li.active a {
color: #459be5 !important;
}
.head-nav ul#header-nav li.active p {
color: #459be5 !important;
}
.head-nav ul#header-nav li p:hover {
color: #cccccc;
}
.head-nav ul#header-nav li p {
display: block;
height: 100%;
width: 100%;
color: #fff
}
.head-nav ul#header-nav li.active div ul li a {
color: #000 !important;
}
.head-nav ul#header-nav li.active div ul li a:hover {
color: #FFF !important;
}
.head-nav ul#header-nav li.active ul li a {
color: #000 !important;
}
.head-nav ul#header-nav li.active ul li a:hover {
color: #FFF !important;
}
.head-nav ul#header-nav li.active:after {
content: '';
position: absolute;
left: 0px;
top: auto;
bottom: 10px;
right: auto;
height: 2px;
width: 14px;
background-color: #459be5;
}
.nav-img {
position: absolute;
top: 2px;

View File

@ -114,14 +114,6 @@ a:visited {
color: #898989;
}
a:hover {
color: #FF7500;
}
a:hover.fa {
color: #FF7500;
}
input,
textarea,
select {

View File

@ -97,10 +97,6 @@ a:visited {
color: #05101a;
}
a:hover {
color: #459be5;
}
ol,
ul,
li {

View File

@ -1363,9 +1363,9 @@ a:visited {
color: #05101a;
}
a:hover {
color: #459be5;
}
/*a:hover {*/
/* color: #2A61FF!important;*/
/*}*/
ol,
ul,
@ -1473,7 +1473,7 @@ a.edu-txt-w80,
/*隐藏*/
.none {
display: none
display: none!important;
}
.block {
@ -1609,7 +1609,7 @@ a.decoration {
}
.mt6 {
margin-top: 6px;
margin-top: 3px;
}
.mt7 {
@ -1753,7 +1753,7 @@ a.decoration {
}
.mb15 {
margin-bottom: 15px;
margin-bottom: 15px!important;
}
.mb16 {
@ -2346,7 +2346,6 @@ input::-ms-clear {
/*中间部分宽度固定为1200*/
.newMain {
margin: 0 auto;
padding-bottom: 110px;
min-width: 1200px;
}
@ -2425,13 +2424,19 @@ input::-ms-clear {
.color-grey-c {
color: #ccc !important;
}
a.hoverLine:hover{
text-decoration: underline;
}
.color-grey-cd {
color: #cdcdcd !important;
}
.color-grey-d {
color: #ddd;
}
.color-grey-9 {
color: #999999 !important;
color: #333333 !important;
}
.color-grey-98 {
@ -2466,33 +2471,24 @@ input::-ms-clear {
a.color-grey-name:hover,
a.color-dark:hover,
a.color-grey-6:hover,
a.color-grey-3:hover {
color: #4cacff !important;
}
a.color-grey-9:hover,
a.color-grey-8:hover,
a.color-grey-c:hover {
color: #111C24 !important;
a.color-grey-3:hover,a.color-ooo span:hover{
color: #466AFF !important;
}
/*蓝色*/
.color-blue {
.color-blue, .color-blue-file{
color: #4CACFF !important;
}
/* 绿色 */
.color-green-file{
color: #28BD6C;
.color-blue {
color: #2A61FF !important;
}
/* 绿色 */
/*主*/
.color-blue_4C {
color: #4CACFF !important;
}
a.color-blue:hover,
a.color-blue_4C:hover {
color: #459BE6 !important;
}
/*橙色*/
.color-orange {
@ -3410,7 +3406,7 @@ a.user_bluebg_btn {
}
.cdefault {
cursor: default
cursor: default!important;
}
@ -3585,42 +3581,6 @@ a.user_bluebg_btn {
margin-right: 5px;
}
/*-------------------个人主页:右侧提示区域--------------------------*/
.-task-sidebar {
position: fixed;
width: 40px;
height: 180px;
right: 0;
bottom: 80px;
z-index: 10;
}
.-task-sidebar div {
height: 40px;
line-height: 40px;
box-sizing: border-box;
width: 40px;
background: #4CACFF;
color: #fff;
font-size: 20px;
text-align: center;
margin-bottom: 5px;
border-radius: 4px;
}
.-task-sidebar div i {
color: #fff;
}
.-task-sidebar div i:hover {
color: #fff !important;
}
.gotop {
background-color: rgba(208, 207, 207, 0.5) !important;
padding: 0px !important;
}
/***** loading ******/
/*****载入中******/
@ -3945,11 +3905,21 @@ html>body #ajax-indicator {
max-height: 340px;
}/*头部导航条样式---2018-03-19--by-cs*/
.privateTag{
display: block;
padding:0px 6px;
border-radius: 12px;
border:1px solid #2FC25B;
height: 18px;
line-height: 18px;
font-size: 12px;
margin-left: 10px;
color: #2FC25B;
}
.head-nav {
text-align: center;
height: 70px;
box-sizing: border-box;
min-width: 780px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@ -3971,7 +3941,7 @@ html>body #ajax-indicator {
cursor: pointer;
position: relative;
font-size: 16px;
padding:0px 20px;
padding-right:40px;
}
.head-nav ul#header-nav li a {
@ -4108,21 +4078,6 @@ em.vertical-line {
/* 右侧内容宽度变化的话需要调整posi-search right的值*/
/*底部*/
.newFooter {
max-height: 110px;
}
.newFooter {
position: absolute;
bottom: 0;
width: 100%;
background: #323232;
clear: both;
min-width: 1200px;
z-index: 8;
left: 0px;
}
.footercon {
border-bottom: 1px solid #47494d;
@ -6719,3 +6674,18 @@ ul.count_ul li:not(:last-child):after {
input.ant-input-lg::placeholder{
font-size: 14px !important;
}
p{
margin-bottom: 0px!important;
}
.toprightNum{
position: absolute;
right: 0px;
top:4px;
color: #999;
}
.ant-input, .ant-input .ant-input-suffix{
background-color: #fff!important;
}
.has-error .ant-input{
background-color: #FEF1F0!important;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,692 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "23791639",
"name": "项目公告",
"font_class": "xiangmugonggao",
"unicode": "e8c2",
"unicode_decimal": 59586
},
{
"icon_id": "23791640",
"name": "成果",
"font_class": "chengguo",
"unicode": "e8c3",
"unicode_decimal": 59587
},
{
"icon_id": "23791410",
"name": "成交公告",
"font_class": "chengjiaogonggao",
"unicode": "e8c0",
"unicode_decimal": 59584
},
{
"icon_id": "23791411",
"name": "技术资产",
"font_class": "jishuzichan",
"unicode": "e8c1",
"unicode_decimal": 59585
},
{
"icon_id": "23790928",
"name": "废标公告",
"font_class": "feibiaogonggao",
"unicode": "e8bc",
"unicode_decimal": 59580
},
{
"icon_id": "23790929",
"name": "中标公告",
"font_class": "zhongbiaogonggao",
"unicode": "e8bd",
"unicode_decimal": 59581
},
{
"icon_id": "23790930",
"name": "更正公告",
"font_class": "gengzhenggonggao",
"unicode": "e8be",
"unicode_decimal": 59582
},
{
"icon_id": "23790931",
"name": "招标公告",
"font_class": "zhaobiaogonggao",
"unicode": "e8bf",
"unicode_decimal": 59583
},
{
"icon_id": "23732532",
"name": "文件",
"font_class": "wenjian6",
"unicode": "e8ba",
"unicode_decimal": 59578
},
{
"icon_id": "23732533",
"name": "文件夹",
"font_class": "wenjianjia4",
"unicode": "e8bb",
"unicode_decimal": 59579
},
{
"icon_id": "23642443",
"name": "取消关注",
"font_class": "quxiaoguanzhu",
"unicode": "e89a",
"unicode_decimal": 59546
},
{
"icon_id": "23642444",
"name": "点赞_icon",
"font_class": "dianzan_icon",
"unicode": "e8a2",
"unicode_decimal": 59554
},
{
"icon_id": "23639530",
"name": "文件",
"font_class": "wenjian5",
"unicode": "e896",
"unicode_decimal": 59542
},
{
"icon_id": "23639533",
"name": "文件夹",
"font_class": "wenjianjia3",
"unicode": "e8a9",
"unicode_decimal": 59561
},
{
"icon_id": "23639440",
"name": "复制icon",
"font_class": "fuzhiicon",
"unicode": "e886",
"unicode_decimal": 59526
},
{
"icon_id": "23639422",
"name": "主页-fill",
"font_class": "zhuye-fill",
"unicode": "e876",
"unicode_decimal": 59510
},
{
"icon_id": "23639423",
"name": "代码库icon",
"font_class": "daimakuicon",
"unicode": "e884",
"unicode_decimal": 59524
},
{
"icon_id": "23572260",
"name": "新建",
"font_class": "xinjian2",
"unicode": "e8b0",
"unicode_decimal": 59568
},
{
"icon_id": "23567674",
"name": "协议icon",
"font_class": "xieyiicon",
"unicode": "e870",
"unicode_decimal": 59504
},
{
"icon_id": "23567675",
"name": "内存icon",
"font_class": "neicunicon",
"unicode": "e891",
"unicode_decimal": 59537
},
{
"icon_id": "23567676",
"name": "自述文件_icon",
"font_class": "zishuwenjian_icon",
"unicode": "e8a6",
"unicode_decimal": 59558
},
{
"icon_id": "23472253",
"name": "标签icon",
"font_class": "biaoqianicon",
"unicode": "e882",
"unicode_decimal": 59522
},
{
"icon_id": "23472254",
"name": "编 辑",
"font_class": "a-bianji",
"unicode": "e883",
"unicode_decimal": 59523
},
{
"icon_id": "23472256",
"name": "仓库设置icon",
"font_class": "cangkushezhiicon",
"unicode": "e885",
"unicode_decimal": 59525
},
{
"icon_id": "23472258",
"name": "链接icon",
"font_class": "lianjieicon",
"unicode": "e887",
"unicode_decimal": 59527
},
{
"icon_id": "23472259",
"name": "合并请求icon",
"font_class": "hebingqingqiuicon",
"unicode": "e888",
"unicode_decimal": 59528
},
{
"icon_id": "23472260",
"name": "里程碑icon",
"font_class": "lichengbeiicon",
"unicode": "e889",
"unicode_decimal": 59529
},
{
"icon_id": "23472261",
"name": "工作流icon",
"font_class": "gongzuoliuicon",
"unicode": "e88a",
"unicode_decimal": 59530
},
{
"icon_id": "23472262",
"name": "动态icon",
"font_class": "dongtaiicon",
"unicode": "e88b",
"unicode_decimal": 59531
},
{
"icon_id": "23472263",
"name": "默认点赞_icon",
"font_class": "morendianzan_icon",
"unicode": "e88e",
"unicode_decimal": 59534
},
{
"icon_id": "23472265",
"name": "目录icon",
"font_class": "muluicon",
"unicode": "e894",
"unicode_decimal": 59540
},
{
"icon_id": "23472267",
"name": "设 置",
"font_class": "a-shezhi",
"unicode": "e899",
"unicode_decimal": 59545
},
{
"icon_id": "23472269",
"name": "提交icon",
"font_class": "tijiaoicon",
"unicode": "e89e",
"unicode_decimal": 59550
},
{
"icon_id": "23472270",
"name": "默认关注_ICON",
"font_class": "morenguanzhu_ICON",
"unicode": "e89f",
"unicode_decimal": 59551
},
{
"icon_id": "23472272",
"name": "下拉按钮",
"font_class": "xialaanniu1",
"unicode": "e8a4",
"unicode_decimal": 59556
},
{
"icon_id": "23472276",
"name": "左滑icon",
"font_class": "zuohuaicon",
"unicode": "e8b5",
"unicode_decimal": 59573
},
{
"icon_id": "23472277",
"name": "master_icon",
"font_class": "master_icon",
"unicode": "e8b6",
"unicode_decimal": 59574
},
{
"icon_id": "23472278",
"name": "默认复刻_icon",
"font_class": "morenfuke_icon",
"unicode": "e8b7",
"unicode_decimal": 59575
},
{
"icon_id": "23472279",
"name": "wiki icon",
"font_class": "a-wikiicon",
"unicode": "e8b8",
"unicode_decimal": 59576
},
{
"icon_id": "23472280",
"name": "易修icon",
"font_class": "yixiuicon",
"unicode": "e8b9",
"unicode_decimal": 59577
},
{
"icon_id": "23436350",
"name": "缩放",
"font_class": "suofang",
"unicode": "e87f",
"unicode_decimal": 59519
},
{
"icon_id": "23436351",
"name": "放大icon",
"font_class": "fangdaicon",
"unicode": "e881",
"unicode_decimal": 59521
},
{
"icon_id": "23384231",
"name": "搜索_icon",
"font_class": "sousuo_icon1",
"unicode": "e873",
"unicode_decimal": 59507
},
{
"icon_id": "23384232",
"name": "欢迎_icon",
"font_class": "huanying_icon",
"unicode": "e878",
"unicode_decimal": 59512
},
{
"icon_id": "23384233",
"name": "文件夹",
"font_class": "wenjianjia2",
"unicode": "e879",
"unicode_decimal": 59513
},
{
"icon_id": "23384234",
"name": "删除icon",
"font_class": "shanchuicon1",
"unicode": "e87a",
"unicode_decimal": 59514
},
{
"icon_id": "23261798",
"name": "请求icon",
"font_class": "qingqiuicon",
"unicode": "e871",
"unicode_decimal": 59505
},
{
"icon_id": "23261799",
"name": "响应icon",
"font_class": "xiangyingicon",
"unicode": "e87c",
"unicode_decimal": 59516
},
{
"icon_id": "23144143",
"name": "多选选中",
"font_class": "duoxuanxuanzhong",
"unicode": "e88f",
"unicode_decimal": 59535
},
{
"icon_id": "23144144",
"name": "错误icon",
"font_class": "cuowuicon",
"unicode": "e890",
"unicode_decimal": 59536
},
{
"icon_id": "23144146",
"name": "成功icon",
"font_class": "chenggongicon",
"unicode": "e892",
"unicode_decimal": 59538
},
{
"icon_id": "23144147",
"name": "未选中响应icon",
"font_class": "weixuanzhongxiangyingicon",
"unicode": "e893",
"unicode_decimal": 59539
},
{
"icon_id": "23144149",
"name": "必填icon",
"font_class": "bitianicon",
"unicode": "e895",
"unicode_decimal": 59541
},
{
"icon_id": "23144151",
"name": "未选中项目标签icon",
"font_class": "weixuanzhongxiangmubiaoqianicon",
"unicode": "e897",
"unicode_decimal": 59543
},
{
"icon_id": "23144152",
"name": "列表icon",
"font_class": "liebiaoicon",
"unicode": "e898",
"unicode_decimal": 59544
},
{
"icon_id": "23144155",
"name": "未选中请求icon",
"font_class": "weixuanzhongqingqiuicon",
"unicode": "e89b",
"unicode_decimal": 59547
},
{
"icon_id": "23144158",
"name": "协作者管理icon",
"font_class": "xiezuozheguanliicon",
"unicode": "e8a1",
"unicode_decimal": 59553
},
{
"icon_id": "23144160",
"name": "选中分支icon",
"font_class": "xuanzhongfenzhiicon",
"unicode": "e8a3",
"unicode_decimal": 59555
},
{
"icon_id": "23144162",
"name": "选中基本设置icon",
"font_class": "xuanzhongjibenshezhiicon",
"unicode": "e8a5",
"unicode_decimal": 59557
},
{
"icon_id": "23144165",
"name": "选中项目标签icon",
"font_class": "xuanzhongxiangmubiaoqianicon",
"unicode": "e8aa",
"unicode_decimal": 59562
},
{
"icon_id": "23144167",
"name": "选中webhook icon",
"font_class": "a-xuanzhongwebhookicon",
"unicode": "e8af",
"unicode_decimal": 59567
},
{
"icon_id": "23046290",
"name": "shanchu_tc_icon",
"font_class": "shanchu_tc_icon",
"unicode": "e88c",
"unicode_decimal": 59532
},
{
"icon_id": "23046293",
"name": "wiki_icon",
"font_class": "wiki_icon",
"unicode": "e88d",
"unicode_decimal": 59533
},
{
"icon_id": "23046244",
"name": "导入模版_icon",
"font_class": "daorumoban_icon",
"unicode": "e86f",
"unicode_decimal": 59503
},
{
"icon_id": "23046252",
"name": "错误",
"font_class": "cuowu",
"unicode": "e872",
"unicode_decimal": 59506
},
{
"icon_id": "23046255",
"name": "更多_icon",
"font_class": "gengduo_icon",
"unicode": "e874",
"unicode_decimal": 59508
},
{
"icon_id": "23046258",
"name": "复层关闭_icon",
"font_class": "fucengguanbi_icon",
"unicode": "e875",
"unicode_decimal": 59509
},
{
"icon_id": "23046268",
"name": "删除icon",
"font_class": "shanchuicon",
"unicode": "e877",
"unicode_decimal": 59511
},
{
"icon_id": "23046273",
"name": "搜索_删除icon",
"font_class": "sousuo_shanchuicon",
"unicode": "e87b",
"unicode_decimal": 59515
},
{
"icon_id": "23046275",
"name": "搜索_icon",
"font_class": "sousuo_icon",
"unicode": "e87d",
"unicode_decimal": 59517
},
{
"icon_id": "23046276",
"name": "文档预览_icon",
"font_class": "wendangyulan_icon",
"unicode": "e87e",
"unicode_decimal": 59518
},
{
"icon_id": "23046278",
"name": "下拉按钮",
"font_class": "xialaanniu",
"unicode": "e880",
"unicode_decimal": 59520
},
{
"icon_id": "22906287",
"name": "二次确认_icon",
"font_class": "erciqueren_icon",
"unicode": "e867",
"unicode_decimal": 59495
},
{
"icon_id": "22906288",
"name": "选中ssh_icon",
"font_class": "xuanzhongssh_icon",
"unicode": "e868",
"unicode_decimal": 59496
},
{
"icon_id": "22906289",
"name": "未选中安全设置_icon",
"font_class": "weixuanzhonganquanshezhi_icon",
"unicode": "e869",
"unicode_decimal": 59497
},
{
"icon_id": "22906290",
"name": "未选中ssh_icon",
"font_class": "weixuanzhongssh_icon",
"unicode": "e86a",
"unicode_decimal": 59498
},
{
"icon_id": "22906291",
"name": "选中安全设置_icon",
"font_class": "xuanzhonganquanshezhi_icon",
"unicode": "e86b",
"unicode_decimal": 59499
},
{
"icon_id": "22906292",
"name": "删除_icon",
"font_class": "shanchu_icon",
"unicode": "e86c",
"unicode_decimal": 59500
},
{
"icon_id": "22906293",
"name": "列表ssh_icon",
"font_class": "liebiaossh_icon",
"unicode": "e86e",
"unicode_decimal": 59502
},
{
"icon_id": "17575494",
"name": "file-submodule",
"font_class": "file-submodule",
"unicode": "e866",
"unicode_decimal": 59494
},
{
"icon_id": "7539612",
"name": "nv",
"font_class": "nv1",
"unicode": "e864",
"unicode_decimal": 59492
},
{
"icon_id": "7539613",
"name": "nan",
"font_class": "nan1",
"unicode": "e865",
"unicode_decimal": 59493
},
{
"icon_id": "21936935",
"name": "邮箱",
"font_class": "youxiang",
"unicode": "e8b2",
"unicode_decimal": 59570
},
{
"icon_id": "21936924",
"name": "单位",
"font_class": "danwei",
"unicode": "e8a7",
"unicode_decimal": 59559
},
{
"icon_id": "21936925",
"name": "待办事项",
"font_class": "daibanshixiang",
"unicode": "e8a8",
"unicode_decimal": 59560
},
{
"icon_id": "21936928",
"name": "概览",
"font_class": "gailan",
"unicode": "e8ab",
"unicode_decimal": 59563
},
{
"icon_id": "21936929",
"name": "男",
"font_class": "nan",
"unicode": "e8ac",
"unicode_decimal": 59564
},
{
"icon_id": "21936930",
"name": "女",
"font_class": "nv",
"unicode": "e8ad",
"unicode_decimal": 59565
},
{
"icon_id": "21936931",
"name": "工作流",
"font_class": "gongzuoliu1",
"unicode": "e8ae",
"unicode_decimal": 59566
},
{
"icon_id": "21936934",
"name": "数据统计",
"font_class": "shujutongji",
"unicode": "e8b1",
"unicode_decimal": 59569
},
{
"icon_id": "21936936",
"name": "项目",
"font_class": "xiangmu",
"unicode": "e8b3",
"unicode_decimal": 59571
},
{
"icon_id": "21936937",
"name": "组织",
"font_class": "zuzhi",
"unicode": "e8b4",
"unicode_decimal": 59572
},
{
"icon_id": "14835599",
"name": "右箭头",
"font_class": "arrowRight",
"unicode": "e863",
"unicode_decimal": 59491
},
{
"icon_id": "21151489",
"name": "箭头镂空-左",
"font_class": "jiantouloukong-zuo",
"unicode": "e861",
"unicode_decimal": 59489
},
{
"icon_id": "21151557",
"name": "箭头镂空-右",
"font_class": "jiantouloukong-you",
"unicode": "e862",
"unicode_decimal": 59490
},
{
"icon_id": "21568989",
"name": "分享",
"font_class": "fenxiang1",
"unicode": "e89c",
"unicode_decimal": 59548
},
{
"icon_id": "21568990",
"name": "回到顶部",
"font_class": "huidaodingbu1",
"unicode": "e89d",
"unicode_decimal": 59549
},
{
"icon_id": "21568993",
"name": "帮助",
"font_class": "bangzhu",
"unicode": "e8a0",
"unicode_decimal": 59552
},
{
"icon_id": "991344",
"name": "提交",
@ -4236,7 +4922,7 @@
{
"icon_id": "1004630",
"name": "点赞2",
"font_class": "dianzan1",
"font_class": "dianzaned",
"unicode": "e639",
"unicode_decimal": 58937
},

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 733 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/favicon.ico Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="zh-CN" class="notranslate translated-ltr" translate="no">
<head>
<meta charset="utf-8">
<meta name=”Keywords” Content=”trustie,trustieforge,forge,确实让创建更美好,协同开发平台″>

View File

@ -60,12 +60,13 @@ body {
.ant-progress-textno {
color: #f5222d;
}
.CodeMirror pre.CodeMirror-line{
font-size: 16px!important;
}
/* md多空格 */
.markdown-body p {
margin:10px 0px!important;
font-size: 16px !important;
line-height: 2 !important;
white-space: pre-wrap;
}
@ -87,6 +88,10 @@ body {
border-left: 1px solid rgb(221, 221, 221);
/* 某些情况下被cm盖住了 */
z-index: 99;
padding:8px 8px 50px;
}
.editormd-preview .markdown-body{
padding:0px !important;
}
/* 图片点击放大的场景,隐藏图片链接 */

View File

@ -17,8 +17,7 @@ import marked from './common/marked';
import moment from 'moment'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import history from './history';
import SiderBar from './forge/Component/SiderBar'
import { SnackbarHOC } from 'educoder'
import { initAxiosInterceptors } from './AppConfig'
@ -40,6 +39,11 @@ const Projects = Loadable({
loader: () => import('./forge/Index'),
loading: Loading,
})
//forge安全设置
const Security = Loadable({
loader: () => import('./forge/SecuritySetting/Index'),
loading: Loading,
})
//forge项目-devOps详情
const OpsDetail = Loadable({
loader: () => import('./forge/DevOps/opsDetail'),
@ -74,7 +78,19 @@ const EducoderLogin = Loadable({
loader: () => import('./modules/login/EducoderLogin'),
loading: Loading,
})
const Search = Loadable({
loader: () => import('./modules/search/'),
loading: Loading,
})
const WikiPreview = Loadable({
loader: () => import('./forge/Wiki/Preview'),
loading: Loading,
})
const ProjectIndex = Loadable({
loader: () => import("./forge/Index"),
loading: Loading,
});
class App extends Component {
constructor(props) {
super(props);
@ -100,36 +116,9 @@ class App extends Component {
Addcoursestypes: false
})
};
ModalCancelsy = () => {
this.setState({
mydisplay: false,
})
window.location.href = "/";
};
ModalshowCancelsy = () => {
this.setState({
mydisplay: true,
})
};
disableVideoContextMenu = () => {
window.$("body").on("mousedown", "video", function (event) {
if (event.which === 3) {
window.$('video').bind('contextmenu', function () { return false; });
} else {
window.$('video').unbind('contextmenu');
}
});
}
componentDidMount() {
document.title = "loading...";
this.disableVideoContextMenu();
history.listen(() => {
this.forceUpdate()
const $ = window.$
$("html").animate({ scrollTop: $('html').scrollTop() - 0 })
});
initAxiosInterceptors(this.props);
this.getAppdata();
@ -207,13 +196,23 @@ class App extends Component {
};
render() {
const { mygetHelmetapi } = this.state;
let personal = mygetHelmetapi && mygetHelmetapi.personal;
return (
<Provider store={store}>
<ConfigProvider locale={zhCN}>
<MuiThemeProvider theme={theme}>
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
<SiderBar />
<Router>
<Switch>
{/* wiki预览 */}
<Route path="/projects/:owner/:projectsId/wiki/preview/:projectName/:projectId" render={
(props) => {
return (<WikiPreview {...this.props} {...props} {...this.state} />)
}
} />
{/*项目*/}
<Route
path={"/projects/:owner/:projectId/devops/:opsId/detail"}
@ -223,6 +222,14 @@ class App extends Component {
}
}>
</Route>
<Route
path={"/settings"}
render={
(props) => {
return (<Security {...this.props} {...props} {...this.state} />)
}
}>
</Route>
{/*项目*/}
<Route
path={"/projects"}
@ -253,6 +260,11 @@ class App extends Component {
</Route>
{/*404*/}
<Route path="/nopage" component={Shixunnopage} />
{/* 查询 */}
<Route path="/search" component={Search} />
{/* 个人主页 */}
<Route path="/users/:username"
render={
@ -263,7 +275,10 @@ class App extends Component {
<Route exact path="/"
render={
(props) => (
<Projects {...this.props} {...props} {...this.state}></Projects>
personal && personal.length > 0 ?
<InfosIndex {...this.props} {...props} />
:
<ProjectIndex {...this.props} {...props} />
)
}
/>

View File

@ -2,7 +2,7 @@ import axios from 'axios';
import { requestProxy } from "./indexEduplus2RequestProxy";
import { broadcastChannelOnmessage, isDev, queryString } from 'educoder';
import { notification } from 'antd';
import cookie from 'react-cookies';
import './index.css';
let message501 = false;
@ -11,9 +11,7 @@ broadcastChannelOnmessage('refreshPage', () => {
})
function locationurl(list) {
if (window.location.port === "3007") {
} else {
if (window.location.port !== "3007") {
window.location.href = list
}
}
@ -29,50 +27,19 @@ if (isDev) {
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
}
function clearAllCookie() {
cookie.remove('_educoder_session', { path: '/' });
cookie.remove('autologin_trustie', { path: '/' });
setpostcookie()
}
clearAllCookie();
function setpostcookie() {
const str = window.location.pathname;
if (str.indexOf("/wxcode") !== -1) {
cookie.remove('_educoder_session', { path: '/' });
cookie.remove('autologin_trustie', { path: '/' });
const _params = window.location.search;
if (_params) {
let _search = _params.split('?')[1];
let _educoder_sessions = _search.split('&')[0].split('=');
cookie.save('_educoder_session', _educoder_sessions[1], { domain: '.educoder.net', path: '/' });
let autologin_trusties = _search.split('&')[1].split('=');
cookie.save('autologin_trustie', autologin_trusties[1], { domain: '.educoder.net', path: '/' });
}
}
}
setpostcookie();
window._debugType = debugType;
export function initAxiosInterceptors(props) {
// 判断网络是否连接
initOnlineOfflineListener();
var proxy = "http://localhost:3000";
proxy = "https://testforgeplus.trustie.net";
const requestMap = {};
window.setfalseInRequestMap = function (keyName) {
requestMap[keyName] = false;
}
var proxy = "https://testforgeplus.trustie.net";
//响应前的设置
axios.interceptors.request.use(
config => {
setpostcookie()
clearAllCookie()
if (config.url.indexOf(proxy) !== -1) {
if(config.url.indexOf("http") !== -1) {
return config
}
requestProxy(config)
requestProxy(config);
let url = `/api${config.url}`;
if (`${config[0]}` !== `true`) {
@ -86,12 +53,6 @@ export function initAxiosInterceptors(props) {
} else {
config.url = url;
}
setpostcookie();
}
if (config.url.indexOf('update_file') === -1) {
requestMap[config.url] = true;
window.setTimeout("setfalseInRequestMap('" + config.url + "')", 900)
}
return config;
},
@ -146,8 +107,6 @@ export function initAxiosInterceptors(props) {
message501 = false
}, 2000);
}
requestMap[response.config.url] = false;
setpostcookie();
return response;
}, function (error) {
return Promise.reject(error);

View File

@ -9,20 +9,7 @@ class Loading extends Component {
}
render() {
return (
<div className="App" style={{ minHeight: '800px', width: "100%" }}>
<style>
{
`
.margintop{
margin-top:20%;
}
`
}
</style>
<Spin size="large" className={"margintop"} />
</div>
);
return ""
}
}

View File

@ -218,7 +218,7 @@ a:hover {
}
.color-blue {
color: #4CACFF;
color: #2A61FF;
}
.color-huang {

View File

@ -1,4 +1,5 @@
import moment from "moment";
import { number } from "prop-types";
// 处理整点 半点
// 取传入时间往后的第一个半点
@ -97,3 +98,40 @@ export function formatDuring(mss){
}
return days + "天" + hours + "小时" + minutes + "分";
}
/*
返回多久以前
backDate以前的某个日期
*/
export function timeAgo(backDate) {
try {
moment(backDate);
} catch (e) {
return;
}
if(typeof backDate ==='number'){
backDate=backDate*1000
}else{
backDate= moment(backDate);
}
let time = new Date() - backDate;
var days = Math.floor(time / (1000 * 60 * 60 * 24));
var hours = Math.floor((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((time % (1000 * 60 * 60)) / 1000);
if (time <= 0) {
return "刚刚";
}
if (days) {
return days + "天前";
}
if (hours) {
return hours + "小时前";
}
if (minutes) {
return minutes + "分前";
}
if (seconds) {
return seconds + "秒前";
}
}

View File

@ -15,7 +15,24 @@ export function getImageUrl(path) {
if (isDev) {
return `${local}/${path}`
}
return `/${path}`;
return `${path}`;
}
export function numFormat(num, digits){
let d = digits || 1;
var si = [
{ value: 1, symbol: "" },
{ value: 1E3, symbol: "k" },
{ value: 1E4, symbol: "W" }
];
var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
var i;
for (i = si.length - 1; i > 0; i--) {
if (num >= si[i].value) {
break;
}
}
return (num / si[i].value).toFixed(d).replace(rx, "$1") + si[i].symbol;
}
export function getImage(path) {
@ -162,28 +179,28 @@ export function getmyUrl(geturl) {
}
export function getUploadActionUrl(path, goTest) {
return `${getUrl()}/api/attachments.json?debug=${window._debugType || 'admin'}`;
return `${getUrl()}/api/attachments.json${isDev ?`${isDev ?`?debug=${window._debugType || 'admin'}` : ""}` : ""}`;
}
export function getUploadLogoActionUrl() {
return `${getUrl()}/api/resumes/logo.json?debug=${window._debugType || 'admin'}`;
return `${getUrl()}/api/resumes/logo.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`;
}
export function getUploadActionUrltwo(id) {
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json?debug=${window._debugType || 'admin'}`
return `${getUrlmys()}/api/shixuns/${id}/upload_data_sets.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
}
export function getUploadActionUrlthree() {
return `${getUrlmys()}/api/jupyters/import_with_tpm.json?debug=${window._debugType || 'admin'}`
return `${getUrlmys()}/api/jupyters/import_with_tpm.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
}
export function getupload_git_file(id) {
return `${getUrlmys()}/api/shixuns/${id}/upload_git_file.json?debug=${window._debugType || 'admin'}`
return `${getUrlmys()}/api/shixuns/${id}/upload_git_file.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
}
export function getUploadActionUrlOfAuth(id) {
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json?debug=${window._debugType || 'admin'}`
return `${getUrl()}/api/users/accounts/${id}/auth_attachment.json${isDev ?`?debug=${window._debugType || 'admin'}` : ""}`
}
export function getRandomNumber(type) {

View File

@ -64,7 +64,7 @@ function CommentItem({
const commentAvatar = (author) => (
<img
className="item-flex flex-image"
src={author.image_url ? getImageUrl(`images/${author.image_url}`) : 'https://b-ssl.duitang.com/uploads/item/201511/13/20151113110434_kyReJ.jpeg'}
src={author.image_url ? getImageUrl(`/${author.image_url}`) : 'https://b-ssl.duitang.com/uploads/item/201511/13/20151113110434_kyReJ.jpeg'}
alt=""
/>
);

View File

@ -3,7 +3,7 @@
// export { default as OrderStateUtil } from '../routes/Order/components/OrderStateUtil';
export {
getUploadLogoActionUrl as getUploadLogoActionUrl,
getUploadLogoActionUrl as getUploadLogoActionUrl,numFormat as numFormat,
getImageUrl as getImageUrl,getImage as getImage, getmyUrl as getmyUrl, getRandomNumber as getRandomNumber, getUrl as getUrl, publicSearchs as publicSearchs, getRandomcode as getRandomcode, getUrlmys as getUrlmys, getUrl2 as getUrl2, setImagesUrl as setImagesUrl
, getUploadActionUrl as getUploadActionUrl, getUploadActionUrltwo as getUploadActionUrltwo, getUploadActionUrlthree as getUploadActionUrlthree, getUploadActionUrlOfAuth as getUploadActionUrlOfAuth
, getTaskUrlById as getTaskUrlById, TEST_HOST, htmlEncode as htmlEncode, getupload_git_file as getupload_git_file, getcdnImageUrl as getcdnImageUrl
@ -27,7 +27,7 @@ export {
markdownToHTML, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, isImageExtension,
downloadFile, sortDirections, validateLength, mdJSONParse, exportMdtoHtml
} from './TextUtil'
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds } from './DateUtil'
export { handleDateString, getNextHalfHourOfMoment, formatDuring, formatSeconds ,timeAgo} from './DateUtil'
export { configShareForIndex, configShareForPaths, configShareForShixuns, configShareForCourses, configShareForCustom } from './util/ShareUtil'

View File

@ -46,18 +46,18 @@ export default ({
let id = decodeURIComponent(u.split("#")[1]);
let ele = document.getElementById(id);
if(ele){
window.scrollTo(0, ele.offsetTop + 220);
window.scrollTo(0, ele.offsetTop + 120);
}
}
}
},[url])
},[url,html])
const el = useRef();
function onAncherHandler(e) {
let target = e.target
let target = e.target;
if (target.tagName.toUpperCase() === 'A') {
let ancher = target.getAttribute('href')
if (ancher.startsWith('#')) {
let ancher = target.getAttribute('href');
if (ancher && ancher.startsWith('#')) {
e.preventDefault()
let viewEl = document.getElementById(ancher.replace('#', ''))
if (viewEl) {

View File

@ -69,7 +69,7 @@ function Index(props){
<div className="aboutPanels">
<div className="aboutContent">
<AlignCenterBetween style={{padding:"14px 20px"}}>
<span className="font-16"><i className="iconfont icon-xiangmujianjie mr5 font-16 color-blue"></i>项目简介</span>
<span className="font-16"><i className="iconfont icon-xiangmujianjie mr5 font-16 color-blue"></i>项目概览</span>
{ editOpration && !edit && <a onClick={editContent} className="color-blue">编辑</a> }
</AlignCenterBetween>
{
@ -117,7 +117,7 @@ function Index(props){
{content ?
<RenderHtml className="break_word_comments imageLayerParent" value={content} url={props.history.location}/>
:
<div>暂无简介~</div>
<div>暂无概览~</div>
}
{attachments && attachments.length > 0 &&
<Attachments

View File

@ -1,7 +1,7 @@
import React , { Component } from 'react';
import { Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
import '../css/index.scss';
import '../Branch/branch.css';
import '../Branch/branch.scss';
import './activity.css';
import NoneData from '../Nodata';

View File

@ -33,7 +33,7 @@ class ActivityItem extends Component {
}
<p className="itemLine mt10">
<Link to={`/users/${item && item.user_login}`} className="show-user-link">
<img alt="" src={getImageUrl(`images/${item.user_avatar}`)} className="createImage" />
<img alt="" src={getImageUrl(`/${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>}

View File

@ -1,39 +1,35 @@
import React, { Component } from 'react';
import { Dropdown, Icon, Tooltip } from 'antd';
import "./branch.css";
import React, { useState } from 'react';
import { Dropdown, Menu, Tooltip } from 'antd';
import "./branch.scss";
class CloneAddress extends Component {
function CloneAddress({http_url , ssh_url , zip_url , tar_url}) {
const [ key , setKey ] = useState("HTTP");
// 点击按钮复制功能
jsCopy = () => {
function jsCopy(){
var e = document.getElementById("copy_rep_content");
e.select();
document.execCommand("Copy");
}
render() {
const { http_url, downloadUrl } = this.props;
return (
<div className="downMenu">
<div style={{borderBottom:"1px solid #eee"}}>
<Menu className="urlMenu" selectedKeys={[key]} mode={"horizontal"}>
<Menu.Item key="HTTP" onClick={(e)=>{setKey(e.key)}}>HTTP</Menu.Item>
<Menu.Item key="SSH" onClick={(e)=>{setKey(e.key)}}>SSH</Menu.Item>
</Menu>
<div className="gitAddressClone">
{/* <p className="addressTips"><span>版本库地址已变更,请基于新地址提交代码</span></p> */}
{
http_url && <span>HTTP</span>
}
<input type="text" id="copy_rep_content" value={http_url} />
<input type="text" id="copy_rep_content" value={key==="HTTP" ? http_url:ssh_url} />
<Tooltip title="复制链接">
<span className="color-blue" onClick={() => this.jsCopy()}><i className="iconfont icon-fuzhi"></i></span>
<span className="color-blue" onClick={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 color-blue" />
</a>
</Dropdown>
</span>
}
</div>
</div>
<Menu className="edu-txt-center">
<Menu.Item><a href={zip_url}>下载 ZIP</a></Menu.Item>
<Menu.Item><a href={tar_url}>下载 TAR.GZ</a></Menu.Item>
</Menu>
</div>
)
}
}
export default CloneAddress;

View File

@ -1,116 +1,36 @@
import React , { useState , useEffect } from 'react';
import { Popover , Input , Spin } from 'antd';
import './branch.css';
import { Popover , Dropdown , Input , Spin } from 'antd';
import './branch.scss';
import { getBranch , getTag } from '../GetData/getData';
import SelectOverlay from './SelectOverlay';
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true })=>{
const [ showValue , setShowValue ] = useState(branch);
const [ inputValue , setInputValue] = useState(undefined);
const [ nav , setNav ] = useState(0);
const [ isSpin , setIsSpin ] = useState(true);
const [ flag , setFlag ] = useState(false);
const [ data , setData ] = useState(undefined);
const [ datas , setDatas ] = useState(undefined);
useEffect(()=>{
setShowValue(branch);
},[branch])
useEffect(()=>{
document.body.addEventListener('click', e => {
let name = e.target.className;
let turn = name === "ant-input OptionsInput" || name === "navli active"|| name === "navli" || name === "padding10 bor-bottom-greyE";
if(turn){
return;
}else{
setFlag(false);
}
})
})
useEffect(()=>{
if(branchList){
setData(branchList);
setDatas(branchList);
setIsSpin(false);
}
},[branchList])
async function getBranchs(id,owner){
let result = await getBranch(id,owner);
setData(result);
setDatas(result);
setIsSpin(false);
}
async function getTags(id,owner){
let result = await getTag(id,owner);
setData(result);
setDatas(result);
setIsSpin(false);
}
function changeInputValue(e){
setInputValue(e.target.value);
let filter = e.target.value ? data && data.length>0 && data.filter(item=>item.name.indexOf(e.target.value)>-1) : data;
setDatas(filter);
}
function changeNav(nav){
setNav(nav);
setIsSpin(true);
if(nav === 0){
getBranchs(projectsId,owner);
}else{
getTags(projectsId,owner);
}
}
function chooseitem(value){
// setShowValue(value);
changeBranch(value);
}
const menu = (
<div>
<div className="padding10 bor-bottom-greyE">
<Input
placeholder="请输入分支或标签名称搜索"
autocomplete="off" className="OptionsInput" value={inputValue}
onChange={changeInputValue} style={{width:"220px"}}
<SelectOverlay
changeBranch={changeBranch}
tagflag={tagflag}
projectsId={projectsId}
owner={owner}
branchList={branchList}
/>
<ul className="navUl">
<li className={nav === 0?"navli active":"navli"} onClick={()=>changeNav(0)}><i className="iconfont icon-fenzhi1 font-14 mr3"></i>分支列表</li>
{ tagflag && <li className={nav === 1?"navli active":"navli"} onClick={()=>changeNav(1)}><i className="iconfont icon-biaoqian3 font-14 mr3"></i>标签列表</li> }
</ul>
</div>
<Spin spinning={isSpin}>
<ul className="OptionsUl" id="ul-btn">
{
datas && datas.length>0 ?
datas.map((item,key)=>{
return(
<li key={key} onClick={()=>chooseitem(item.name)}><a className="task-hide ulALink">{item.name}</a></li>
)
}):
<p className="listTips">暂无{inputValue}{nav === 0 ?"分支":"标签"}~</p>
}
</ul>
</Spin>
</div>
);
return(
<Popover placement="bottom" visible={flag} content={menu} onClick={()=>setFlag(!flag)} overlayClassName="branch-tagBox-list">
<Dropdown placement='bottomLeft' overlay={menu} overlayClassName="branch-tagBox-list" trigger={['click']} >
<div className="branch-tagBox">
{/* {nav === 0 ?"分支":"标签"} */}
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
<a className="ant-dropdown-link">
<a className="ant-dropdown-link task-hide">
{showValue}
</a>
<i className="showtag iconfont icon-xiajiantou font-14 color-grey-9 mr8" />
<i className="showtag iconfont icon-sanjiaoxing-down font-15 color-grey-9 mr5 ml5 mt1" />
</div>
</Popover>
</Dropdown>
)
})

View File

@ -0,0 +1,84 @@
import React , { useState , useEffect } from 'react';
import { Input , Spin , Menu } from 'antd';
import { getBranch , getTag } from '../GetData/getData';
function SelectOverlay({ changeBranch , tagflag , branchList , projectsId , owner }) {
const [ inputValue , setInputValue] = useState(undefined);
const [ nav , setNav ] = useState(0);
const [ isSpin , setIsSpin ] = useState(true);
const [ data , setData ] = useState(undefined);
const [ datas , setDatas ] = useState(undefined);
const [ keys ,setKeys] = useState("branch");
useEffect(()=>{
if(branchList){
setData(branchList);
setDatas(branchList);
setIsSpin(false);
}
},[branchList])
async function getBranchs(id,owner){
let result = await getBranch(id,owner);
setData(result);
setDatas(result);
setIsSpin(false);
}
async function getTags(id,owner){
let result = await getTag(id,owner);
setData(result);
setDatas(result);
setIsSpin(false);
}
function chooseitem(value){
changeBranch(value);
}
function changeInputValue(e){
setInputValue(e.target.value);
let filter = e.target.value ? data && data.length>0 && data.filter(item=>item.name.indexOf(e.target.value)>-1) : data;
setDatas(filter);
}
function changeNav(e){
setKeys(e.key);
setIsSpin(true);
if(e.key === "branch"){
getBranchs(projectsId,owner);
}else{
getTags(projectsId,owner);
}
}
return(
<div className="overlayBranch">
<div className="padding15" style={{paddingBottom:"0px"}}>
<Input
prefix={<i className="iconfont icon-sousuo_icon1 font-14"></i>}
placeholder="请输入分支或标签名称搜索"
autocomplete="off" className="OptionsInput"
value={inputValue}
onChange={changeInputValue}
/>
</div>
<Menu mode="horizontal" className="navUl" selectedKeys={[keys]} onClick={changeNav}>
<Menu.Item key={"branch"}>分支</Menu.Item>
{ tagflag && <Menu.Item key={"tag"}>标签</Menu.Item> }
</Menu>
<Spin spinning={isSpin}>
<ul className="OptionsUl" id="ul-btn">
{
datas && datas.length>0 ?
datas.map((item,key)=>{
return(
<li key={key} onClick={()=>chooseitem(item.name)}><a className="task-hide ulALink">{item.name}</a></li>
)
}):
<p className="listTips">暂无{inputValue}{nav === 0 ?"分支":"标签"}~</p>
}
</ul>
</Spin>
</div>
)
}
export default SelectOverlay;

View File

@ -1,5 +1,5 @@
.branchDropdown{
border:1px solid #eee;
.branchDropdown {
border: 1px solid #eee;
border-radius: 4px;
display: flex;
justify-content: center;
@ -7,78 +7,126 @@
line-height: 40px;
min-width: 220px;
}
.branchDropdown .ant-dropdown-trigger{
.branchDropdown .ant-dropdown-trigger {
width: 100%;
padding:0px 15px;
padding: 0px 15px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
}
.branchOptions{
.branchOptions {
width: 220px;
box-shadow: 0px 0px 3px 1px rgba(134, 134, 134, 0.4);
border-radius: 3px;
background: #fff;
max-height: 300px;
}
.OptionsUl{
.OptionsUl {
max-height: 220px;
overflow-y: auto;
}
.OptionsUl li{
height: 35px;
line-height: 35px;
.OptionsUl li {
height: 30px;
line-height: 30px;
cursor: pointer;
padding:0px 10px;
padding: 0px 20px;
margin: 5px 0px;
}
.OptionsUl li:hover{
.OptionsUl li:hover {
background-color: #F0F0F0;
}
.OptionsUl li a{
.OptionsUl li a {
display: block;
}
.OptionsInput{
.OptionsInput {
height: 32px;
padding-left: 4px;
line-height: 32px;
width: 100%;
}
.branch-tagBox{
border:1px solid #eee;
.branch-tagBox {
border: 1px solid #D0D0D0;
border-radius: 3px;
height: 40px;
height: 36px;
display: flex;
align-items: center;
cursor: pointer;
min-width: 140px;
min-width: 104px;
}
.branch-tagBox-list .ant-popover-arrow{
.branch-tagBox:hover {
background-color: #F3F4F6;
}
.branch-tagBox-list {
background: #FFFFFF;
box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5);
border-radius: 4px;
}
.branch-tagBox-list .ant-popover-arrow {
display: none;
}
.branch-tagBox-list.ant-popover.ant-popover-placement-bottom{
padding-top:0px;
.branch-tagBox-list.ant-popover.ant-popover-placement-bottom {
padding-top: 0px;
}
.branch-tagBox .ant-dropdown-link{
.branch-tagBox-list .branch-tagBox .ant-dropdown-link {
display: block;
flex:1;
flex: 1;
max-width: 105px;
}
.branch-tagBox-list .ant-popover-inner-content{
padding:0px;
.branch-tagBox-list .ant-popover-inner-content {
padding: 0px;
}
.navUl{
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 5px;
.overlayBranch {
width: 325px;
}
.navUl li{
cursor: pointer;
.overlayBranch .navUl {
margin-top: 8px;
height: 30px;
line-height: 30px;
}
.navUl li.active{
color:#5091FF;
.overlayBranch .navUl li {
height: 30px;
line-height: 30px;
padding: 0px 5px;
margin-left: 20px !important;
}
.listTips{
padding:20px 0px;
.listTips {
padding: 20px 0px;
text-align: center;
}
.urlMenu {
line-height: 30px;
margin-bottom: 10px;
padding: 15px 20px 0px 20px;
border-bottom: none;
}
.urlMenu li.ant-menu-item {
height: 30px;
line-height: 30px;
padding: 0px 5px;
margin-right: 20px !important;
}
.urlMenu li.ant-menu-item.ant-menu-item-selected, .urlMenu li.ant-menu-item.ant-menu-item-active {
color: #333;
}
.urlMenu li.ant-menu-item.ant-menu-item-selected {
border-color: #1890ff !important;
}
.urlMenu li.ant-menu-item.ant-menu-item-active {
border-color: transparent;
}
/*# sourceMappingURL=branch.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["branch.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACG;;;AAEH;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;AACA;EACE;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;;AAGJ;EACE;;AACA;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;;AAIN;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;;AAEF;EACE","file":"branch.css"}

View File

@ -0,0 +1,118 @@
.branchDropdown{
border:1px solid #eee;
border-radius: 4px;
display: flex;
justify-content: center;
height: 40px;
line-height: 40px;
min-width: 220px;
}
.branchDropdown .ant-dropdown-trigger{
width: 100%;
padding:0px 15px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
}
.branchOptions{
width: 220px;
box-shadow: 0px 0px 3px 1px rgba(134, 134, 134, 0.4);
border-radius: 3px;
background: #fff;
max-height: 300px;
}
.OptionsUl{
max-height: 220px;
overflow-y: auto;
}
.OptionsUl li{
height: 30px;
line-height: 30px;
cursor: pointer;
padding:0px 20px;
margin:5px 0px;
}
.OptionsUl li:hover{
background-color: #F0F0F0;
}
.OptionsUl li a{
display: block;
}
.OptionsInput{
height: 32px;
padding-left: 4px;
line-height: 32px;
width: 100%;
}
.branch-tagBox{
border:1px solid #D0D0D0;
border-radius: 3px;
height: 36px;
display: flex;
align-items: center;
cursor: pointer;
min-width: 104px;
}
.branch-tagBox:hover{
background-color: #F3F4F6;
}
.branch-tagBox-list{
background: #FFFFFF;
box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5);
border-radius: 4px;
.ant-popover-arrow{
display: none;
}
&.ant-popover.ant-popover-placement-bottom{
padding-top:0px;
}
.branch-tagBox .ant-dropdown-link{
display: block;
flex:1;
max-width: 105px;
}
.ant-popover-inner-content{
padding:0px;
}
}
.overlayBranch{
width: 325px;
.navUl{
margin-top: 8px;
height: 30px;
line-height: 30px;
li{
height: 30px;
line-height: 30px;
padding:0px 5px;
margin-left: 20px!important;
}
}
}
.listTips{
padding:20px 0px;
text-align: center;
}
.urlMenu{
line-height: 30px;
margin-bottom: 10px;
padding:15px 20px 0px 20px;
border-bottom: none;
li.ant-menu-item{
height: 30px;
line-height: 30px;
padding:0px 5px;
margin-right: 20px!important;
&.ant-menu-item-selected,&.ant-menu-item-active{
color: #333;
}
&.ant-menu-item-selected{
border-color:#1890ff!important;
}
&.ant-menu-item-active{
border-color:transparent ;
}
}
}

View File

@ -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);
@ -42,10 +42,10 @@ function AddMember({getID,login}){
className="user_img radius"
width="28"
height="28"
src={getImageUrl(`images/${item && item.image_url}`)}
src={getImageUrl(`/${item && item.image_url}`)}
alt=""
/>
<span className="ml10" style={{ "vertical-align": "middle" }}>
<span className="ml10" style={{ verticalAlign: "middle" }}>
{item.username}
<span className="color-grey ml10">({item.login})</span>
</span>
@ -66,7 +66,12 @@ function AddMember({getID,login}){
};
function addCollaborator(){
if(source && source.length>0){
getID && getID(id);
setSearchKey(undefined);
}else{
showNotification("请选择存在的用户!");
}
}
return(

View File

@ -3,10 +3,10 @@ import { getImageUrl } from 'educoder';
import { Link } from 'react-router-dom';
import './Component.scss';
function Cards({img , title, desc , rightBtn , src}){
function Cards({img , title, desc , rightBtn , src , bottomInfos}){
return(
<div className="cards">
{img &&<div className="img"><img src={getImageUrl(`images/${img}`)} alt=""/></div>}
{img &&<div className="img"><img src={getImageUrl(`/${img}`)} alt=""/></div>}
<div className="content">
<p className="titles">
<Link to={src}>{title}</Link>
@ -15,6 +15,7 @@ function Cards({img , title, desc , rightBtn , src}){
<div className="desc">
{desc}
</div>
{bottomInfos}
</div>
</div>
)

View File

@ -0,0 +1,432 @@
@charset "UTF-8";
ul.ant-menu {
border-right: none;
}
ul.ant-menu li:last-child {
border-bottom: none;
}
li.ant-menu-item {
margin: 0px !important;
border-bottom: 1px solid #eee;
}
.flags {
border: 1px solid red;
border-radius: 5px;
}
.cards {
display: flex;
align-items: center;
padding: 20px 34px;
background-color: #fff;
margin-bottom: 18px;
min-height: 130px;
border: 1px solid #eee;
}
.cards .img {
margin-right: 20px;
width: 190px;
height: 90px;
border: 1px solid #eeeeee;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.cards .img img {
max-width: 100%;
max-height: 100%;
}
.cards .content {
flex: 1;
width: 0;
}
.cards .content .titles {
display: flex;
justify-content: space-between;
margin-bottom: 10px !important;
align-items: center;
height: 22px;
line-height: 22px;
}
.cards .content .titles > a {
font-size: 18px;
color: #333;
}
.cards .content .desc {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-height: 20px;
}
.tabsStyle {
border: 1px solid #eee;
}
.tabsStyle .ant-tabs-bar.ant-tabs-top-bar {
padding-left: 35px;
margin-bottom: 0px;
}
.tabsStyle .ant-tabs-nav .ant-tabs-tab {
padding: 19px 0px;
margin-right: 40px;
}
.tabsStyle .ant-tabs-ink-bar {
width: 25px !important;
bottom: 10px;
}
.statusColor {
display: inline-block;
padding: 0px 10px;
height: 20px;
line-height: 20px;
border-radius: 11px;
color: #fff;
margin-left: 5px;
font-size: 12px;
}
.statusColor.running {
background: #5091FF;
color: #F1F8FF;
}
.statusColor.Preparing {
background: #ff6e21;
color: #fff8f4;
}
.statusColor.pass {
background: #28BD6C;
color: #EEFDF5;
}
.statusColor.failed {
background: #F73030;
color: #FCEEEE;
}
.statusColor.killed {
background: #eee;
color: #999;
}
.handleBox {
position: fixed;
top: 45%;
right: 240px;
z-index: 10000;
}
.laterest {
background-color: #EF3131;
color: #fff;
font-size: 12px;
margin-left: 10px;
padding: 0px 5px;
border-radius: 2px;
height: 18px;
line-height: 18px;
}
@media screen and (max-width: 1800px) {
.handleBox {
right: 190px;
}
}
@media screen and (max-width: 1700px) {
.handleBox {
right: 140px;
}
}
@media screen and (max-width: 1600px) {
.handleBox {
right: 90px;
}
}
@media screen and (max-width: 1450px) {
.handleBox {
right: 10px;
}
}
@media screen and (max-width: 1380px) {
.handleBox {
right: 0px;
}
}
.ant-drawer {
z-index: 10000 !important;
}
.ant-drawer-body {
padding: 0px !important;
}
.ant-drawer-body .drawerHead {
background-color: #333;
color: #fff;
padding: 15px 20px;
}
.ant-drawer-body .ant-tree {
margin: 0px 20px !important;
}
.menuPanels {
width: 295px;
}
.menuPanels .leftline {
position: relative;
color: #666;
height: 16px;
}
.menuPanels .leftline::before {
position: absolute;
left: -10px;
top: 3px;
height: 12px;
width: 1px;
background-color: #666666;
content: "";
}
.menuPanels .ant-btn {
height: 36px;
line-height: 34px;
width: 83px;
text-align: center;
padding: 0px;
font-weight: 500;
font-size: 14px;
}
.menuPanels .ant-btn.currentBtn {
cursor: default;
color: #333;
}
.menuPanels .ant-btn.currentBtn:hover {
color: #333;
border-color: #d0d0d0;
}
.menuPanels .ant-btn-default {
color: #333;
border-color: #d0d0d0;
}
.menuPanels .ant-btn-default:hover {
background: #F3F4F6;
}
.menuPanels .ant-btn-primary {
color: #fff;
background-color: #2A61FF;
}
.menuPanels .focusPanelHeadInfo {
padding: 14px 16px;
border-bottom: 1px solid #eee;
}
.menuPanels .ant-popover-content, .menuPanels .ant-popover-inner {
height: 100%;
width: 100%;
}
.menuPanels .ant-popover-inner-content {
padding: 0px;
}
.halfs {
margin-top: 24px;
padding: 24px 0px 0px 0px;
border-top: 1px solid #e8e8e8;
}
.aboutSubTitle {
display: flex;
align-items: center;
}
.menuinfos {
padding: 10px 20px;
}
.menuinfos > a {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.menuinfos > a > span:first-child {
font-size: 16px;
font-weight: 500;
color: #333;
line-height: 22px;
}
.menuinfos > a > span:last-child {
color: #666;
font-weight: 400;
line-height: 20px;
margin-top: 6px;
}
/*-------------------个人主页:右侧提示区域--------------------------*/
.-task-sidebar {
position: fixed;
width: 40px;
right: 0;
bottom: 80px;
z-index: 10;
}
@media screen and (max-width: 1920px) {
.-task-sidebar {
right: 220px;
}
}
@media screen and (max-width: 1750px) {
.-task-sidebar {
right: 160px;
}
}
@media screen and (max-width: 1650px) {
.-task-sidebar {
right: 115px;
}
}
@media screen and (max-width: 1550px) {
.-task-sidebar {
right: 90px;
}
}
@media screen and (max-width: 1450px) {
.-task-sidebar {
right: 45px;
}
}
@media screen and (max-width: 1200px) {
.-task-sidebar {
right: 0px;
display: none;
}
}
.-task-sidebar > div {
height: 40px;
line-height: 40px;
box-sizing: border-box;
width: 40px;
color: #999;
font-size: 20px;
text-align: center;
margin-bottom: 20px;
border-radius: 50%;
background: #FFFFFF;
box-shadow: 0px 0px 10px 1px #F1F1F1;
}
.-task-sidebar > div i {
color: #999;
}
.-task-sidebar > div:hover i {
color: #fff !important;
}
.-task-sidebar > div:hover {
background: #1890FF;
box-shadow: 0px 0px 10px 2px #B6D0FC;
}
.helpBox {
width: 260px;
z-index: 103;
}
.helpBox.shareContent {
width: 200px;
}
.helpBox .ant-popover-inner-content {
padding: 0px;
}
.helpBox p.titlecontent {
font-size: 18px;
color: #333;
line-height: 20px;
padding: 15px 20px;
}
.helpBox .faqUl {
padding: 0px 20px 10px;
max-height: 230px;
overflow-y: auto;
}
.helpBox .faqUl li {
background: #F5F5F5;
border-radius: 20px;
padding: 0px 20px;
color: #333;
height: 34px;
line-height: 34px;
margin-bottom: 10px;
}
.helpBox .faqUl li a {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.helpBox .faqUl li:hover {
background-color: #D1E9FF;
}
.helpBox .faqUl li:hover a {
color: #333 !important;
}
.helpBox .shareUl {
padding: 10px 0px;
display: flex;
align-items: center;
}
.helpBox .shareUl .titlecontent {
margin-right: 20px;
}
.helpBox .shareUl li > i {
font-size: 32px !important;
}
.-task-desc {
background: #494949;
width: 90px;
line-height: 36px;
text-align: center;
position: absolute;
color: #fff;
font-size: 13px;
z-index: 999999;
opacity: 0;
}
.-task-desc div {
position: absolute;
top: 10px;
right: -7px;
height: 13px;
}
.-task-desc div img {
float: left;
}
.-task-sidebar .scan_ewm {
position: absolute !important;
right: 45px !important;
bottom: 0px !important;
background-color: #494949 !important;
-webkit-box-sizing: border-box !important;
box-sizing: border-box !important;
font-size: 14px !important;
line-height: 16px !important;
display: none;
height: 213px !important;
}
.trangle_right {
position: absolute;
right: -5px;
bottom: 15px;
width: 0;
height: 0px;
border-top: 6px solid transparent;
border-left: 5px solid #494949;
border-bottom: 6px solid transparent;
}
/*# sourceMappingURL=Component.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["Component.scss"],"names":[],"mappings":";AAAA;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AAGJ;EACE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAKN;EACE;;AACA;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;;AAGJ;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;;;AAEF;EACE;;AACA;EACE;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;;AACA;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;;AACA;EACE;EACA;;AAIN;EACE;EACA;;AACA;EACE;;AAGJ;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;;AAEF;EACE;;;AAGJ;EACE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;AACA;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;;AAKN;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;IACE;;;AAGJ;EACE;IACE;IACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;AACA;EACE;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AACA;EACE;;AAKR;EACE;EACA;EACA;;AACA;EACE;;AAEF;EACE;;;AAON;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"Component.css"}

View File

@ -112,6 +112,16 @@ li.ant-menu-item{
right:240px;
z-index: 10000;
}
.laterest{
background-color: #EF3131;
color: #fff;
font-size: 12px;
margin-left: 10px;
padding:0px 5px;
border-radius: 2px;
height: 18px;
line-height: 18px;
}
@media screen and (max-width: 1800px){
.handleBox{
@ -152,3 +162,258 @@ li.ant-menu-item{
margin:0px 20px!important;
}
}
.menuPanels{
width: 295px;
.leftline{
position: relative;
color: #666;
height: 16px;
&::before{
position: absolute;
left: -10px;
top:3px;
height: 12px;
width: 1px;
background-color: #666666;
content: "";
}
}
.ant-btn{
height: 36px;
line-height: 34px;
width: 83px;
text-align: center;
padding:0px ;
font-weight: 500;
font-size: 14px;
&.currentBtn{
cursor: default;
color: #333;
&:hover{
color: #333;
border-color: #d0d0d0;
}
}
}
.ant-btn-default{
color: #333;
border-color: #d0d0d0;
&:hover{
background: #F3F4F6;
}
}
.ant-btn-primary{
color: #fff;
background-color: #2A61FF;
}
.focusPanelHeadInfo{
padding:14px 16px;
border-bottom: 1px solid #eee;
}
.ant-popover-content,.ant-popover-inner{
height: 100%;
width: 100%;
}
.ant-popover-inner-content{
padding:0px;
}
}
.halfs{
margin-top: 24px;
padding:24px 0px 0px 0px;
border-top: 1px solid #e8e8e8;
}
.aboutSubTitle{
display: flex;
align-items: center;
}
.menuinfos{
padding:10px 20px;
&>a{
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
& >span:first-child{
font-size: 16px;
font-weight: 500;
color: #333;
line-height: 22px;
}
& >span:last-child{
color: #666;
font-weight: 400;
line-height: 20px;
margin-top: 6px;
}
}
}
/*-------------------个人主页:右侧提示区域--------------------------*/
.-task-sidebar {
position: fixed;
width: 40px;
right: 0;
bottom: 80px;
z-index: 10;
}
@media screen and (max-width: 1920px){
.-task-sidebar{
right:220px;
}
}
@media screen and (max-width: 1750px){
.-task-sidebar{
right:160px;
}
}
@media screen and (max-width: 1650px){
.-task-sidebar{
right:115px;
}
}
@media screen and (max-width: 1550px){
.-task-sidebar{
right:90px;
}
}
@media screen and (max-width: 1450px){
.-task-sidebar{
right:45px;
}
}
@media screen and (max-width: 1200px){
.-task-sidebar{
right:0px;
display: none;
}
}
.-task-sidebar>div {
height: 40px;
line-height: 40px;
box-sizing: border-box;
width: 40px;
color: #999;
font-size: 20px;
text-align: center;
margin-bottom: 20px;
border-radius: 50%;
background: #FFFFFF;
box-shadow: 0px 0px 10px 1px #F1F1F1;
}
.-task-sidebar>div i {
color: #999;
}
.-task-sidebar>div:hover i {
color: #fff !important;
}
.-task-sidebar>div:hover{
background: #1890FF;
box-shadow: 0px 0px 10px 2px #B6D0FC;
}
.helpBox{
width: 260px;
z-index: 103;
&.shareContent{
width: 200px;
}
.ant-popover-inner-content{
padding:0px;
}
p.titlecontent{
font-size: 18px;
color: #333;
line-height: 20px;
padding:15px 20px;
}
.faqUl{
padding:0px 20px 10px;
max-height: 230px;
overflow-y: auto;
li{
background: #F5F5F5;
border-radius: 20px;
padding:0px 20px;
color: #333;
height: 34px;
line-height: 34px;
margin-bottom: 10px;
a{
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
&:hover{
background-color: #D1E9FF;
a{
color: #333!important;
}
}
}
}
.shareUl{
padding:10px 0px;
display: flex;
align-items: center;
.titlecontent{
margin-right: 20px;
}
li > i{
font-size: 32px!important;
}
}
}
.-task-desc {
background: #494949;
width: 90px;
line-height: 36px;
text-align: center;
position: absolute;
color: #fff;
font-size: 13px;
z-index: 999999;
opacity: 0;
}
.-task-desc div {
position: absolute;
top: 10px;
right: -7px;
height: 13px;
}
.-task-desc div img {
float: left
}
.-task-sidebar .scan_ewm {
position: absolute !important;
right: 45px !important;
bottom: 0px !important;
background-color: #494949 !important;
-webkit-box-sizing: border-box !important;
box-sizing: border-box !important;
font-size: 14px !important;
line-height: 16px !important;
display: none;
height: 213px !important;
}
.trangle_right {
position: absolute;
right: -5px;
bottom: 15px;
width: 0;
height: 0px;
border-top: 6px solid transparent;
border-left: 5px solid #494949;
border-bottom: 6px solid transparent
}

View File

@ -1,21 +1,166 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { AlignCenter , FlexAJ } from '../Component/layout';
import { Link } from 'react-router-dom';
import { Popover , Spin , Button } from 'antd';
import { getImageUrl } from 'educoder';
import './Component.scss';
import { getUser } from '../GetData/getData';
import axios from 'axios';
function Contributors({contributors,owner,projectsId}){
return(
<div>
<FlexAJ>
<AlignCenter><span className="font-16 color-grey-6">贡献者</span>{ contributors && contributors.total_count > 0 && <span className="infoCount">{contributors.total_count}</span>}</AlignCenter>
<Link className="font-12 color-grey-9" to={`/projects/${owner}/${projectsId}/contribute`}>全部</Link>
</FlexAJ>
<div className="attrPerson">
function Contributors({contributors,owner,projectsId,currentLogin}){
const [ menuList ,setMenuList ]= useState([]);
const [ list , setList ]= useState(undefined);
const [ total , setTotal ]= useState(0);
const [ menu , setMenu ] = useState("");
const [ login , setLogin ] = useState(undefined);
const [ isSpin , setIsSpin ] = useState(false);
useEffect(()=>{
if(contributors && contributors.total_count>0){
setTotal(contributors.total_count);
setList(contributors.list);
}
},[contributors])
useEffect(()=>{
if(login){
getUsers(login);
}else{
setMenu(undefined);
}
},[login])
async function getUsers(login){
setIsSpin(true);
let a = menuList && menuList.filter(i=>i.login === login);
if(a.length === 0){
let result = await getUser(login);
let arr = menuList;
arr.push({...result});
setMenuList(arr);
setMenusFunc(result);
setIsSpin(false);
}else{
setMenusFunc(a[0]);
setIsSpin(false);
}
}
function setMenusFunc(data){
if(data){
let ele = (
<Spin spinning={isSpin}>
<AlignCenter className="focusPanelHeadInfo">
<Link to={`/users/${data.login}`}><img src={getImageUrl(`/${data.image_url}`)} alt="" className="radius" width="38px" height="38px"/></Link>
<div className="flex1 ml10" style={{width:"0"}}>
<AlignCenter>
<Link to={`/users/${data.login}`} className="font-16">{data.name}</Link>
{
contributors && contributors.total_count > 0 ?
contributors.list.map((item,key)=>{
data.location &&
<span className="ml20 font-12 leftline">{data.location}</span>
}
</AlignCenter>
{
data.organizations && data.organizations.length > 0 ?
<AlignCenter className="font-12 mt5">
<span>所属组织</span>
<div className="task-hide flex1">
{renderArray(data.organizations)}
</div>
</AlignCenter>
:""
}
</div>
</AlignCenter>
<AlignCenter className="menuinfos">
<a href={data.projects_url}>
<span>{data.projects_count}</span>
<span>项目数</span>
</a>
<a href={data.followers_url}>
<span>{data.followers_count}</span>
<span>粉丝数</span>
</a>
<a href={data.following_url}>
<span>{data.following_count}</span>
<span>关注数</span>
</a>
</AlignCenter>
<div className={"pb20"} style={{display:"flex",justifyContent:'center'}}>
{
currentLogin && (currentLogin === data.login)
?
<Button className="currentBtn">当前用户</Button>
:
data.is_watch ?
<Button type={"default"} onClick={()=>FocusFunc(false,data.login)}>已关注</Button>
:
<Button type={"primary"} onClick={()=>FocusFunc(true,data.login)}>关注TA</Button>
}
</div>
</Spin>
)
setMenu(ele);
}
}
function FocusFunc(flag,login){
axios({
method: flag ? 'post' : 'delete',
url: `/watchers/${flag ? 'follow' : 'unfollow'}.json`,
params: {target_type: "user",id:login}
}).then(result => {
if (result && (result.data.status === 0 || result.data.status === 2)) {
let a = menuList && menuList.filter(i=>i.login === login);
if(a){
a[0].is_watch = flag;
}
setMenusFunc(a[0]);
}
})
.catch(error => {
console.log(error);
});
}
function renderArray(array){
let str = "";
for(var i = 0;i<array.length;i++){
str += array[i].name +"、";
}
let substr = str.substr(0,str.length-1);
return (<span title={substr}>{substr}</span>)
}
function setVisibleFunc(flag,l,index){
if(l !== login){
setLogin(l);
}
var lx = list.concat();
lx.map(i=>i.visible =false);
if(flag){
lx[index].visible = flag;
}
lx.splice();
setList(lx);
}
return(
<Link key={key} to={`/users/${item.login}`}><img src={getImageUrl(`images/${item.image_url}`)} alt=""/></Link>
<div className="halfs">
<Link to={`/projects/${owner}/${projectsId}/contribute`} className="font-16 color-ooo aboutSubTitle">
<span>贡献者</span>
{ contributors && contributors.total_count > 0 && <span className="infoCount">{contributors.total_count}</span>}
</Link>
<div className="attrPerson" onMouseLeave={()=>setVisibleFunc(false)}>
{
total > 0 ?
list.map((item,key)=>{
return(
<Popover content={menu} visible={item.visible} overlayClassName="menuPanels" placement="top">
<Link key={key} to={`/users/${item.login}`}>
<img src={getImageUrl(`/${item.image_url}`)} alt="" onMouseOver={()=>setVisibleFunc(true,item.login,key)}/>
</Link>
</Popover>
)
})
:""

View File

@ -0,0 +1,35 @@
import React from 'react';
import { AlignCenter } from '../layout';
import { Modal , Button } from 'antd';
import './Index.scss';
function DeleteBox({
visible ,
onCancel ,
onSuccess ,
title ,
subTitle,
content
}) {
return(
<Modal
visible={visible}
onCancel={onCancel}
title={title}
width="600px"
className="deleteBox"
footer={
<div>
<Button size={'large'} onClick={onCancel}>取消</Button>
<Button type={"danger"} size={"large"} onClick={onSuccess}>确认删除</Button>
</div>
}
>
<div className="desc">
<AlignCenter className="descMain"><i className="iconfont icon-shanchu_tc_icon mr10"></i>{content}</AlignCenter>
<p>{subTitle}</p>
</div>
</Modal>
)
}
export default DeleteBox;

View File

@ -0,0 +1,45 @@
.deleteBox{
.ant-modal-header{
background-color: #f8f8f8;
border-bottom: none;
.ant-modal-title{
text-align: left;
font-size: 20px;
}
}
.ant-modal-body{
padding:30px 50px;
p{
font-size: 16px;
line-height: 26px;
color:#666;
word-break: break-all;
}
.desc{
.descMain{
align-items: center;
justify-content: center;
font-size: 20px;
margin-bottom: 10px;
i{
font-size: 38px!important;
color:#DF0002
}
}
}
}
.ant-modal-footer{
border-top: none;
text-align: center;
padding-bottom: 40px;
button{
width: 120px;
margin:0px 20px;
&.ant-btn-danger{
background-color: #fff;
color: #DF0002;
border-color: #D0D0D0;
}
}
}
}

View File

@ -4,6 +4,12 @@ import './Component.scss';
import axios from 'axios';
const { TreeNode , DirectoryTree } = Tree;
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
function DrawerPanel({visible,onClose,branch,owner,projectsId,history, name , list}){
const [ treeData , setTreeData ] = useState(undefined);
const [ isSpin , setIsSpin ] = useState(true);
@ -71,7 +77,8 @@ function DrawerPanel({visible,onClose,branch,owner,projectsId,history, name , li
let dataref = event.node.props.dataRef;
if(dataref.type==="file"){
onClose();
history.push(`/projects/${owner}/${projectsId}/tree/${branch}/${dataref.path}`);
let value = turnbar(branch);
history.push(`/projects/${owner}/${projectsId}/tree/${value}/${dataref.path}`);
}
}

View File

@ -0,0 +1,9 @@
.ant-modal-mask {
z-index: 1001;
}
.ant-modal-wrap {
z-index: 1002;
}
/*# sourceMappingURL=EAccount.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["EAccount.scss"],"names":[],"mappings":"AAAA;EACE;;;AAEF;EACE","file":"EAccount.css"}

View File

@ -0,0 +1,6 @@
.ant-modal-mask{
z-index: 1001;
}
.ant-modal-wrap{
z-index: 1002;
}

View File

@ -0,0 +1,60 @@
import React , {forwardRef, useEffect} from 'react';
import { Modal , Form , Input , Button } from 'antd';
import './EAccount.scss';
function EducoderAccount({form , visible , onOk , email}){
const { getFieldDecorator, validateFields , setFieldsValue } = form;
useEffect(()=>{
if(email){
setFieldsValue({email})
}
},[email])
function onSure(){
validateFields((error,values)=>{
if(!error){
onOk(values);
}
})
}
const layout = {
labelCol: { span: 5 },
wrapperCol: { span: 18 },
};
return(
<Modal
visible={visible}
title="提示"
width="500px"
closable={false}
footer={
<Button type="primary" onClick={onSure}>确定</Button>
}
centered
>
<div>
<p className="mb15 edu-txt-center" style={{maxWidth:"350px",margin:"0px auto"}}>
为确保您能正常使用平台功能请确认以下信息:
</p>
<Form {...layout}>
<Form.Item label="邮箱">
{getFieldDecorator("email",{
rules:[{required:true,message:"请输入邮箱账号"}]
})(
<Input placeholder="请输入您的邮箱账号" width="220px"/>
)}
</Form.Item>
<Form.Item label="密码">
{getFieldDecorator("password",{
rules:[{required:true,message:"请输入邮箱密码"}]
})(
<Input.Password placeholder="请输入您的邮箱密码" width="220px"/>
)}
</Form.Item>
</Form>
</div>
</Modal>
)
}
export default Form.create()(forwardRef(EducoderAccount));

View File

@ -0,0 +1,41 @@
import React, { useState } from "react";
import { Input ,notification} from "antd";
const { Search } = Input;
export default ({history}) => {
const [openSearch, setOpenSearch] = useState(false);
function onGlobalSearch(value) {
history.push('/search?value=' + value);
// window.location.href = `search?value=` + value;
// history.push({
// pathname:'/search',
// state:value
// })
}
return (
<React.Fragment>
{
openSearch ?
<div
onBlur={() => {
setTimeout(() => {
setOpenSearch(false)
}, 500)
}}
>
<Search placeholder="请输入搜索关键字"
className={`search-input mr20`}
onSearch={onGlobalSearch}
autoFocus={true}
style={{width:'260px'}}
/>
</div>
:
<i className="iconfont icon-sousuo font-18 color-grey-6 ml30" onClick={() => {
setOpenSearch(true)
}} />
}
</React.Fragment>
)
};

View File

@ -25,7 +25,7 @@ function LanguagePower({languages}){
}
return(
<div>
<p className="font-16 color-grey-6">开发语言</p>
<p className="font-16 color-ooo aboutSubTitle">开发语言</p>
<div className="progress">
{
array && array.map((item,key)=>{

View File

@ -45,7 +45,7 @@ const Div = styled.div`{
export default (({ user , img, name, time, focusStatus, is_current_user, login , successFunc }) => {
return (
<Div>
<Link to={`/users/${user && user.login}`}><Img src={getImageUrl(`images/${img}`)} /></Link>
<Link to={`/users/${user && user.login}`}><Img src={getImageUrl(`/${img}`)} /></Link>
<div className="m-infos">
<Link to={`/users/${user && user.login}`}><Name>{name}</Name></Link>
<Time><I className="iconfont icon-shijian"></I>加入时间:{time}</Time>

View File

@ -0,0 +1,62 @@
import React, {useEffect, useRef, useState} from 'react';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
import './Component.scss';
function Monaco(props) {
const {
style = { // dom
height: '400px',
},
value = '', //
onChange = () => { //
},
fontSize = 14, //
monacoOptions = {
scrollBeyondLastLine: false,
lineNumbers: "off",
wordWrap: true,
overviewRulerBorder: true,
lineHeight: 24,
readOnly:true
}, // monaco
language = 'html', // js ts sql css json html
} = props;
const editOrRef = useRef();
const ThisEditor = useRef();
useEffect(() => {
ThisEditor.current = monaco.editor.create(editOrRef.current, {
value: value || '',
language,
theme: "vs-grey",
fontSize: fontSize + 'px',
minimap: { //
enabled: false,
},
...monacoOptions,
});
ThisEditor.current.onDidChangeModelContent((e) => {
let newValue = ThisEditor.current.getValue();
onChange(newValue);
});
return () => {
ThisEditor.current.dispose();
ThisEditor.current = undefined; //
}
}, []);
useEffect(() => {
if (ThisEditor.current) {
ThisEditor.current.updateOptions({
fontSize: fontSize + 'px',
})
}
}, [fontSize]);
return (
<div style={style} ref={editOrRef}>
</div>
);
}
export default Monaco;

View File

@ -2,34 +2,33 @@ import React from 'react';
import { AlignCenter , AlignTop , FlexAJ } from '../Component/layout';
import { Link } from 'react-router-dom';
function Releases({owner,projectsId,releaseVersions}){
function Releases({owner,projectsId,releaseVersions , baseOperate , projectType}){
return(
<div>
<FlexAJ>
<AlignCenter><span className="font-16 color-grey-6">发行版</span>
<Link to={`/projects/${owner}/${projectsId}/releases`} className="font-16 color-ooo aboutSubTitle">
<span>发行版</span>
{ releaseVersions && releaseVersions.total_count > 0 && <span className="infoCount">{releaseVersions.total_count}</span>}
</AlignCenter>
{ releaseVersions && releaseVersions.total_count > 0 ?
<Link className="font-12 color-grey-9" to={`/projects/${owner}/${projectsId}/releases`}>全部</Link>
:
<Link className="font-12 color-blue" to={`/projects/${owner}/${projectsId}/releases/new`}>新建</Link>
}
</FlexAJ>
</Link>
{
releaseVersions && releaseVersions.total_count>0 ?
releaseVersions.list.map((item,key)=>{
return(
<AlignTop className="mt10">
<i className="iconfont icon-biaoqian3 color-grey-6 font-18 mr10"></i>
key === 0 &&<AlignTop className="mt10">
<div>
<p className="font-16 color-grey-6"><Link to={`/projects/${owner}/${projectsId}/releases/8/update`}>{item.name}</Link></p>
<p className="color-grey-9 font-13">{item.created_at}</p>
<p className="font-16">
<Link to={`/projects/${owner}/${projectsId}/releases`} className="color-grey-3">发布{item.name}版本</Link>
<span className="laterest">最新</span>
</p>
<p className="color-grey-3 font-12">{item.created_at}</p>
</div>
</AlignTop>
)
})
:""
:
<div className="mt8">
您暂未发布任何版本{baseOperate && projectType !==2 && <Link className="color-blue ml20" to={`/projects/${owner}/${projectsId}/releases/new`}>创建新版本</Link>}
</div>
}
</div>

View File

@ -1,24 +1,33 @@
import React , { useState } from 'react';
import React , { useState , useEffect } from 'react';
import { AutoComplete } from 'antd';
import { getImageUrl } from "educoder";
import axios from 'axios';
const Option = AutoComplete.Option;
export default ({ getUser })=>{
export default ({ getUser , placeholder, width ,value })=>{
const [ source , setSource ] = useState(undefined);
const [ searchKey , setSearchKey ] = useState(undefined);
const [ userDataSource , setUserDataSource ] = useState(undefined);
useEffect(()=>{
if(!value){
setSearchKey(undefined);
}
},[value])
useEffect(()=>{
getUserList();
},[searchKey])
function getUserList(e){
const url = `/users/list.json`;
axios.get(url, {
params: {
search: e,
search: searchKey,
},
})
.then((result) => {
}).then((result) => {
if (result) {
setUserDataSource(result.data.users);
sourceOptions(result.data.users);
}
})
.catch((error) => {
@ -26,25 +35,20 @@ export default ({ getUser })=>{
});
};
function changeInputUser(value){
setSearchKey(value);
getUserList(value);
}
function selectInputUser(id, option){
setSearchKey(option.props.value);
getUserList(option.props.value);
getUser && getUser(id);
}
const source =
userDataSource && userDataSource.map((item, key) => {
function sourceOptions(userDataSource){
const s = userDataSource && userDataSource.map((item, key) => {
return (
<Option key={key} value={`${item.login}`}>
<Option
key={key}
value={`${item.user_id}`}
login={`${item.login}`}
name={item.username}
>
<img
className="user_img radius"
width="28"
height="28"
src={getImageUrl(`images/${item && item.image_url}`)}
src={getImageUrl(`/${item && item.image_url}`)}
alt=""
/>
<span className="ml10" style={{ "vertical-align": "middle" }}>
@ -54,14 +58,31 @@ export default ({ getUser })=>{
</Option>
);
});
setSource(s);
}
function changeInputUser(e){
setSearchKey(e);
};
//
function selectInputUser(e, option){
setSearchKey(option.props.name);
getUser(option.props.login);
};
return(
<div className="addPanel">
<AutoComplete
getPopupContainer={trigger => trigger.parentNode}
dataSource={source}
value={searchKey}
style={{ width: 300 }}
style={{ width: width || 300 }}
onChange={changeInputUser}
onSelect={selectInputUser}
placeholder="搜索需要添加的用户..."
placeholder={placeholder || "搜索需要添加的用户..."}
allowClear
/>
</div>
)
}

View File

@ -0,0 +1,91 @@
import React, { useEffect, useState } from 'react';
import { Popover , Tooltip } from 'antd';
import './Component.scss';
import axios from 'axios';
import ShareModal from './SiderBarShareModal';
const $ = window.$;
$(window).scroll(function () {
if ($(".gotop").length > 0) {
if ($(document).scrollTop() > 0) {
$(".-task-sidebar .gotop").show();
$(".gotop").click(function () {
$("html,body").scrollTop(0);
});
}
if ($(document).scrollTop() === 0) {
$(".-task-sidebar .gotop").hide();
}
}
});
function SiderBar() {
const [ data , setData ] = useState([]);
const [ visible , setVisible ] = useState(false);
useEffect(()=>{
getFAQ();
},[])
function getFAQ(){
const url = `/faqs.json`;
axios.get(url).then(result=>{
if(result && result.data){
setData(result.data);
}
}).catch(error=>{})
}
function content(list){
return <div>
<p className="titlecontent">帮助</p>
<ul className="faqUl">
{
list && list.map((i,k)=>{
return(
<li key={i.question+k}><a href={`${i.url}`} title={i.question} target="_blank">{i.question}</a></li>
)
})
}
</ul>
</div>
}
function shareContent(){
return <div>
<ul className="shareUl">
<p className="titlecontent">分享到</p>
<li onClick={()=>setVisible(true)}><i className="iconfont icon-weixin2" style={{color:"#62b900"}}></i></li>
</ul>
</div>
}
return (
<div className={"-task-sidebar"} >
<ShareModal visible={visible} urlValue={window.location.href} onCancel={()=>setVisible(false)}/>
{
data && data.length > 0 && (data[0] && data[0].question) ?
<Popover content={content(data)} overlayClassName="helpBox" placement={"left"}>
<div className="feedback">
<i className="iconfont icon-bangzhu font-22"></i>
</div>
</Popover>
:""
}
{/* <div className="scan pr" title="">
<span className="inline erweima"><i className="iconfont icon-erweima color-white font-22 fl"></i></span>
</div>*/}
<Popover content={shareContent()} overlayClassName="helpBox shareContent" placement={"left"}>
<div className="consult">
<i className="iconfont icon-fenxiang1"></i>
</div>
</Popover>
<div className="gotop">
<Tooltip title="返回顶部" placement={"right"}>
<a><i className="iconfont icon-huidaodingbu1"></i></a>
</Tooltip>
</div>
</div>
)
}
export default SiderBar;

View File

@ -0,0 +1,27 @@
import React from 'react';
import { Modal } from 'antd';
import QRCode from 'qrcode.react';
function SiderBarShareModal({visible,urlValue,onCancel}) {
return(
<Modal
title={"分享到微信"}
visible={visible}
width="500px"
closable={true}
footer={false}
onCancel={onCancel}
>
<div style={{textAlign:"center"}}>
{urlValue &&<QRCode
value={urlValue}
size={200}
fgColor="#000000"
style={{margin:"20px"}}
/>}
<p>打开微信扫一扫,点击右上角菜单即可将网页分享至朋友圈</p>
</div>
</Modal>
)
}
export default SiderBarShareModal;

View File

@ -1,8 +1,8 @@
import React from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
export default ({ url , name , column })=>{
export default ({ url , name , column , id , login })=>{
const Img = styled.span`
display:flex;
${column && "flex-direction: column;text-align:center;"}
@ -19,6 +19,14 @@ export default ({ url , name , column })=>{
}
`;
return(
id?
<Link to={`/users/${login}`}>
<Img>
{ url && <img src={url} alt=""/> }
<span>{name}</span>
</Img>
</Link>
:
<Img>
{ url && <img src={url} alt=""/> }
<span>{name}</span>

View File

@ -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;

View File

@ -36,8 +36,7 @@ function About(props, ref) {
const [ disabled, setDisabled ] = useState(false);
const [ typeFlag, setTypeFlag] = useState(false);
const AuthorLogin = props.author && props.author.login;
const AuthorLogin = props.projectDetail && props.projectDetail.author && props.projectDetail.author.login;
const CurrentLogin = props.current_user && props.current_user.login;
useEffect(()=>{
if(CurrentLogin === AuthorLogin){
@ -56,11 +55,6 @@ function About(props, ref) {
setIsSpining(false);
if(result && result.data ){
setStep(result.data.step);
// setStep(0);
// setFieldsValue({...result.data.cloud_account});
// if(result.data.cloud_account){
// setDisabled(true);
// }
}
}).catch(error=>{
setIsSpining(false);

View File

@ -10,6 +10,12 @@ import { Link } from 'react-router-dom';
// killed:"",
// pending:""
// }
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
function renderTableStatus(status) {
switch (status) {
case "running":
@ -65,8 +71,9 @@ function List({ list, operate , projectsId , owner , showModal , deleteFunc }){
width:"15%",
ellipsis:true,
render:(value,item)=>{
let v = turnbar(item.branch);
return(
<Link to={`/projects/${owner}/${projectsId}/tree/${item.branch}/${value}`} className="color-blue">{value}</Link>
<Link to={`/projects/${owner}/${projectsId}/tree/${v}/${value}`} className="color-blue">{value}</Link>
)
}
},

View File

@ -42,7 +42,7 @@ function PipelineName({visible,onCancel,onOk,value ,branchList}){
</div>
<div className="choosenList mt20">
<span>触发条件:</span>
<Select value={branchValue} style={{width:"150px"}} onChange={(e)=>setBranchValue(e)}>
<Select value={branchValue} style={{width:"150px"}} dropdownClassName="chooseCon" onChange={(e)=>setBranchValue(e)}>
{
branchList && branchList.length>0 && branchList.map((item,key)=>{
return(
@ -51,7 +51,7 @@ function PipelineName({visible,onCancel,onOk,value ,branchList}){
})
}
</Select>
<Select mode="multiple" allowClear value={eventValue} style={{width:"180px",marginLeft:"10px"}} onChange={(e)=>{console.log(e);setEventValue(e)}}>
<Select mode="multiple" allowClear value={eventValue} dropdownClassName="chooseCon" style={{width:"180px",marginLeft:"10px"}} onChange={(e)=>{console.log(e);setEventValue(e)}}>
{
EVENT.map((item,key)=>{
return(

View File

@ -1,7 +1,8 @@
import React, { useState, useEffect } from "react";
import { Spin } from "antd";
import { Spin , Menu } from "antd";
import { FlexAJ, AlignCenter } from "../Component/layout";
import axios from "axios";
import CodeSSH from './ssh/Index';
export default ({
data,
@ -17,6 +18,8 @@ export default ({
const [spining, setSpining] = useState(true);
const [stage, setStage] = useState(undefined);
const [step, setStep] = useState(undefined);
const [nav, setNav] = useState("0");
useEffect(() => {
setSpining(rightSpin);
}, [rightSpin]);
@ -35,6 +38,7 @@ export default ({
: p[0];
setStep(sub);
setNav("0");
if (sub && sub.status !== "skipped") {
getStep(pre.number, sub.number);
}
@ -65,6 +69,13 @@ export default ({
}
}
return (
<React.Fragment>
{/* <Menu className="devopsNav" onClick={(e)=>{setNav(e.key)}} selectedKeys={[nav]} mode="horizontal">
<Menu.Item key={'0'} value="0">开发流水线</Menu.Item>
<Menu.Item key={'1'} value="1">命令行</Menu.Item>
</Menu> */}
{
nav === "0" &&
<Spin spinning={spining}>
<div className="rightMainContent">
{data && data.status !== "error" ? (
@ -103,5 +114,10 @@ export default ({
)}
</div>
</Spin>
}
{
nav === "1" && <CodeSSH />
}
</React.Fragment>
);
};

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect , useImperativeHandle ,forwardRef } from "re
import { FlexAJ, AlignCenter , Banner } from "../Component/layout";
import { Table, Pagination, Popconfirm } from "antd";
import { truncateCommitId } from "../common/util";
import {getUrl} from 'educoder';
import { getImageUrl } from 'educoder';
import axios from "axios";
import { Link } from 'react-router-dom';
@ -58,6 +58,7 @@ function Structure(props,ref){
return {
...item,
author:item.author && item.author.name,
image_url:item.author && item.author.image_url,
message: {
branch: item.branch_target,
message: item.message,
@ -244,7 +245,7 @@ function Structure(props,ref){
{meg.sha && <span className="color-orange">{meg.sha}</span>}
</div>
<AlignCenter>
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} src={`${current_user && getUrl(`/images/${current_user.image_url}`)}`} />
<img style={{borderRadius:"50%",marginRight:"10px",width:"25px",height:"25px"}} alt="" src={`${item.image_url && getImageUrl(`/${item.image_url}`)}`} />
<div className="task-hide ml5" style={{ maxWidth: "300px" }}>
{meg.message}
</div>

View File

@ -194,6 +194,18 @@
&.rightSection{
width:100%;
background-color: #081930;
.devopsNav{
background-color: #111c24;
border-bottom: none;
.ant-menu-item{
color: #ccc;
padding:0px;
margin:0px 20px!important;
}
.ant-menu-item.ant-menu-item-selected{
color: #1890ff;
}
}
.rightMainContent{
padding:24px 30px;
height:100vh;
@ -379,6 +391,9 @@
}
}
}
.chooseCon.ant-select-dropdown{
z-index: 100001;
}
.choosenList{
display: flex;

View File

@ -0,0 +1,42 @@
import React, { useState, useEffect } from "react";
import XmlPanel from "./XmlPanel";
import mediator from "./mediator";
import axios from "axios";
// const defaulturl = `http://47.111.130.18:48088`;
const defaultValue = {
host: "106.75.231.63",
port: "2021",
ws_url: "wss://pre-webssh.educoder.net/ws",
username: "root",
secret: "Dron_123123",
};
function Index() {
const [sshConfigData, setSshConfigData] = useState(undefined);
useEffect(() => {
if (!sshConfigData) {
init();
}
setTimeout(() => {
mediator.publish("create-socket", 1);
}, 300);
}, [sshConfigData]);
//
function init() {
const url = `/api/ci/pipelines/ssh_server.json`;
axios.get(url).then(result=>{
if(result && result.data){
setSshConfigData({...result.data})
}
}).catch(error=>{})
}
return (
<XmlPanel
sshConfigData={sshConfigData||{}}
sid={1}
/>
);
}
export default Index;

View File

@ -0,0 +1,219 @@
import React, { useRef, useEffect, useState } from 'react';
import { Base64 } from 'js-base64';
import { Terminal } from 'xterm';
import 'xterm/css/xterm.css';
import mediator from './mediator';
import ResizeObserver from 'resize-observer-polyfill';
function getColsAndRows(width, height, term) {
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
let h = term._core._renderService.dimensions.actualCellHeight || 18;
const rows = Math.floor(height / h);
const cols = Math.floor(width / w);
return [cols, rows];
}
function onLayout(term, el) {
const ro = new ResizeObserver(entries => {
console.log(entries);
for (let entry of entries) {
if (entry.target.offsetHeight > 0 || entry.target.offsetWidth > 0) {
const [cols, rows] = getColsAndRows(
entry.target.offsetWidth,
entry.target.offsetHeight,
term,
);
console.log('cols, rows', cols, rows);
term.resize(cols, rows);
mediator.publish('ssh-xterm-resize', {
columns: cols,
rows: rows,
width: entry.target.offsetWidth,
height: entry.target.offsetHeight,
});
}
}
});
ro.observe(el);
return ro;
}
const TimeTicket = 30000;
// websockt
//
//socket term socket
//mediator id
export default ({ sshConfigData, sid }) => {
const [term, setTerm] = useState(null);
const { ws_url, password, port, secret } = sshConfigData;
const el = useRef();
const socket = useRef();
const isFirstConnected = useRef(false);
//term init
useEffect(() => {
if (el.current && ws_url) {
const term = new Terminal({ fontSize: 16, rendererType: 'dom' });
term.open(el.current);
term.onData(data => {
if (socket.current) {
if (socket.current.readyState === 1) {
socket.current.send(JSON.stringify({ tp: 'client', data: data }));
mediator.publish('on-operating-ssh'); //
} else {
//
// socket.current = null
// mediator.publish('create-socket', sid)
}
}
});
term.write('Connecting...');
setTerm(term);
const ro = onLayout(term, el.current);
return () => {
term.dispose();
ro.unobserve(el.current);
};
}
}, [ws_url, el.current]);
useEffect(() => {
if (term && ws_url) {
function createSocket() {
const socketInstance = new WebSocket(ws_url);
socket.current = socketInstance;
socketInstance.onopen = () => {
let container = term.element.parentElement;
if (container) {
let width = container.offsetWidth;
let height = container.offsetHeight;
console.log('init', {
tp: 'init',
data: {
...sshConfigData,
secret: secret,
width,
height,
rows: term.rows,
columns: term.cols,
},
});
socketInstance.send(
JSON.stringify({
tp: 'init',
data: {
...sshConfigData,
secret: secret,
width,
height,
rows: term.rows,
columns: term.cols,
},
}),
);
}
term.focus();
};
socketInstance.onerror = error => {
console.log(
'------in socket error----',
error,
socketInstance,
ws_url,
);
//
// mediator.publish('on-recreate-socket')
};
socketInstance.onmessage = event => {
if (!isFirstConnected.current) {
term.write('\r');
// term.focus()
setTimeout(() => {
// term.clear();
}, 1000);
}
isFirstConnected.current = true;
console.log('event:', event);
const data = Base64.decode(event.data.toString());
let w = term._core._renderService.dimensions.actualCellWidth || 9.5;
console.log('data:', data, w, term);
term.write(data);
};
socketInstance.onclose = evt => {
if (tid) {
clearInterval(tid);
}
term.write('\r\nconnection closed');
};
}
const tid = setInterval(() => {
if (socket.current) {
socket.current.send(JSON.stringify({ tp: 'h' }));
}
}, TimeTicket);
const unSubCreate = mediator.subscribe('create-socket', id => {
if (sid === id) {
if (socket.current && socket.current.readyState === 1) {
term.focus();
} else {
createSocket();
}
term.focus();
}
});
const unSubClose = mediator.subscribe('close-socket', id => {
if (sid === id) {
if (socket.current) {
socket.current.close();
isFirstConnected.current = false;
term.clear();
}
socket.current = null;
}
});
const unSubResize = mediator.subscribe('ssh-xterm-resize', option => {
if (socket.current && socket.current.readyState === 1) {
socket.current.send(
JSON.stringify({ tp: 'resize', data: { ...option } }),
);
}
});
const unSubAddTime = mediator.subscribe('ssh-add-connect-time', () => {
if (socket.current && socket.current.readyState === 1) {
socket.current.send(JSON.stringify({ tp: 'overtime' }));
}
});
return () => {
unSubClose();
unSubCreate();
unSubResize();
unSubAddTime();
if (socket.current) {
socket.current.close();
isFirstConnected.current = false;
}
};
}
}, [term, ws_url, port]);
return (
<div ref={el} className="xterm-panel" style={{height:"100%"}}>
{!ws_url ? <p style={{ color: '#fff' }}>正在连接命令行服务...</p> : null}
</div>
);
};

View File

@ -0,0 +1,46 @@
function Mediator(obj) {
const channels = {};
const mediator = {
subscribe: function(channel, cb) {
if (!channels[channel]) {
channels[channel] = [];
}
channels[channel].push(cb);
return this.unsubscribe.bind(null, channel, cb);
},
unsubscribe: function(channel, cb) {
let rs = channels[channel];
let index = -1;
if (rs) {
for (let i = 0; i < rs.length; i++) {
if (rs[i].name === cb.name) {
index = i;
break;
}
}
if (index >= 0) {
channels[channel].splice(index, 1);
return true;
}
}
return false;
},
publish: function(channel) {
if (!channels[channel]) {
return false;
}
const args = Array.prototype.slice.call(arguments, 1);
channels[channel].forEach(subscription => {
subscription.apply(null, args);
});
return this;
},
};
return obj ? Object.assign(obj, mediator) : mediator;
}
const mediator = new Mediator();
export default mediator;

View File

@ -0,0 +1,175 @@
import React ,{ forwardRef, useEffect, useState } from 'react';
import { Modal , Form , Input , Radio , Select } from 'antd';
import SearchUser from '../Component/SearchUser';
import './Index.scss';
import Axios from 'axios';
const { Option } = Select;
function DivertModal({form , visible , onSuccess , onCancel,owner,repo}){
const { getFieldDecorator, validateFields , setFieldsValue } = form;
const [ cate , setCate ] = useState(0);
const [ value , setValue ] = useState(undefined);
const [ organizations , setOrganizations ] = useState(undefined);
useEffect(()=>{
setFieldsValue({goal:cate})
},[])
useEffect(()=>{
if(owner && repo && visible===true){
getTeam();
}
if(!visible){
setFieldsValue({
owner_name:undefined,
identifier:undefined
})
setValue(undefined)
}
},[repo,owner,visible])
function getTeam(){
const url = `/${owner}/${repo}/applied_transfer_projects/organizations.json`;
Axios.get(url).then(result=>{
if(result){
setOrganizations(result.data.organizations);
}
}).catch(error=>{})
}
//
function onOk(){
validateFields((error,values)=>{
console.log(...values);
if(!error){
const url = `/${owner}/${repo}/applied_transfer_projects.json`;
Axios.post(url,{
...values
}).then(result=>{
if(result){
onSuccess(result.data && result.data.owner);
}
}).catch(error=>{})
}
})
}
function changeType(e){
setCate(e.target.value);
setFieldsValue({
owner_name:undefined
})
}
function checkIdentifier(rule, value, callback){
if(!value){
callback();
}
if (repo && value !== repo) {
callback("请输入当前项目的标识!");
}
callback();
}
const layout = {
labelCol: { span: 5 },
wrapperCol: { span: 18 },
};
function getUser(id){
setValue(id);
setFieldsValue({
owner_name:id
})
}
return(
<Modal
width="620px"
visible={visible}
title="转移仓库"
onCancel={onCancel}
onOk={onOk}
okText="确认转移"
cancelText={"取消"}
centered
>
<div className="diverModal">
{
cate === 0 ?
<ul className="descUl">
<li>转移需对方确认接受转移成功后你将被移出仓库其他已有成员权限不变</li>
<li>转移成功后仓库的地址将变更至目标用户的命名空间下</li>
<li>已有成员如需继续操作仓库需更新本地仓库的remote使之指向新的地址</li>
</ul>
:
<ul className="descUl">
<li>仓库仅可以转移到您已经加入的组织中不可以转移到未加入的组织中</li>
<li>涉及到仓库改名操作请提前做好仓库备份并且在转移后对本地仓库的remote进行修改</li>
<li>转移仓库到组织后你和组织创建者/管理员同时拥有对该仓库的管理操作</li>
</ul>
}
<Form {...layout} colon={false} layout={"horizontal"}>
<Form.Item label="转移给:" style={{marginBottom:"0px"}}>
{getFieldDecorator("goal",{
rules:[]
})(
<Radio.Group onChange={changeType}>
<Radio value={0}>个人</Radio>
<Radio value={1}>组织</Radio>
</Radio.Group>
)}
</Form.Item>
{
cate === 0 &&
<Form.Item label=" ">
{getFieldDecorator("owner_name",{
rules:[{required:true,message:"请输入目标用户名"}]
})(
// <Input placeholder="" autoComplete={"off"}/>
<SearchUser getUser={getUser} width={"100%"} placeholder="请输入目标用户" value={value}/>
)}
</Form.Item>
}
{
cate === 1 &&
<Form.Item label=" ">
{getFieldDecorator("owner_name",
{rules:[{required:true,message:"请选择目标组织"}]}
)(
<Select placeholder="请选择目标组织" getPopupContainer={trigger => trigger.parentNode}>
{
organizations && organizations.length > 0 ?
organizations.map((i,k)=>{
return(
<Option value={i.name}>{i.nickname}</Option>
)
})
:""
}
</Select>
)}
</Form.Item>
}
<Form.Item label="仓库标识:" style={{marginBottom:"0px"}}>
{getFieldDecorator("identifier",
{
rules:[
{required:true,message:"请输入仓库标识!"},
{
validator:checkIdentifier
}
]
}
)(
<Input placeholder="请输入仓库标识" autoComplete={"off"}/>
)}
</Form.Item>
<span className="color-grey-9" style={{marginLeft:"120px"}}>请输入当前项目的标识<span className="ml5 mr5 color-grey-3">{repo}</span>进行确认</span>
</Form>
</div>
</Modal>
)
}
export default Form.create()(forwardRef(DivertModal));

View File

@ -0,0 +1,12 @@
.diverModal{
.descUl{
background-color: #fffae6;
border-radius: 4px;
padding:10px 15px;
color: #efc16b;
border:1px solid #efc16b;
}
.ant-form-item-required::before{
content: "";
}
}

View File

@ -15,3 +15,7 @@ export const getHooks = async (id,params)=>{
export const getSubEntries = async (owner,projectsId,params)=>{
return (await axios.get(`/${owner}/${projectsId}/sub_entries.json`,{params})).data;
}
//
export const getUser = async (login)=>{
return (await axios.get(`/users/${login}/hovercard.json`)).data;
}

View File

@ -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(
<React.Fragment>
<Modal
title="加入项目"
width="480px"
visible={visible}
centered={true}
onOk={onOk}
onCancel={()=>setVisible(false)}
>
<Form layout={'inline'} className="inviteForm">
<Form.Item label="项目邀请码">
{getFieldDecorator("code",{
rules:[
{required:true,message:"请输入6位项目邀请码"},
{validator:checkValue}
]
})(
<Input placeholder="请输入6位项目邀请码" autoComplete={"off"} maxLength="6" style={{width:"300px"}}/>
)}
</Form.Item>
<Form.Item label="选择角色">
{getFieldDecorator("role",{
rules:[{required:true,message:"请选择角色"}]
})(
<Radio.Group defaultValue={"developer"}>
<Radio value="manager">管理员</Radio>
<Radio value="developer">开发者</Radio>
<Radio value="reporter">报告者</Radio>
</Radio.Group>
)}
</Form.Item>
</Form>
</Modal>
<a onClick={()=>setVisible(true)}>加入项目</a>
</React.Fragment>
)
})
)

66
src/forge/Head/Footer.jsx Normal file
View File

@ -0,0 +1,66 @@
import React, { useEffect , useState } from 'react';
import './header.scss';
function Footer(){
const [ value , setValue ] = useState(undefined);
useEffect(()=>{
try {
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
setValue(chromesettingArray.footer);
} catch (e) {
}
},[])
function showhtml(htmlString){
var html = {__html:htmlString};
return <div dangerouslySetInnerHTML={html}></div> ;
}
return(
<div>
<div style={{height:"497px"}}></div>
<div className="newFooter edu-txt-center">
{value && showhtml(value)}
{/* <div className="footerInfos">
<ul>
<li>社区</li>
<li><a href={`/`} target="_blank">网站首页</a></li>
<li><a href={`https://www.trustie.net/agreement`} target="_blank">服务协议</a></li>
<li><a href={`https://forum.trustie.net/forums/1168/detail`} target="_blank">帮助中心</a></li>
<li><a href={`https://forum.trustie.net/`} target="_blank">问吧交流</a></li>
<li><a href={`https://www.trustie.net/cooperation`} target="_blank">合作伙伴</a></li>
</ul>
<ul>
<li>支持与服务</li>
<li><a href={`https://forgeplus.trustie.net/docs/api`} target="_blank">API文档</a></li>
<li><a href={`https://forum.trustie.net/forums/1168/detail`} target="_blank">帮助中心</a></li>
<li><a href={`https://git-scm.com`} target="_blank">Git常用命令</a></li>
<li><a href={`https://forum.trustie.net/forums/3080/detail`} target="_blank">DevOps使用文档</a></li>
<li><a href={`https://forgeplus.trustie.net/projects/jasder/forgeplus/tree/master/CHANGELOG.md`} target="_blank">日志更新</a></li>
</ul>
<ul>
<li>合作伙伴</li>
<li><a href={`http://www.sei.pku.edu.cn`} target="_blank">北京大学</a></li>
<li><a href={`http://scse.buaa.edu.cn`} target="_blank">北京航空航天大学</a></li>
<li><a href={`https://www.nju.edu.cn`} target="_blank">南京大学</a></li>
<li><a href={`https://www.xtu.edu.cn`} target="_blank">湘潭大学</a></li>
<li><a href={`http://www.iscas.ac.cn`} target="_blank">ISCAS</a></li>
<li><a href={`https://www.ucloud.cn`} target="_blank">UCloud优刻得</a></li>
<li><a href={`http://www.inforbus.com`} target="_blank">中创软件</a></li>
<li><a href={`https://www.inspur.com`} target="_blank">浪潮集团</a></li>
<li><a href={`http://www.copu.org.cn`} target="_blank">中国开源软件推进联盟</a></li>
<li><a href={`https://www.sjtu.edu.cn`} target="_blank">上海交通大学</a></li>
</ul>
<ul>
<li>合作伙伴</li>
<li><span>热线</span></li>
<li><span>QQ群1071514693</span></li>
</ul>
</div>
<p className="footerCopy">© Copyright 2007~2021 国防科技大学Trustie团队 & IntelliDE <a href="https://beian.miit.gov.cn">湘ICP备 17009477</a></p> */}
</div>
</div>
)
}
export default Footer;

View File

@ -2,16 +2,15 @@ import React, { Component } from 'react';
import AccountProfile from "../../modules/user/AccountProfile";
import { getImageUrl } from 'educoder'
import axios from 'axios';
import { Modal, Input, message, notification , Dropdown , Menu ,Divider } from 'antd';
import { Input , notification , Dropdown , Menu } from 'antd';
import { Link } from 'react-router-dom';
import LoginDialog from '../../modules/login/LoginDialog';
import GotoQQgroup from '../../modal/GotoQQgroup'
// import 'antd/lib/modal/style/index.css';
// import 'antd/lib/checkbox/style/index.css';
// import 'antd/lib/radio/style/index.css';
// import 'antd/lib/input/style/index.css';
import HeadSearch from '../Component/HeadSearch';
import AddProjectModal from './AddProjectModal';
import '../../modules/tpm/TPMIndex.css';
import logo from '../../modules/tpm/images/logo.png';
import './header.scss';
const $ = window.$
// TODO 这部分脚本从公共脚本中直接调用
@ -35,11 +34,9 @@ class NewHeader extends Component {
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
RadioGroupvalue: undefined,
submitapplications: false,
isRender: false,
showSearchOpentype: false,
showTrial: false,
setevaluatinghides: false,
occupation: 0,
@ -47,13 +44,11 @@ class NewHeader extends Component {
headtypesonClickbool: false,
headtypess: "/",
settings: null,
goshowqqgtounp: false,
visiblemyss: false,
openSearch:false,
}
}
componentDidMount() {
// this.getAppdata();
this.geturlsdata();
window._header_componentHandler = this;
@ -84,36 +79,6 @@ class NewHeader extends Component {
} catch (e) {}
}
SearchInput = (open,item)=>{
if(open){
return(
<div
onBlur={() => {
setTimeout(() => {
this.setState({
openSearch:false
})
}, 300)
}}
>
<Search placeholder="实践课程/教学课堂/实践项目/交流问答"
className={`search-input mr20`}
onSearch={(value)=>this.onGlobalSearch(value,item)}
autoFocus={true}
/>
</div>
)
}else{
return <i className="iconfont icon-sousuo font-18 color-grey-6 ml30" onClick={() => {
this.setState({openSearch:true})
}} />
}
}
onGlobalSearch=(value,item)=>{
window.location.href=`${item && item.url}?value=` + value;
}
openNotification = (messge) => {
notification.open({
message: "提示",
@ -122,8 +87,6 @@ class NewHeader extends Component {
});
};
componentWillReceiveProps(newProps, oldProps) {
this.setState({
user: newProps.user
@ -132,158 +95,7 @@ class NewHeader extends Component {
old_url = newProps.Headertop.old_url
}
}
getCookie = (key) => {
var arr, reg = RegExp('(^| )' + key + '=([^;]+)(;|$)');
if (arr === document.cookie.match(reg))
return decodeURIComponent(arr[2]);
else
return null;
}
delCookie = (name) => {
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval = this.getCookie(name);
if (cval != null) {
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
}
}
onLogout = () => {
const url = `/accounts/logout.json`
this.delCookie("autologin_trustie")
axios.get(url, {
}).then((response) => {
if (response.data.status === 1) {
this.setState({
user: undefined
})
window.location.href = "/login"
message.success('退出成功');
}
});
}
tojoinclass = () => {
let { user } = this.state;
if (user === undefined) {
this.setState({
isRender: true
})
return
}
if (user && user.login === "") {
this.setState({
isRender: true
})
return;
}
if (user && user.profile_completed === false) {
this.setState({
AccountProfiletype: true
})
return;
}
this.setState({
Addcoursestypes: true,
})
}
tojoinitem = () => {
if (this.props.user && this.props.user.email === undefined || this.props.user && this.props.user.email === null || this.props.user && this.props.user.email === "") {
this.openNotification("请先绑定邮箱,谢谢");
return
}
let { user } = this.state;
if (user === undefined) {
this.setState({
isRender: true
})
return
}
if (user && user.login === "") {
this.setState({
isRender: true
})
return;
}
if (user && user.profile_completed === false) {
this.setState({
AccountProfiletype: true
})
return;
}
this.setState({
tojoinitemtype: true
})
}
submitstatevalue = (sum, value, data) => {
this.setState({
Addcoursestypes: false,
tojoinitemtype: false,
tojoinclasstitle: undefined,
rolearr: ["", ""],
Checkboxteacherchecked: false,
Checkboxstudentchecked: false,
Checkboxteachingchecked: false,
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
submitapplicationssum: sum,
submitapplications: true,
submitapplicationsvalue: value,
submitapplicationsvaluedata: data,
RadioGroupvalue: undefined
})
}
onChangeRadioGroup = (e) => {
this.setState({
RadioGroupvalue: e.target.value,
});
}
submitsubmitapplications = () => {
let {
submitapplicationssum,
submitapplicationsvaluedata
} = this.state;
this.setState({
submitapplications: false,
RadioGroupvalue: undefined
})
if (submitapplicationssum === 0) {
if (submitapplicationsvaluedata !== undefined) {
window.location.href = "/courses/" + submitapplicationsvaluedata;
}
} else if (submitapplicationssum === 1) {
if (submitapplicationsvaluedata !== undefined) {
window.location.href = "/projects/" + submitapplicationsvaluedata;
}
}
}
hidesubmitapplications = () => {
this.setState({
Addcoursestypes: false,
tojoinitemtype: false,
tojoinclasstitle: undefined,
rolearr: ["", ""],
Checkboxteacherchecked: false,
Checkboxstudentchecked: false,
Checkboxteachingchecked: false,
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
submitapplications: false,
RadioGroupvalue: undefined
})
}
educoderlogin = () => {
//登录账号
this.setState({
@ -321,30 +133,11 @@ class NewHeader extends Component {
})
};
hidetojoinclass = () => {
this.setState({
tojoinclasstype: false,
tojoinitemtype: false,
tojoinclasstitle: undefined,
rolearr: ["", ""],
Checkboxteacherchecked: false,
Checkboxstudentchecked: false,
Checkboxteachingchecked: false,
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
RadioGroupvalue: undefined
})
}
// 关闭
cancelModulationModels = () => {
this.setState({ isRenders: false })
}
setevaluatinghides = () => {
this.setState({
setevaluatinghides: true
@ -404,39 +197,13 @@ class NewHeader extends Component {
})
}
getAppdata = () => {
try {
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
this.setState({
settings: chromesettingArray
});
if (chromesettingArray.tab_logo_url) {
this.gettablogourldata(chromesettingresponseArray);
} else {
this.gettablogourlnull();
}
} catch (e) {
this.geturlsdata();
}
};
geturlsdata = () => {
let url = "/setting.json";
axios.get(url).then((response) => {
if (response && response.data) {
this.setState({ settings: 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();
}
localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
localStorage.setItem('chromesettingresponse', JSON.stringify(response));
} else {
this.gettablogourlnull();
}
@ -456,14 +223,6 @@ class NewHeader extends Component {
}
}
// 处理弹框
setgoshowqqgtounp = (bool) => {
this.setState({
goshowqqgtounp: bool
})
}
addMenu=(list)=>{
return(
list && list.length >0 &&
@ -472,34 +231,45 @@ class NewHeader extends Component {
{
list.map((item,key)=>{
return(
(item.name !=="加入课堂" && item.name !=="加入开发项目") && <Menu.Item><a href={item.url}>{item.name}</a></Menu.Item>
(item.name !=="加入课堂" && item.name !=="加入开发项目") && <Menu.Item key={item.name+key}><a href={item.url}>{item.name}</a></Menu.Item>
)
})
}
<Menu.Item><AddProjectModal showNotification={this.props.showNotification}/></Menu.Item>
</Menu>
</div>
)
}
renderMenu=(personal)=>{
const { current_user } = this.props;
return(
<Menu className="currentMenu">
<Menu.Item>
<span title={current_user && current_user.username}>{current_user && current_user.username}</span>
</Menu.Item>
{
personal && personal.length > 0 && personal.map((item,key)=>{
return(
<li key={key}><a href={item.url} target="_blank">{item.name}</a></li>
)
})
}
<li><Link to={`/settings/SSH`}>设置</Link></li>
<Menu.Item><a onClick={() => this.educoderloginysl()}>退出</a></Menu.Item>
</Menu>
)
}
render() {
const { match} = this.props;
let current_user = this.props.user;
let { Addcoursestypes,
tojoinitemtype,
tojoinclasstitle,
code_notice,
checked_notice,
let {
AccountProfiletype,
submitapplications,
submitapplicationsvalue,
user,
isRender,
showSearchOpentype,
headtypesonClickbool,
headtypess,
settings,
goshowqqgtounp,
openSearch,
} = this.state;
/*用户名称 用户头像url*/
let activeIndex = false;
@ -557,7 +327,7 @@ class NewHeader extends Component {
let shixun = "/shixuns";
let paths = "/paths";
let courses = "/courses";
this.props.mygetHelmetapi.navbar.map((item, key) => {
this.props.mygetHelmetapi && this.props.mygetHelmetapi.navbar && this.props.mygetHelmetapi.navbar.map((item, key) => {
var reg = RegExp(item.link);
if (shixun.match(reg)) {
if (item.hidden === true) {
@ -577,8 +347,8 @@ class NewHeader extends Component {
})
}
let search_url = settings && settings.common && settings.common.length> 0 && settings.common.filter(item=>item.name==="搜索");
let notice_url = settings && settings.common && settings.common.length> 0 && settings.common.filter(item=>item.name==="通知");
// let search_url = settings && settings.common && settings.common.search;
let notice_url = settings && settings.common && settings.common.notice;
return (
<div className="newHeaders" id="nHeader">
<div className="headerContent">
@ -595,19 +365,14 @@ class NewHeader extends Component {
{...this.props}
{...this.state}
/> : ""}
{
goshowqqgtounp === true ?
<GotoQQgroup {...this.state} {...this.props} setgoshowqqgtounp={(bool) => this.setgoshowqqgtounp(bool)}></GotoQQgroup>
:""
}
<a href={settings && settings.new_course.default_url} className={"fl mr30"} style={{minWidth:"45px"}}>
{
settings && settings.nav_logo_url ?
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(settings.nav_logo_url)}></img>
:
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={logo}></img>
}
<a href={settings && settings.new_course.default_url} className={"fl mr50"} style={{minWidth:"45px"}}>
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
</a>
:
""
}
<div className="head-nav pr" id={"head-navpre1"}>
{
settings && settings.navbar && settings.navbar.length > 0 ?
@ -646,7 +411,8 @@ class NewHeader extends Component {
}
</div>
<div className="head-right">
{search_url && search_url.length>0 ? this.SearchInput(openSearch,search_url[0]):""}
{/* {search_url ? this.SearchInput(openSearch,search_url):""} */}
<HeadSearch {...this.props}/>
{
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
@ -654,10 +420,10 @@ class NewHeader extends Component {
</Dropdown>:""
}
{this.props.user && this.props.user.login && (notice_url && notice_url.length>0) ?
{this.props.user && this.props.user.login && notice_url ?
<div className="ml30 edu-menu-panel">
{user && user.login &&
<a href={`${notice_url[0].url}`} style={{ position: 'relative' }}>
<a href={`${notice_url}`} style={{ position: 'relative' }}>
<i className="iconfont icon-xiaoxilingdang color-grey-6"></i>
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
</span>
@ -665,62 +431,21 @@ class NewHeader extends Component {
}
</div>:""
}
<Modal
keyboard={false}
title="提示"
visible={submitapplications}
closable={false}
footer={null}
>
<div className="task_popup_con ml30">
<div className="mr15">
<ul>
<div className="task-popup-content">
<p className="task-popup-text-center font-16">
{submitapplicationsvalue}
</p>
</div>
<li className="clearfix mt10 edu-txt-center">
<a className="task-btn mr10"
onClick={this.hidesubmitapplications}>取消</a>
<a
className="task-btn task-btn-orange ml20"
onClick={this.submitsubmitapplications}>确定</a>
</li>
</ul>
</div>
</div>
</Modal>
</div>
{!user || (user && !user.login) ?
<span className="font-15 ml30">
<a onClick={() => this.educoderlogin()} className="mr5 color-grey-6">登录</a>
{
settings && settings.new_course && settings.new_course.register_url &&
<span><em className="vertical-line"></em><a className="ml5 color-grey-6" href={`${settings.new_course.register_url}`} target="_blank"></a></span>
settings && settings.common && settings.common.register &&
<span><em className="vertical-line"></em><a className="ml5 color-grey-6" href={`${settings.common.register}`} target="_blank"></a></span>
}
</span>
:
<div className="ml30 edu-menu-panel" style={{ height: "70px", lineHeight: "70px" }}>
<a href={`/users/${this.props.current_user === undefined ? "" : this.props.current_user.login}/courses`}>
<img alt="头像" className="radius" height="34" id="nh_user_logo" name="avatar_image"
src={getImageUrl(`images/` + user.image_url)} width="34">
</img>
<Dropdown placement={`bottomRight`} overlay={this.renderMenu(settings && settings.personal)}>
<a href={`/users/${this.props.current_user && this.props.current_user.login}`}>
<img alt="头像" src={getImageUrl(`/${user.image_url}`)} className="currentImg"></img>
</a>
<ul className="edu-menu-list" style={{ top: '60px', textAlign: 'center' }}>
<li className="bor-bottom-greyE" style={{cursor:"default",background:"#fff"}}>{this.props.current_user.username}</li>
{
settings && settings.personal && settings.personal.length > 0 && settings.personal.map((item,key)=>{
return(
<li key={key}><a href={item.url} target="_blank">{item.name}</a></li>
)
})
}
<li className="bor-top-greyE">
<a onClick={() => this.educoderloginysl()}>退出</a>
</li>
</ul>
</div>
</Dropdown>
}
</div>
</div>

View File

@ -1,10 +1,122 @@
.dropdownFlex{
display:flex;
padding:5px;
background:#fff;
border-radius: 3px;
.ant-menu-vertical > .ant-menu-item{
border:none
border:none;
height: 35px;
line-height: 35px;
margin:0px;
&.ant-menu-item-selected{
background-color: #fff;
a{color: rgba(0, 0, 0, 0.65)!important;}
}
&.ant-menu-item-active{
a{color: #4cacff!important;}
}
}
.ant-menu-vertical{
border:none;
}
}
.currentImg{
width: 34px;
height: 34px;
border-radius: 50%;
margin-left: 30px;
}
.currentMenu{
width: 120px;
text-align: center;
padding:0px;
li{
height: 40px;
line-height: 40px;
padding:0px!important;
cursor: default;
&:hover{
background-color: #fff;
}
&:first-child{
border-bottom: 1px solid #eee;
}
&:last-child{
border-top: 1px solid #eee;
a{
border-radius: 0px 0px 4px 4px;
}
}
a{
padding:0px;
margin:0px;
display: block;
color: #666;
&:hover{
color: #fff;
background: #4CACFF;
}
}
}
}
.newFooter {
position: absolute;
bottom: 0;
width: 100%;
background: #323232;
clear: both;
min-width: 1200px;
z-index: 8;
left: 0px;
p {
margin-top: 0;
margin-bottom:0px !important;
}
.footerInfos{
display: flex;
max-width: 1200px;
margin:0px auto;
justify-content: space-around;
padding:60px 0px;
& >ul{
padding:0px 40px;
box-sizing: border-box;
max-width: 25%;
text-align: left;
li{
color: #fff;
font-weight: 300;
&:first-child{
font-size: 17px;
}
&>a,&>span{
color: #bbb;
}
&>a:hover{
color: #4cacff;
}
}
}
}
.footerCopy{
color: #bbb;
border-top: 1px solid #4e4e4e;
padding:10px 0px;
a{
color: #bbb;
&:hover{
color: #4cacff;
}
}
}
}
.inviteForm{
.ant-form-item{
margin-right: 0px;
}
.ant-form-item-label{
width: 110px;
text-align: right;
}
}

View File

@ -6,7 +6,6 @@ import { withRouter } from "react-router";
import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC";
import Handbook from './Component/Handbook';
import "./css/index.scss";
import Loadable from "react-loadable";
@ -27,15 +26,18 @@ const ProjectDetail = Loadable({
loading: Loading,
});
const Infos = Loadable({
loader: () => import("./users/Infos"),
loading: Loading,
});
class Index extends Component {
componentDidUpdate=()=>{
this.props.history.listen(()=>{
if (document.body.scrollTop || document.documentElement.scrollTop > 0) {
window.scrollTo(0, 0)
}
})
}
render() {
return (
<div className="newMain clearfix">
<Handbook />
<Switch {...this.props}>
<Route
path="/projects/:projectsType/new/:OIdentifier"
@ -68,12 +70,8 @@ class Index extends Component {
)}
></Route>
<Route
exact
path="/"
render={(props) => (
this.props.current_user && this.props.current_user.login ?
<Infos {...this.props} {...props} />
:
<ProjectIndex {...this.props} {...props} />
)}
></Route>

View File

@ -1,6 +1,6 @@
import React , { useEffect , useState } from 'react';
import { WhiteBack , Box , LongWidth , ShortWidth , Gap , AlignCenter , FlexAJ } from '../Component/layout';
import { Dropdown , Menu , Divider , Spin } from 'antd';
import { Dropdown , Menu , Divider , Spin, Button , Typography } from 'antd';
import { getImageUrl } from "educoder";
import { Link } from 'react-router-dom';
import CloneAddress from '../Branch/CloneAddress';
@ -19,10 +19,27 @@ import LanguagePower from '../Component/LanguagePower';
import DrawerPanel from '../Component/DrawerPanel';
import UpdateDescModal from './sub/UpdateDescModal';
import Nodata from '../Nodata';
import Invite from './sub/Invite';
/**
* projectDetail.type:0是托管项目1是镜像项目2是同步镜像项目(为2时不支持在线创建在线上传在线修改在线删除创建合并请求等功能)
*/
const { Paragraph } = Typography;
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
function returnbar(str){
if(str && str.length>0 && str.indexOf("%2F")>-1){
return str.replaceAll('%2F','/');
}
return str;
}
function CoderDepot(props){
const [ projectDetail , setProjectDetail ]= useState(undefined);
const [ inviteCode , setInviteCode ] = useState(undefined);
const [ treeValue , setTreeValue ] = useState(undefined);
const [ treeValuePath , setTreeValuePath ] = useState(undefined);
const [ lastCommit,setLastCommit ] = useState(undefined);
@ -42,19 +59,46 @@ function CoderDepot(props){
const [ openModal , setOpenModal ] = useState(false);
const [ desc , setDesc ] = useState(undefined);
const [ website , setWebsite ] = useState(undefined);
const [ lesson_url , setLessonUrl ] = useState(undefined);
const [ readme , setReadme ] = useState(undefined);
const [ defaultBranch , setDefaultBranch ] = useState(undefined);
const [ editReadme , setEditReadme ] = useState(false);
const [ pullsFlag , setPullsFlag ] = useState(true);
const [ issuesFlag , setIssuesFlag ] = useState(true);
const owner = props.match.params.owner;
const projectsId = props.match.params.projectsId;
const branchName = props.match.params.branchName;
let branchName = props.match.params.branchName;
branchName = returnbar(branchName);
const details = props.projectDetail;
let pathname = props.history.location.pathname;
const { bannerList } = props;
useEffect(()=>{
if(props.projectDetail){
setProjectDetail(props.projectDetail);
setDesc(props.projectDetail.description);
setWebsite(props.projectDetail.website);
if(bannerList && bannerList.length>0){
let a = bannerList.filter(i=>i.menu_name === "pulls");
let i = bannerList.filter(i=>i.menu_name === "issues");
if(a && a.length === 0){
setPullsFlag(false);
}
},[props])
if(i && i.length === 0){
setIssuesFlag(false);
}
}
},[bannerList])
useEffect(()=>{
if(details){
setProjectDetail(details);
setDesc(details.description);
setWebsite(details.website);
setLessonUrl(details.lesson_url);
setDefaultBranch(details.default_branch);
setInviteCode(details.invite_code);
}
},[details])
useEffect(()=>{
if(treeValue){
@ -64,23 +108,28 @@ function CoderDepot(props){
}
},[treeValue])
useEffect(()=>{
if (pathname){
if(pathname.indexOf(`/projects/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${branchName}/`) > -1) {
let url = pathname.split(`/tree/${branchName}/`)[1];
if (projectsId && owner && defaultBranch){
let b = turnbar(branchName) ;
if(pathname.indexOf(`/projects/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${b}/`) > -1) {
let url = pathname.split(`/tree/${b}/`)[1];
setTreeValue(url);
getFileInfo(url,branchName);
setType("file");
}else{
setTreeValue(undefined);
getDirInfo(branchName ||(projectDetail && projectDetail.default_branch));
getDirInfo(branchName || defaultBranch);
setType("dir");
}
}
},[pathname])
},[projectsId,owner,pathname,defaultBranch])
//
function getDirInfo(branch){
setIsSpin(true);
const url = `/${owner}/${projectsId}/entries.json`;
axios.get(url, {
params: { ref: branch }
}).then((result) => {
@ -92,8 +141,12 @@ function CoderDepot(props){
setZip_url(result.data.zip_url);
let c = result.data.last_commit
setLastCommit(c && c.commit);
setLastCommitAuthor(c && (c.author || (c.commit && c.commit.author)));
setLastCommitAuthor(c && c.committer);
setMainFlag(true);
setReadOnly(true);
setReadme(result.data.readme);
setEditReadme(false);
setHide(true);
}
setTimeout(function(){setIsSpin(false);},500);
}).catch(error=>{setIsSpin(false);})
@ -105,7 +158,7 @@ function CoderDepot(props){
let ele = document.getElementById("ptxt");
if(ele){
let h = ele.offsetHeight;
if( h > 18 ) setHideBtn(true)
if( h > 18 ) setHideBtn(true);
}
}
},[projectDetail,lastCommit])
@ -133,8 +186,10 @@ function CoderDepot(props){
}
let c = result.data.last_commit
setLastCommit(c && c.commit);
setLastCommitAuthor(c && (c.author || (c.commit && c.commit.author)));
setLastCommitAuthor(c && c.committer);
setMainFlag(false);
setReadOnly(!editReadme);
setHide(true);
}
setTimeout(function(){setIsSpin(false);},500)
}).catch(error=>{setIsSpin(false);})
@ -142,17 +197,22 @@ function CoderDepot(props){
//
function changeBranch(value){
let url = `/projects/${owner}/${projectsId}${value && `/tree/${value}`}${treeValue ? `/${treeValue}`:""}`;
let checkvalue = turnbar(value);
let url = `/projects/${owner}/${projectsId}${value && `/tree/${checkvalue}`}${treeValue ? `/${treeValue}`:""}`;
props.history.push(url);
}
//
const fileMenu =(
function fileMenu(){
let b = branchName || defaultBranch;
let checkvalue = turnbar(b);
return (
<Menu>
<Menu.Item><a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/${branchName || (projectDetail && projectDetail.default_branch)}/uploadfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>上传文件</a></Menu.Item>
<Menu.Item><a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/${branchName || (projectDetail && projectDetail.default_branch)}/newfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>新建文件</a></Menu.Item>
<Menu.Item><a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/${checkvalue}/uploadfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>上传文件</a></Menu.Item>
<Menu.Item><a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/${checkvalue}/newfile${treeValue === undefined ? "" : `/${treeValue}`}`)}>新建文件</a></Menu.Item>
</Menu>
)
}
function getPathUrl(array,index){
if(array && array.length>0 && index){
@ -166,27 +226,36 @@ function CoderDepot(props){
//
function returnMain(){
setTreeValue(undefined);
let branch = branchName || (projectDetail && projectDetail.default_branch);
props.history.push(`/projects/${owner}/${projectsId}/tree/${branch}`);
let branch = branchName || defaultBranch;
let checkvalue = turnbar(branch);
props.history.push(`/projects/${owner}/${projectsId}/tree/${checkvalue}`);
};
//
function returnUlr(url){
props.history.push(`/projects/${owner}/${projectsId}/tree${branchName?`/${branchName}`:""}/${url}`);
let enBranch = turnbar(branchName);
props.history.push(`/projects/${owner}/${projectsId}/tree${enBranch?`/${enBranch}`:""}/${url}`);
}
//
function goToSubRoot(path,type,filename){
if(type!=="submodule"){
let enBranch = branchName || defaultBranch;
let checkvalue = turnbar(enBranch);
setType(type);
props.history.push(`/projects/${owner}/${projectsId}${`/tree/${branchName || (projectDetail && projectDetail.default_branch)}`}${path?`/${path}`:""}`);
props.history.push(`/projects/${owner}/${projectsId}${`/tree/${checkvalue}`}${path?`/${path}`:""}`);
}
}
function onEdit(readOnly){
setReadOnly(readOnly);
setEditReadme(false);
}
function ChangeFile(path, readOnly){
//
props.history.push(`/projects/${owner}/${projectsId}/tree/${branchName || (projectDetail && projectDetail.default_branch)}/${path}`);
let enBranch = branchName || defaultBranch;
let checkvalue = turnbar(enBranch);
props.history.push(`/projects/${owner}/${projectsId}/tree/${checkvalue}/${path}`);
setType("file");
setReadOnly(readOnly);
setEditReadme(true);
};
function changeHide(hide){
@ -202,32 +271,35 @@ function CoderDepot(props){
}
const downloadMenu = (
<div className="downMenu">
<div style={{padding:"20px",borderBottom:"1px solid #eee"}}>
<CloneAddress
http_url={projectDetail && projectDetail.clone_url}
ssh_url = {projectDetail && projectDetail.ssh_url}
zip_url={zip_url}
tar_url={tar_url}
showNotification={props.showNotification}/>
</div>
<Menu className="edu-txt-center">
<Menu.Item><a href={zip_url}>下载 ZIP</a></Menu.Item>
<Menu.Item><a href={tar_url}>下载 TAR.GZ</a></Menu.Item>
</Menu>
</div>
)
function okUpdate(d,w){
// website
function okUpdate(d,w,l){
const url = `/${owner}/${projectsId}.json`;
axios.put(url,{
description:d,website:w
description:d,website:w,lesson_url:l
}).then(result=>{
if(result && result.data && result.data.id){
setDesc(result.data.description);
setWebsite(result.data.website);
setLessonUrl(result.data.lesson_url);
}
})
}
let n = fileInfo && fileInfo.name;
const mdFlag = n && n.substring(n.length-3,n.length) === ".md";
const { current_user } = props;
const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter";
const fileOperate = type === "dir" && projectDetail && projectDetail.type !== 2 && ((projectDetail.permission && projectDetail.permission !=="Reporter") || (current_user && current_user.admin));
return(
<WhiteBack>
<UpdateDescModal desc={desc} website={website} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
<UpdateDescModal desc={desc} website={website} lesson_url={lesson_url} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
<Spin spinning={isSpin}>
{
(dirInfo || fileInfo) &&
@ -237,12 +309,15 @@ function CoderDepot(props){
owner={owner}
projectsId={projectsId}
name={projectDetail && projectDetail.name}
branch={branchName || (projectDetail && projectDetail.default_branch)}
branch={branchName || defaultBranch}
visible={visible}
onClose={()=>setVisible(false)}
list = {mainFlag ? dirInfo : undefined}
/>
<div className="drawerBtn" onClick={()=>setVisible(true)}><i className="iconfont icon-youjiantou"></i></div>
<div className="drawerBtn" onClick={()=>setVisible(true)}>
<i className="iconfont icon-zuohuaicon font-14"></i>
<span>目录</span>
</div>
</React.Fragment>
}
<div style={{minHeight:"500px"}}>
@ -253,42 +328,55 @@ function CoderDepot(props){
<div className="panelmenu">
<FlexAJ>
<AlignCenter>
<div className="mr20">
<div className="mr30">
{
props && props.platform ?
<SelectBranch
repo_id={projectDetail && projectDetail.repo_id}
projectsId={projectsId}
branch={branchName || (projectDetail && projectDetail.default_branch)}
branch={branchName || defaultBranch}
changeBranch={changeBranch}
owner={owner}
history={props.history}
branchList={projectDetail && projectDetail.branches && projectDetail.branches.list}
></SelectBranch>
:
<span>分支<span className="color-grey-6">{branchName || (projectDetail && projectDetail.default_branch)}</span></span>
<span>分支<span className="color-grey-6">{branchName || defaultBranch}</span></span>
}
</div>
<AlignCenter className="mr20">
<Link to={`/projects/${owner}/${projectsId}/branchs`} className="color-grey-9">
<i className="iconfont icon-fenzhi2 font-18 color-grey-9 mr3"></i>
<span className="color-grey-6 mr3">{projectDetail && projectDetail.branches && projectDetail.branches.total_count}</span>分支
<Link to={`/projects/${owner}/${projectsId}/branchs`} className="depotNum">
<i className="iconfont icon-master_icon font-14 mr3"></i>
<span className="mr3">分支</span>
<span>{projectDetail && projectDetail.branches && projectDetail.branches.total_count}</span>
</Link>
</AlignCenter>
<AlignCenter className="mr20">
<Link to={`/projects/${owner}/${projectsId}/tag`} className="color-grey-9">
<i className="iconfont icon-biaoqian3 font-16 color-grey-9 mr3"></i>
<span className="color-grey-6 mr3">{projectDetail && projectDetail.tags && projectDetail.tags.total_count}</span>标签
<Link to={`/projects/${owner}/${projectsId}/tag`} className="depotNum">
<i className="iconfont icon-biaoqianicon font-14 mr3"></i>
<span className="mr3">标签</span>
<span>{projectDetail && projectDetail.tags && projectDetail.tags.total_count}</span>
</Link>
</AlignCenter>
</AlignCenter>
<AlignCenter>
<div className="mr20 addOptionBtn">
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/pulls/new`)} >+ 合并请求</a>
<a onClick={()=>urlLink(`/projects/${owner}/${projectsId}/issues/new`)} >+ 任务</a>
</div>
{ type === "dir" && <Dropdown.Button overlay={fileMenu} className="mr20">文件</Dropdown.Button>}
<Dropdown.Button overlay={downloadMenu} type={'primary'}>下载</Dropdown.Button>
<AlignCenter className="depotBtn">
{
baseOperate && projectDetail.type !== 2 && pullsFlag &&
<Button type="default" onClick={()=>urlLink(`/projects/${owner}/${projectsId}/pulls/new`)} className="mr10"><i className="iconfont icon-xinjian2 font-12 mr3"></i> 合并请求</Button>
}
{
baseOperate && issuesFlag &&
<Button type="default" onClick={()=>urlLink(`/projects/${owner}/${projectsId}/issues/new`)} className="mr10"><i className="iconfont icon-xinjian2 font-12 mr3"></i> 任务</Button>
}
{ fileOperate &&
<Dropdown overlay={fileMenu()} className="mr10" trigger={['click']}>
<Button type="default">文件 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-grey-6 mr-5"></i></Button>
</Dropdown>
}
<Dropdown overlay={downloadMenu} placement="bottomRight" trigger={['click']}>
<Button type={'primary'}>下载 <i className="iconfont icon-sanjiaoxing-down ml3 font-14 color-white mr-3"></i></Button>
</Dropdown>
</AlignCenter>
</FlexAJ>
{
@ -297,12 +385,19 @@ function CoderDepot(props){
{
lastCommit &&
<div className="listtablehead">
<User url={getImageUrl(`images/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} />
<div className={hideBtn && hide ? "ellipsistxt hide" :"ellipsistxt"}><p id="ptxt">{lastCommit && lastCommit.message}</p></div>
<User url={getImageUrl(`/${lastCommitAuthor && lastCommitAuthor.image_url}`)} name={lastCommitAuthor && lastCommitAuthor.name} id={lastCommitAuthor && lastCommitAuthor.id} login={lastCommitAuthor && lastCommitAuthor.login}/>
<div className={hideBtn && hide ? "ellipsistxt hidetxt" :"ellipsistxt"}>
<pre id="ptxt">{lastCommit && lastCommit.message}</pre>
</div>
{ hideBtn && <span className="ellipsis" onClick={()=>changeHide(hide)}><i className="iconfont icon-shenglvehao"></i></span> }
<span className="ml12 color-grey-9 mt3">{lastCommit && lastCommit.time_from_now}</span>
{ commitCount ? <Link to={`/projects/${owner}/${projectsId}/commits`} className="ml12 color-grey-9"><i className="iconfont icon-tijiao mr3 font-17 color-grey-9"></i>{commitCount}次提交</Link>:"" }
<span className="ml20 color-grey-9 mt1">{lastCommit && lastCommit.time_from_now}</span>
{
commitCount ?
<Link to={`/projects/${owner}/${projectsId}/commits/branch/${turnbar(branchName || defaultBranch)}`} className="ml20 color-grey-9" style={{height:"30px",lineHeight:"30px"}}>
<i className="iconfont icon-tijiaoicon mr3 font-16"></i>{commitCount}次提交
</Link>:""
}
</div>
}
<ul className="listtablebody">
@ -335,9 +430,11 @@ function CoderDepot(props){
{...props}
detail={fileInfo}
readOnly={readOnly}
md={mdFlag}
onEdit={onEdit}
currentBranch={branchName || (projectDetail && projectDetail.default_branch)}
></CoderRootFileDetail>
currentBranch={branchName || defaultBranch}
type={projectDetail.type}
></CoderRootFileDetail>[[]]
}
</ul>
</div>
@ -347,7 +444,7 @@ function CoderDepot(props){
(dirInfo && dirInfo.length === 0) && (fileInfo && fileInfo.length === 0) ? <Nodata _html="暂未发现文件"/> :""
}
{/* readme文件显示(显示文件详情时不显示readme文件) */}
{ dirInfo && (projectDetail && projectDetail.readme) ? <ReadMe ChangeFile={ChangeFile} readme={projectDetail && projectDetail.readme} operate={props && (props.isManager || props.isDeveloper)} history={props.history} /> :"" }
{ dirInfo && (readme && readme.content) ? <ReadMe ChangeFile={ChangeFile} readme={readme} operate={props && (props.isManager || props.isDeveloper) && projectDetail.type !==2 } history={props.history} /> :"" }
</div>
</LongWidth>
{
@ -355,48 +452,74 @@ function CoderDepot(props){
<ShortWidth>
<Gap style={{paddingLeft:"30px"}}>
<div className="panelmenu">
<FlexAJ className="font-18 color-grey-6 mb20" style={{lineHeight:"28px"}}>简介
{projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner") && <i onClick={()=>setOpenModal(true)} className="iconfont icon-anquanshezhi color-grey-9 font-15"></i>}
<FlexAJ className="font-16 color-ooo mb10" style={{lineHeight:"22px"}}>关于
{projectDetail.permission && (projectDetail.permission==="Admin" || projectDetail.permission==="Owner") &&
<a className="color-grey-6" href="javascript:void(0)"><i onClick={()=>setOpenModal(true)} className="iconfont icon-a-shezhi font-15"></i></a>
}
</FlexAJ>
{desc && <p className="font-14 color-grey-9 mb15 task-hide-2" style={{lineHeight:"22px",WebkitLineClamp:"4",textAlign:"justify"}}>{desc}</p>}
{desc && <p className="font-14 color-grey-3 mb15 task-hide-2" style={{lineHeight:"24px",WebkitLineClamp:"4",textAlign:"justify",wordBreak:"break-all"}}>{desc}</p>}
{
website &&
<p className="color-grey-6 df">
<i className="iconfont icon-lianjie2 font-15 mr10 color-grey-9"></i>
<span style={{wordBreak:"break-all",lineHeight:"20px",marginTop:"5px"}}>{website}</span>
</p>
<div className="color-grey-6 df pinfos mb5">
<i className="iconfont icon-lianjie2 font-15 mr10"></i>
<a href={website} target="_blank" style={{wordBreak:"break-all",lineHeight:"20px",marginTop:"5px",textDecoration:"underline"}}>{website}</a>
</div>
}
<p>
<i className="iconfont icon-wenjian4 font-15 mr10 color-grey-9"></i>
<a href="#readme" className="color-grey-6">README.md</a>
</p>
<p className="color-grey-6">
<i className="iconfont icon-dataBase font-15 mr10 color-grey-9"></i>
<div className="pinfos mb5">
<i className="iconfont icon-zishuwenjian_icon font-15 mr10"></i>
<a href="#readme">README.md</a>
</div>
<div className="color-grey-6 mb5">
<i className="iconfont icon-neicunicon font-15 mr10"></i>
<span>{projectDetail && projectDetail.size}</span>
</p>
</div>
{
projectDetail && projectDetail.license_name &&
<p className="color-grey-6">
<i className="iconfont icon-tianping font-16 mr10 color-grey-9"></i>
<span>{projectDetail.license_name}</span>
</p>
<div>
<i className="iconfont icon-xieyiicon font-16 mr10 color-grey-6"></i>
<span className="color-grey-6">{projectDetail.license_name}</span>
</div>
}
</div>
{
inviteCode &&
<div>
<Divider />
<Invite code={inviteCode}/>
</div>
}
{
lesson_url &&
<div>
<Divider />
<p className="font-16 color-ooo">实践课程</p>
<a href={lesson_url} target="_blank" className="color-grey-6" style={{textDecoration:"underline",wordBreak:"break-all"}}>{lesson_url}</a>
</div>
}
{/* 发布 */}
{
projectDetail && projectDetail.release_versions &&
<React.Fragment>
<Divider />
<Releases owner={owner} projectsId={projectsId} releaseVersions={projectDetail.release_versions} history={props.history}/>
<Releases
owner={owner}
projectsId={projectsId}
releaseVersions={projectDetail.release_versions}
history={props.history}
baseOperate={baseOperate}
projectType={projectDetail.type}
/>
</React.Fragment>
}
{/* 贡献者 */}
{
projectDetail && projectDetail.contributors &&
<React.Fragment>
<Divider />
<Contributors contributors={projectDetail && projectDetail.contributors} owner={owner} projectsId={projectsId}/>
</React.Fragment>
<Contributors
contributors={projectDetail && projectDetail.contributors}
owner={owner}
projectsId={projectsId}
currentLogin={current_user && current_user.login}
/>
}
{/* 语言 */}
{ projectDetail && projectDetail.languages &&

View File

@ -2,12 +2,18 @@ import React from 'react';
import { Link } from 'react-router-dom';
import { truncateCommitId } from '../common/util';
const typeIco = {
"submodule":"icon-file-submodule font-17",
"file":'icon-wenjian6 font-15',
"dir":"icon-wenjianjia4 font-15"
}
function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId }){
return(
<li>
<span>
<a onClick={()=>goToSubRoot(item.path,item.type,item.name)}>
<i className={item.type === 'dir' ? "iconfont icon-wenjianjia1 color-green-file font-15 mr5":"iconfont icon-wenjia color-green-file font-15 mr5"}></i>{item.name}
<a onClick={()=>goToSubRoot(item.path,item.type,item.name)} className={item.type === "submodule" && "submoduleStyle"}>
<i className={`iconfont ${typeIco[`${item.type}`]} color-blue-file mr8`}></i>{item.name}
</a>
</span>
<span title="init project">

View File

@ -1,25 +1,72 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import RenderHtml from '../../components/render-html';
import { AlignCenter } from '../Component/layout';
import { Dropdown , Anchor , Spin } from 'antd';
import ReadmeCatelogue from './sub/ReadmeCatelogue';
const $ = window.$;
function CoderDepotReadme({ operate , history , readme , ChangeFile }){
const [ menuList ,setMenuList ] = useState(undefined);
const [ content ,setContent ] = useState(undefined);
useEffect(()=>{
if(readme && readme.content){
setContent(readme.content);
}else{
setContent(undefined);
}
},[readme])
useEffect(()=>{
let path = history.location.pathname;
const items = $.map($("#readme").find("h1,h2,h3,h4,h5,h6"), function (el, _) {
const anchor = el.id;
const level = el.tagName.replace("H", "");
const href = `#${anchor}`;
return { href:`${href}`,text:el.textContent , level:level }
});
setMenuList(items);
},[content])
function menu(){
if(menuList && menuList.length > 0){
return(
<div className="commonBox" id="readme">
<div className="commonBox-title">
<span className="mr10">
<i className="iconfont icon-wenjian1 font-16 color-grey-9 fl mt3"></i>
<ReadmeCatelogue menuList={menuList} hash={history.location.hash}/>
)
}else{
return <Spin />
}
}
return(
<div className="commonBox readBox" id="readme">
<Anchor offsetTop={70} targetOffset={160}>
<div className="commonBox-title boxTitle">
<AlignCenter>
<Dropdown overlay={menu()} trigger={['hover']} overlayClassName="menuslist">
<span className="catelogue">
<i className="iconfont icon-muluicon font-12 mr5"></i>
<span>目录</span>
</span>
</Dropdown>
<span className="commonBox-title-read">README.md</span>
</AlignCenter>
{
operate ?
<a className="ml20 pull-right" onClick={() =>ChangeFile(readme && readme.path, false)}>
<i className="iconfont icon-bianji6 font-16 color-blue"></i>
<i className="iconfont icon-a-bianji font-17 color-grey-6"></i>
</a>
:""
}
</div>
</Anchor>
{
content &&
<div className="commonBox-info">
<RenderHtml className="break_word_comments imageLayerParent" value={readme && readme.content} url={history.location}/>
<RenderHtml className="break_word_comments imageLayerParent" value={content} url={history.location}/>
</div>
}
</div>
)
}

View File

@ -4,14 +4,20 @@ import { Dropdown , Menu , Icon , Tooltip , Spin } from 'antd';
import { truncateCommitId } from '../common/util';
import { getBranch } from '../GetData/getData';
import Nodata from '../Nodata';
import './list.css';
import './list.scss';
function turnbar(str){
if(str && str.length>0 && str.indexOf("/")>-1){
return str.replaceAll('/','%2F');
}
return str;
}
export default ((props)=>{
const [ data , setData ] =useState(undefined);
const [ isSpin , setIsSpin ] =useState(true);
const { projectsId , owner } = props.match.params;
const { isManager , isDeveloper , projectDetail } = props;
useEffect(()=>{
getBranchs(projectsId, owner);
},[projectsId])
@ -32,7 +38,7 @@ export default ((props)=>{
return(
<li key={key}>
<div>
<Link to={`/projects/${owner}/${projectsId}/tree/${item.name}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
<Link to={`/projects/${owner}/${projectsId}/tree/${turnbar(item.name)}`} className="color-blue font-15" style={{"maxWidth":"100px"}}>{item.name}</Link>
<p className="f-wrap-alignCenter mt15">
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.last_commit.sha}`)}`} className="mr5 commitKey" style={{marginLeft:0}}>{item.last_commit && truncateCommitId(item.last_commit.sha)}</Link>
<span className="color-grey-3 hide-1 messages leftPoint">{item.last_commit && item.last_commit.message}</span>
@ -40,7 +46,10 @@ export default ((props)=>{
</p>
</div>
<span>
<Link to={`/projects/${owner}/${projectsId}/pulls/new`} className="mr20 color-blue mr30">创建合并请求</Link>
{
(isManager || isDeveloper) && (projectDetail && projectDetail.type!==2) &&
<Link to={`/projects/${owner}/${projectsId}/pulls/new/${item.name}`} className="mr20 color-blue mr30">创建合并请求</Link>
}
<Dropdown overlay={menu(item.zip_url,item.tar_url)} trigger={['click']} placement="bottomRight" className="color-green-file">
<a className="ant-dropdown-link">
<Tooltip title={`下载分支${item.name}`}><Icon type="cloud-download" className="font-18"/></Tooltip>
@ -64,6 +73,7 @@ export default ((props)=>{
<Menu.Item key={'1'}><a href={tar_url}>TAR.GZ</a></Menu.Item>
</Menu>
)
return(
<React.Fragment>
<div className="main">

View File

@ -2,12 +2,19 @@ import React , { Component } from 'react';
import { Spin , Pagination } from 'antd';
import { getImageUrl } from 'educoder';
import { truncateCommitId } from '../common/util';
import { AlignTop } from '../Component/layout';
import SelectBranch from '../Branch/Select';
import Nodata from '../Nodata';
import axios from 'axios';
import {Link} from "react-router-dom";
function returnbar(str){
if(str && str.length>0 && str.indexOf("%2F")>-1){
return str.replaceAll('%2F','/');
}
return str;
}
class CoderRootCommit extends Component{
constructor(props){
super(props)
@ -56,11 +63,12 @@ class CoderRootCommit extends Component{
this.setState({
isSpining:true
})
console.log(returnbar(branch));
const { projectsId , owner } = this.props.match.params;
const url = `/${owner}/${projectsId}/commits.json`;
axios.get(url,{
params:{
sha:branch,
sha:returnbar(branch),
page,
limit
}
@ -74,6 +82,7 @@ class CoderRootCommit extends Component{
array.push({
name:item.author && item.author.name,
login: item.author && item.author.login,
id: item.author && item.author.id,
image_url:item.author && item.author.image_url,
sha:item.sha,
time_from_now:item.time_from_now,
@ -104,10 +113,10 @@ class CoderRootCommit extends Component{
const { commitDatas , dataCount , limit , page , isSpining , branchList } = this.state;
const { projectDetail, commit_class , defaultBranch } = this.props;
const { projectsId , owner , branchName } = this.props.match.params;
let branch = branchName || defaultBranch;
let branch = returnbar(branchName || defaultBranch);
return(
<React.Fragment>
<div className={"main"}>
<div className={"main"}style={{padding:"0px",border:"none"}}>
<div className="f-wrap-between">
<SelectBranch
repo_id={projectDetail && projectDetail.repo_id}
@ -131,15 +140,23 @@ class CoderRootCommit extends Component{
commitDatas && commitDatas.length > 0 && commitDatas.map((item,k)=>{
return(
<div key={k}>
<p className="f-wrap-alignCenter">
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitKey" style={{marginLeft:0}}>{truncateCommitId(`${item.sha}`)}</Link>
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="flex1 ml20 font-16 color-grey-3">{item.message}</Link>
</p>
<AlignTop>
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitKey" style={{marginLeft:0,marginTop:"3px"}}>{truncateCommitId(`${item.sha}`)}</Link>
<Link to={`/projects/${owner}/${projectsId}/commits/${truncateCommitId(`${item.sha}`)}`} className="commitDesc">{item.message}</Link>
</AlignTop>
<p className="f-wrap-alignCenter mt15">
{
item.id ?
<Link to={`/users/${item.login}`} className="show-user-link">
{item.image_url?<img src={getImageUrl(`images/${item.image_url}`)} alt="" width="28px" height="28px" className="mr15 radius"/>:""}
{item.image_url?<img src={getImageUrl(`/${item.image_url}`)} alt="" width="28px" height="28px" className="mr15 radius"/>:""}
<label className="font-14 color-grey-6" style={{verticalAlign:'middle'}}>{item.name ?`${item.name}:`:""}提交于 {item.time_from_now}</label>
</Link>
</Link>:
<span className="show-user-link">
{item.image_url?<img src={getImageUrl(`/${item.image_url}`)} alt="" width="28px" height="28px" className="mr15 radius"/>:""}
<label className="font-14 color-grey-6" style={{verticalAlign:'middle'}}>{item.name ?`${item.name}:`:""}提交于 {item.time_from_now}</label>
</span>
}
</p>
</div>
)

View File

@ -1,6 +1,6 @@
import React, { Component } from "react";
import { Popconfirm , Select } from "antd";
import "./list.css";
import "./list.scss";
import axios from "axios";
import Meditor from "../Newfile/m_editor";
import RenderHtml from "../../components/render-html";
@ -24,13 +24,25 @@ class CoderRootFileDetail extends Component {
}
componentDidMount = () => {
const { detail } = this.props;
const { detail , mdFlag } = this.props;
this.setState({
value: detail.content,
});
this.languages_total();
};
componentDidUpdate=(prevProps)=>{
const { content } = this.props && this.props.detail;
const prevcontent = prevProps.detail && prevProps.detail.content;
if (content && prevcontent) {
if (prevcontent !== content){
this.setState({
description: content
});
}
}
}
languages_total = () => {
const { detail } = this.props;
const file_name = detail.path.split("/").pop().split(".").pop();
@ -164,9 +176,10 @@ class CoderRootFileDetail extends Component {
current_user,
isManager,
isDeveloper,
md,
currentBranch,
platform
platform,
md,
type
} = this.props;
const { language, languages, description } = this.state;
let flag = current_user && current_user.login && (isManager || isDeveloper);
@ -185,17 +198,18 @@ class CoderRootFileDetail extends Component {
{readOnly ? (
<span>
{
detail.direct_download ?
""
:
!detail.direct_download?
<span>
<a onClick={() => this.DownLoadFile(detail.download_url)} className="ml20">
<i className="iconfont icon-xiazai1 font-15 color-grey-6"></i>
</a>
{
type !==2 &&
<a onClick={() => this.EditFile(false)} className="ml20">
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
</a>
</span>
}
</span>:""
}
</span>
) : (
@ -226,7 +240,8 @@ class CoderRootFileDetail extends Component {
</button>
</React.Fragment>
)}
{
type !==2 &&
<Popconfirm
title="确认删除这个文件?"
className="ml20"
@ -238,6 +253,8 @@ class CoderRootFileDetail extends Component {
<i className="iconfont icon-shanchu font-15 color-grey-6"></i>
</a>
</Popconfirm>
}
</div>
)}
</p>
@ -245,11 +262,7 @@ class CoderRootFileDetail extends Component {
<div>
{detail.image_type ? (
<div className="edu-txt-center pt20 pb20">
<img
alt=""
src={detail.download_url}
style={{ maxWidth: "80%" }}
/>
<img alt="" src={detail.download_url} style={{ maxWidth: "80%" }} />
</div>
) : detail.direct_download ? (
<div className="mt20 text-center">
@ -268,10 +281,11 @@ class CoderRootFileDetail extends Component {
{...this.state}
language={language ? language : "javascript"}
filepath={`/${detail.path}`}
content={detail.content}
content={description}
readOnly={readOnly}
editorType="update"
currentBranch={currentBranch}
descName={detail && `Update ${detail.name}`}
></Meditor>
)}
</div>

View File

@ -13,10 +13,6 @@ const UploadFile = Loadable({
loader: () => import('../Newfile/upload_file'),
loading: Loading,
})
const CoderRootDirectory = Loadable({
loader: () => import('./CoderRootDirectory'),
loading: Loading,
})
const CoderRootCommit = Loadable({
loader: () => import('./CoderRootCommit'),
loading: Loading,
@ -106,6 +102,11 @@ class CoderRootIndex extends Component{
(props) => (<FileNew {...this.props} {...props} {...this.state} getTopCount={this.getTopCount} />)
}
></Route>
<Route path="/projects/:owner/:projectsId/commits/branch/:branchName"
render={
() => (<CoderRootCommit {...this.props} {...this.state} commit_class="main" getTopCount={this.getTopCount} />)
}
></Route>
<Route path="/projects/:owner/:projectsId/commits/:sha"
render={
(props) => (<Diff {...this.props} {...props} {...this.state}/>)

View File

@ -26,7 +26,7 @@ export default (( props, { projectDetail }) => {
}, [owner, projectsId]);
return (
<div className="main">
<div className="main" style={{padding:"0px",border:"none"}}>
<Spin spinning={isSpin}>
<div style={{minHeight:"400px"}}>
{

View File

@ -1,10 +1,11 @@
import React, { Component } from 'react';
import { Spin, Tooltip } from 'antd';
import { Spin, Tooltip, Button } from 'antd';
import { Link, Route, Switch } from 'react-router-dom';
import { Content } from '../Component/layout';
import { Content , AlignTop, AlignCenter } from '../Component/layout';
import DetailBanner from './sub/DetailBanner';
import { numFormat } from 'educoder';
import '../css/index.scss'
import './list.css';
import './list.scss';
import Loadable from 'react-loadable';
import Loading from '../../Loading';
@ -127,7 +128,15 @@ const Source = Loadable({
const DevIndex = Loadable({
loader: () => import('../DevOps/Index'),
loading: Loading,
})
});
const Wiki = Loadable({
loader: () => import('../Wiki/Index'),
loading: Loading,
});
const WikiEdit = Loadable({
loader: () => import('../Wiki/EditWiki'),
loading: Loading,
});
/**
* permissionManager:管理员Reporter报告人员(只有读取权限)Developer开发人员除不能设置仓库信息外
*/
@ -151,6 +160,8 @@ function checkPathname(projectsId,owner,pathname){
name="devops"
}else if(url.indexOf(`/source`)>-1){
name="source"
}else if(url.indexOf(`/wiki`)>-1){
name="wiki"
}
}
return name;
@ -176,6 +187,7 @@ class Detail extends Component {
firstSync:false,
secondSync:false,
open_devops:false,
forkSpin:false,
// 默认分支
defaultBranch:undefined,
@ -214,7 +226,7 @@ class Detail extends Component {
if(num){
this.setState({
secondSync:true,
firsrtSync:false
firstSync:false
})
}else{
this.setState({
@ -225,7 +237,7 @@ class Detail extends Component {
}else{
this.getDetail();
this.setState({
firsrtSync:false,
firstSync:false,
secondSync:false
})
}
@ -246,7 +258,7 @@ class Detail extends Component {
var cable = actioncable.createConsumer(`wss://${name}/cable`);
this.canvasChannel1 = cable.subscriptions.create({
channel: `MirrorProjectChannel`,
id: project && project.identifier
id: project && project.id
}, {
connected: () => {
console.log("###### channel connected! ######");
@ -256,6 +268,10 @@ class Detail extends Component {
console.log(`###### ---received data--- ######`);
if (data) {
this.getDetail();
this.setState({
firstSync:false,
secondSync:false
});
cable.subscriptions.consumer.disconnect();
}
}
@ -358,6 +374,9 @@ class Detail extends Component {
forkFunc = () => {
const { platform } = this.state;
if(!platform)return;
this.setState({
forkSpin:true
})
const { current_user } = this.props
const { projectsId , owner } = this.props.match.params;
const url = `/${owner}/${projectsId}/forks.json`;
@ -366,8 +385,13 @@ class Detail extends Component {
this.props.history.push(`/projects/${current_user && current_user.login}/${result.data.identifier}`);
this.props.showNotification(result.data.message);
}
this.setState({
forkSpin:false
})
}).catch(error => {
console.log(error);
this.setState({
forkSpin:false
})
})
}
@ -389,32 +413,33 @@ class Detail extends Component {
})
}
textFunc = (forked_from_project_id,fork_info)=>{
let type = fork_info && fork_info.fork_project_user_type;
return forked_from_project_id && fork_info ?
<div className="color-grey-9 df">
<span>复刻自</span>
<Link to={`${type ==="Organization" ? "/organize":'/users'}/${fork_info.fork_project_user_login}`} className="show-user-link color-grey-6 ml5">{fork_info.fork_project_user_name}</Link>
<span> / </span>
<Link to={`/projects/${fork_info.fork_project_user_login}/${fork_info.fork_project_identifier}`} className="color-grey-6 task-hide flex1" style={{maxWidth:"400px"}} title={fork_info.fork_form_name}>{fork_info.fork_form_name}</Link>
</div> : ""
}
render() {
const { projectDetail, watchers_count, praises_count,
forked_count, firstSync , secondSync ,
isManager, watched, praised,
project , open_devops , platform , defaultBranch , bannerList } = this.state;
project , open_devops , platform , defaultBranch , bannerList , forkSpin } = this.state;
const url = this.props.history.location.pathname;
const urlArr = url.split("/");
const urlFlag = (urlArr.length === 3);
const { projectsId , owner } = this.props.match.params;
const { current_user } = this.props;
let pathname = checkPathname(projectsId,owner,url);
const { state } = this.props.history.location;
const text = (
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
<React.Fragment>
<span>forked from </span>
<Link to={`/users/${projectDetail.fork_info.fork_project_user_login}`} className="show-user-link color-grey-ccc">{projectDetail.fork_info.fork_project_user_name}</Link>
<span> / </span>
<Link to={`/projects/${projectDetail.fork_info.fork_project_user_login}/${projectDetail.fork_info.fork_project_identifier}`} className="color-grey-ccc">{projectDetail.fork_info.fork_form_name}</Link>
</React.Fragment> : ""
);
const common = {
getDetail: this.getDetail,
changeOpenDevops:this.changeOpenDevops,
@ -424,56 +449,37 @@ class Detail extends Component {
<div>
<div className="detailHeader-wrapper">
<div className="normal">
<div className="f-wrap-between pb15" style={{ position: "relative" }}>
<p className="font-22 df flex-1 lineH2 mt15" style={{ alignItems: "center" }}>
<AlignCenter style={{paddingTop:"20px",justifyContent:"space-between"}}>
<AlignTop>
<div className="projectallName">
{project && project.author &&
<Link to={`${project.author.type ==="Organization" ? "/organize":'/users'}/${project.author.login}`} className="show-user-link">
{project.author.name}
</Link>
<Link to={`${project.author.type ==="Organization" ? "/organize":'/users'}/${project.author.login}`} title={project.author.name}>{project.author.name}</Link>
}
<span className="ml5 mr5">/</span>
<span className="hide-1 flex-1 df">
<Link to={`/projects/${owner}/${projectsId}`} className="font-22">{project && project.name}</Link>
{
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
<Tooltip placement={'right'} title={text}>
<Link to={`/projects/${projectDetail.fork_info.fork_project_user_login}/${projectDetail.fork_info.fork_project_identifier}`}
className="ml10" >
<i className="iconfont icon-fork font-18 fl mt6" style={{ color: "#8D90E3" }}></i>
</Link>
</Tooltip> : ""
}
{
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
projectDetail.type === 2 ?
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
<i className="iconfont icon-banbenku font-18 mt6" style={{ color: "#8D90E3" }}/>
</Tooltip>
:
<Tooltip title={"镜像自: " + projectDetail.mirror_url} className="ml5" placement={'right'}>
<i className="iconfont icon-jingxiang font-18 color-green mt6" />
</Tooltip>
:""
}
</span>
</p>
<Link to={`/projects/${owner}/${projectsId}`} className="projectN" title={projectDetail && projectDetail.name}>{projectDetail && projectDetail.name}</Link>
</div>
{ projectDetail && projectDetail.private && <span className="privateTag">私有</span>}
</AlignTop>
<div>
{
firstSync ? "":
<span className="df mt25">
<span className="df">
{
projectDetail && projectDetail.type && projectDetail.type === 2 ?
<a className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
((current_user && current_user.admin) || isManager) && (projectDetail && projectDetail.type && projectDetail.type === 2) ?
<a size="middle" className="synchronism ml30" onClick={this.synchronismMirror}>同步镜像</a> : ""
}
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.focusFunc(watched)}>
<i className={watched ? "iconfont icon-shixing color-orange font-16 mr3":"iconfont icon-kongxing color-grey-9 font-16 mr3"}></i>
<i className={watched ? "iconfont icon-quxiaoguanzhu color-blue font-14 mr3":"iconfont icon-morenguanzhu_ICON color-grey-9 font-14 mr3"}></i>
<span>{watched ? '取消关注' : '关注'}</span>
</a>
{
watchers_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" style={{color:`${watched?"#2878FF":"#666"}`}} to={platform?{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }:""}>
{watchers_count}
<Link className="detail_tag_btn_count" to={platform?{ pathname: `/projects/${owner}/${projectsId}/watchers`, state }:""}>
{numFormat(watchers_count)}
</Link>
:
<span className="detail_tag_btn_count">{watchers_count}</span>
@ -482,28 +488,31 @@ class Detail extends Component {
</span>
<span className="detail_tag_btn">
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={() => this.pariseFunc(praised)}>
<i className={praised ? "iconfont icon-weibiaoti105 color-orange font-14 mr3":"iconfont icon-guanzhu color-grey-9 font-14 mr3"}></i>
<i className={praised ? "iconfont icon-dianzan_icon color-blue font-14 mr3":"iconfont icon-guanzhu color-grey-9 font-14 mr3"}></i>
<span>{praised ? '取消点赞' : '点赞'}</span>
</a>
{
praises_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" style={{color:`${praised?"#2878FF":"#666"}`}} to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
{praises_count}
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/stargazers`, state }}>
{numFormat(praises_count)}
</Link>:
<span className="detail_tag_btn_count">{praises_count}</span>
:""
}
</span>
<span className="detail_tag_btn">
<span className="detail_tag_btn" loading={forkSpin}>
<Tooltip title="复刻是fork的中文名即复制代码仓库" placement="bottom">
<a className="detail_tag_btn_name" style={{cursor:platform?"pointer":"default"}} onClick={this.forkFunc}>
<i className="iconfont icon-fork color-grey-9 mr3"></i> (Fork)
<i className="iconfont icon-fork color-grey-9 mr3 font-16"></i>
<span>复刻</span>
</a>
</Tooltip>
{
forked_count > 0 ?
platform ?
<Link className="detail_tag_btn_count" to={{ pathname: `/projects/${owner}/${projectsId}/fork_users`, state }}>
{forked_count}
{numFormat(forked_count)}
</Link>
:
<span className="detail_tag_btn_count">{forked_count}</span>
@ -513,9 +522,23 @@ class Detail extends Component {
</span>
}
</div>
</AlignCenter>
<div className="mt6" style={{minHeight:"20px"}}>
{
projectDetail && projectDetail.forked_from_project_id && projectDetail.fork_info ?
this.textFunc(projectDetail.forked_from_project_id,projectDetail.fork_info)
:""
}
{
projectDetail && projectDetail.type && projectDetail.type !== 0 ?
<span className="color-grey-9">镜像自 <a className="color-blue hoverLine" target="_blank" href={projectDetail.mirror_url}>{projectDetail.mirror_url}</a></span>
:""
}
</div>
{
firstSync ? "" :
<DetailBanner
history={this.props.history}
list={bannerList}
owner={owner}
projectsId={projectsId}
@ -550,6 +573,24 @@ class Detail extends Component {
() => (<DevAbout {...this.props} {...this.state} {...common} />)
}
></Route>
{/* wiki新增文件 */}
<Route path="/projects/:owner/:projectsId/wiki/add"
render={
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
}
></Route>
{/* wiki编辑文件 */}
<Route path="/projects/:owner/:projectsId/wiki/edit/:wikiName"
render={
() => (<WikiEdit {...this.props} {...this.state} {...common} />)
}
></Route>
{/* wiki */}
<Route path="/projects/:owner/:projectsId/wiki"
render={
() => (<Wiki {...this.props} {...this.state} {...common} />)
}
></Route>
{/* 工作流 */}
<Route path="/projects/:owner/:projectsId/devops"
render={
@ -635,6 +676,11 @@ class Detail extends Component {
}
></Route>
{/* 新建合并请求 */}
<Route path="/projects/:owner/:projectsId/pulls/new/:branch"
render={
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)
}
></Route>
<Route path="/projects/:owner/:projectsId/pulls/new"
render={
(props) => (<CreateMerge {...this.props} {...props} {...this.state} {...common} is_fork={true} />)

View File

@ -51,7 +51,7 @@ export default ({ match , history }) => {
}
}, [projectsId , owner, sha]);
return (
<div className="main">
<div className="main" style={{padding:"0px",border:"none"}}>
<Spin spinning={isSpin}>
<Infos>
<div className="commitinfos">
@ -65,7 +65,7 @@ export default ({ match , history }) => {
<div className="f-wrap-between" style={{ alignItems: "center" }}>
<ul className="df">
<User
url={(committer && getImageUrl(`images/${committer.image_url}`))|| "https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"}
url={(committer && getImageUrl(`/${committer.image_url}`))|| "https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"}
name={committer && committer.name}
/>
{committer && committer.time_from_now && <li className="ml20 mt2">{committer.time_from_now}</li>}

420
src/forge/Main/Index.css Normal file
View File

@ -0,0 +1,420 @@
.recommandOri.slick-slider {
width: 1300px;
margin: 20px auto 40px;
}
.recommandOri.slick-slider .slick-track {
margin-left: 0px;
}
.recommandOri.slick-slider .slick-slide li > a {
display: flex;
align-items: center;
justify-content: center;
}
/* recommandProjects */
.recommandProjects.slick-slider {
width: 1230px;
margin: 20px auto 40px;
}
.recommandProjects.slick-slider .slick-track {
margin-left: 0px;
}
.recommandProjects.slick-slider .slick-arrow.slick-prev:before, .recommandProjects.slick-slider .slick-arrow.slick-next:before {
color: #999;
}
.recommandProjects.slick-slider .slick-arrow.slick-prev li.slick-active button:before, .recommandProjects.slick-slider .slick-arrow.slick-next li.slick-active button:before {
color: #999;
}
.recommandProjects.slick-slider .slick-dots {
bottom: -29px;
}
.recommandProjects.slick-slider .slick-dots li button:before {
color: #909090;
}
.recommandProjects.slick-slider .slick-slide {
padding: 0px 15px;
box-sizing: border-box;
}
.recommandProjects.slick-slider .slick-slide > div {
background-color: #fff;
border-radius: 10px;
width: 100%;
cursor: pointer;
border: 1px solid #eee;
}
.recommandProjects.slick-slider .slick-slide > div:hover {
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.1);
}
.recommandProjects.slick-slider .baseInfo {
padding: 18px 15px;
display: flex;
font-size: 12px;
color: #888;
}
.recommandProjects.slick-slider .baseInfo .look {
margin-right: 10px;
}
.recommandProjects.slick-slider .baseInfo .look i {
margin-right: 5px;
}
.recommandProjects.slick-slider .baseInfo .type {
flex: 1;
width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: right;
}
.recommandProjects.slick-slider .mainInfo {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 160px;
border-bottom: 1px solid #eee;
padding: 20px;
box-sizing: border-box;
}
.recommandProjects.slick-slider .mainInfo img {
height: 50px;
width: 50px;
border-radius: 50%;
}
.recommandProjects.slick-slider .mainInfo .name {
font-size: 13px;
color: #666;
height: 18px;
line-height: 18px;
margin-top: 12px;
}
.recommandProjects.slick-slider .mainInfo .school {
margin-top: 12px;
color: #333;
font-size: 16px;
height: 22px;
line-height: 22px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
}
.Panels {
max-width: 1200px;
margin: 0 auto;
}
.Panels .panelmenu {
padding-top: 30px;
}
.Panels .panelmenu .depotBtn .mr-5 {
margin-right: -5px;
}
.Panels .panelmenu .depotBtn .ant-btn {
height: 36px;
line-height: 34px;
width: 83px;
text-align: center;
padding: 0px;
font-weight: 500;
font-size: 14px;
}
.Panels .panelmenu .depotBtn .ant-btn-default {
color: #333;
border-color: #d0d0d0;
}
.Panels .panelmenu .depotBtn .ant-btn-default:hover {
background: #F3F4F6;
}
.Panels .panelmenu .depotBtn .ant-btn-primary {
color: #fff;
background-color: #466AFF;
opacity: 0.8;
}
.Panels .addOptionBtn {
height: 32px;
line-height: 30px;
display: flex;
border: 1px solid #d9d9d9;
border-radius: 2px;
}
.Panels .addOptionBtn a {
padding: 0px 13px;
color: rgba(0, 0, 0, 0.65);
cursor: pointer;
}
.Panels .addOptionBtn > a:first-child {
border-right: 1px solid #d9d9d9;
}
.Panels .addOptionBtn > a:last-child {
border-right: none;
}
.Panels .infoCount {
display: inline-block;
width: 24px;
text-align: center;
height: 24px;
line-height: 24px;
background-color: rgba(153, 153, 153, 0.13);
color: #666;
border-radius: 12px;
margin-left: 6px;
font-size: 12px;
}
.Panels .attrPerson {
padding-top: 12px;
display: flex;
flex-wrap: wrap;
padding-bottom: 2px;
}
.Panels .attrPerson a {
margin: 0px 17px 0px 0px;
}
.Panels .attrPerson a img {
border-radius: 50%;
width: 40px;
height: 40px;
}
.Panels .attrPerson a:nth-child(6) {
margin-right: 0px;
}
.Panels .progress {
display: flex;
border-radius: 10px;
height: 7px;
margin-top: 12px;
}
.Panels .progress span:first-child {
border-radius: 10px 0px 0px 10px;
}
.Panels .progress span:last-child {
border-radius: 0px 10px 10px 0px;
}
.Panels .progresstip {
margin-top: 15px;
flex-wrap: wrap;
}
.Panels .progresstip i.zero {
position: absolute;
display: block;
border-radius: 50%;
height: 8px;
width: 8px;
left: 0px;
top: 10px;
}
.Panels .progresstip > span {
padding-left: 15px;
position: relative;
min-width: 33.5%;
font-size: 12px;
font-weight: 400;
color: #666;
}
.Panels .progresstip > span span:last-child {
margin-left: 5px;
}
.Panels .listtable {
margin-top: 20px;
}
.Panels .listtable .listtablehead {
height: 55px;
display: flex;
justify-content: space-between;
align-items: flex-start;
border-bottom: 1px solid #d9d9d9;
padding: 13px 20px;
border-radius: 4px 4px 0px 0px;
border: 1px solid rgba(42, 97, 255, 0.23);
background-color: #FAFCFF;
}
.Panels .listtable .listtablehead .ellipsistxt {
margin-top: 6px;
margin-left: 13px;
line-height: 18px;
flex: 1;
width: 0;
color: #666;
}
.Panels .listtable .listtablehead .ellipsistxt #ptxt {
margin-bottom: 0px;
word-break: break-all;
overflow: unset;
white-space: pre-wrap;
/* css3.0 */
white-space: -moz-pre-wrap;
/* Firefox */
white-space: -pre-wrap;
/* Opera 4-6 */
white-space: -o-pre-wrap;
/* Opera 7 */
word-wrap: break-word;
}
.Panels .listtable .listtablehead .ellipsistxt.hidetxt {
height: 18px;
overflow: hidden;
position: relative;
padding-right: 8px;
}
.Panels .listtable .listtablehead .ellipsis {
margin-left: 8px;
cursor: pointer;
border-radius: 2px;
height: 16px;
background: rgba(153, 153, 153, 0.2);
border-radius: 2px;
padding: 0px 4px;
height: 14px;
line-height: 14px;
margin-top: 9px;
}
.Panels .listtable .listtablehead .ellipsis i {
font-size: 15px !important;
color: #333;
height: 14px;
line-height: 14px;
}
.Panels .listtable .listtablebody {
border-radius: 0px 0px 4px 4px;
border: 1px solid #D0D0D0;
border-top: none;
}
.Panels .listtable .listtablebody li.listtablepath a {
color: #40a9ff;
}
.Panels .listtable .listtablebody li.listtablepath p {
margin-bottom: 0px !important;
}
.Panels .listtable .listtablebody > li {
height: 38px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #d9d9d9;
padding: 0px 20px 0px 24px;
}
.Panels .listtable .listtablebody > li:hover {
background-color: #F3F4F6;
}
.Panels .listtable .listtablebody > li > span:first-child {
width: 30%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.Panels .listtable .listtablebody > li > span:nth-child(2) {
width: 60%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.Panels .listtable .listtablebody > li > span:nth-child(3) {
width: 10%;
text-align: right;
}
.Panels .listtable .listtablebody > li:last-child {
border-bottom: none;
}
.drawerBtn {
position: fixed;
left: -13px;
width: 33px;
background: #FFFFFF;
box-shadow: 0px 0px 8px 3px rgba(0, 0, 0, 0.09);
border: 1px solid #666666;
border-radius: 0px 12px 12px 0px;
height: 70px;
top: 50%;
margin-top: -35px;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-left: 7px;
}
.drawerBtn:hover {
box-shadow: 0px 0px 8px 3px rgba(0, 0, 0, 0.09);
}
.drawerBtn span {
writing-mode: vertical-lr;
color: #333;
width: 25px;
font-size: 14px;
}
.drawerBtn i {
color: #333;
height: 14px;
line-height: 14px;
width: 14px;
margin-left: 2px;
margin-bottom: 3px;
}
.downMenu {
width: 329px;
background-color: #fff;
box-shadow: 0px 1px 8px 1px rgba(212, 212, 212, 0.5);
padding-bottom: 14px;
}
.downMenu .ant-menu-item {
height: 50px;
line-height: 50px;
}
.catelogue {
cursor: pointer;
background: #FAFBFC;
border-radius: 4px;
border: 1px solid #D0D0D0;
font-size: 15px;
font-weight: normal;
margin-right: 12px;
padding: 0px 10px;
height: 30px;
line-height: 30px;
color: #666 !important;
display: flex;
align-items: center;
}
.catelogue:hover {
background-color: #F3F4F6;
}
.catelogue span {
margin-top: 1px;
}
.submoduleStyle {
cursor: default;
}
.submoduleStyle i {
cursor: default;
}
.submoduleStyle:hover {
color: #05101a;
}
.pinfos i, .pinfos a {
color: #666;
}
.pinfos:hover i, .pinfos:hover a {
color: #466AFF;
}
.graph {
flex: 1;
margin: 0px 12px;
}
.graph .ant-typography {
white-space: pre-wrap;
margin-bottom: 0px;
}
.ant-anchor-wrapper {
padding-left: 2px;
}
.ant-anchor-wrapper .ant-anchor-ink::before {
background-color: #fff;
}
/*# sourceMappingURL=Index.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["Index.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;AACA;EACE;;AAGA;EAEE;EACA;EACA;;;AAIN;AACA;EACE;EACA;;AACA;EACE;;AAGA;EACE;;AAEF;EACE;;AAGJ;EACE;;AACA;EACE;;AAGJ;EACE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;;AAIN;EACE;EACA;EACA;EACA;;AACA;EAIE;;AAHA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKN;EACE;EACA;;AACA;EACE;;AAEE;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AACA;EACE;;AAGJ;EACE;EACA;EACA;;AAIN;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AACA;EACE;;AACA;EACE;EACA;EACA;;AAEF;EACE;;AAIN;EACE;EACA;EACA;EACA;;AAEE;EACE;;AAEF;EACE;;AAIN;EACE;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEE;EACE;;AAKR;EACE;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EAWA;EACA;EACA;EACA;EACA;;AAdA;EACE;EACA;EACA;EACA;AAAsB;EACtB;AAA2B;EAC3B;AAAuB;EACvB;AAAyB;EACzB;;AAOF;EACE;EACA;EACA;EACA;;AASJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;;AAIN;EACE;EACA;EACA;;AAEE;EAAE;;AACF;EACE;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAGJ;EACE;;;AAKR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACE;EACA;EACA;EACA;;AACA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;;;AAGJ;EACE;;AACA;EACE;;AAEF;EACE;;;AAIF;EAAI;;AACJ;EACE;;;AAGJ;EACE;EACA;;AACA;EACE;EACA;;;AAGJ;EACE;;AACA;EACE","file":"Index.css"}

View File

@ -1,9 +1,12 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Menu, Input , Spin, Pagination , Popover , Select } from 'antd';
import { getUrl } from 'educoder';
import Slider from "react-slick";
import { getImageUrl } from 'educoder';
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import '../css/index.scss'
import './list.css';
import './list.scss';
import './Index.scss';
import ListItem from './IndexItem'
import axios from 'axios';
@ -30,6 +33,8 @@ class Index extends Component {
categoryList: undefined,
recommendList:undefined,
recommendOriList:undefined,
languageList:undefined,
languageId:undefined
}
@ -47,6 +52,8 @@ class Index extends Component {
this.getRecommand();
this.getLanguage();
// this.getRecommandOri();
}
// 获取语言列表
@ -72,6 +79,17 @@ class Index extends Component {
}).catch(error=>{})
}
getRecommandOri=()=>{
const url = `/organizations/recommend.json`;
axios.get(url).then(result=>{
if(result){
this.setState({
recommendOriList:result.data.organizations
})
}
}).catch(error=>{})
}
// 获取列表
getListData = (page, limit, search, sort, project_type, category_id,languageId) => {
const { current_user } = this.props;
@ -256,22 +274,56 @@ class Index extends Component {
const { current_user } = this.props;
const { projectsList , recommendList , languageList , languageId ,
isSpin, total, search, limit, page, typeList, categoryList } = this.state;
isSpin, total, search, limit, page, typeList, categoryList , recommendOriList } = this.state;
const setting={
dots: true,
infinite: true,
speed: 500,
slidesToShow: 5,
slidesToScroll: 5,
autoplay:false,
arrows:false,
adaptiveHeight:true
}
const settings={
dots: true,
infinite: true,
speed: 500,
slidesToShow: 6,
slidesToScroll: 6,
autoplay:false,
arrows:false,
adaptiveHeight:true
}
return (
<div>
<p className="t_project_banner">
<img src={banner} width="100%" alt=""/>
</p>
{/* {
recommendOriList && recommendOriList.length>0?
<Slider {...settings} className="recommandOri">
{
recommendOriList.map((i,k)=>{
return(
<li><Link to={''}><img src={getImageUrl(`/${i.avatar_url}`)} alt={i.name} title={i.name} width="80px"/></Link></li>
)
})
}
</Slider>
:""
} */}
{
recommendList && recommendList.length>0 &&
<div className="recommandProjects">
<Slider {...setting} className={recommendList.length>5 ? "recommandProjects":"recommandProjects mb20"}>
{
recommendList.map((item,key)=>{
return(
<div onClick={()=>this.getoDetail(item.author && item.author.login,item.identifier)}>
<div className="items" onClick={()=>this.getoDetail(item.author && item.author.login,item.identifier)}>
<div className="mainInfo">
<img src={getUrl(`/images/${item.author && item.author.image_url}`)} alt=""/>
<img src={getImageUrl(`/${item.author && item.author.image_url}`)} width="50px" height="50px"alt=""/>
<p className="school">{item.name}</p>
<p className="name">{item.author && item.author.name}</p>
</div>
@ -283,9 +335,8 @@ class Index extends Component {
)
})
}
</div>
</Slider>
}
<div className="ProjectListIndex">
<div className="list-left">
<ul className="list-l-Menu">

View File

@ -1,24 +1,74 @@
/* recommandProjects */
.recommandProjects{
.recommandOri.slick-slider{
width: 1300px;
margin:20px auto 40px;
.slick-track{
margin-left: 0px;
}
.slick-slide{
li > a{
display: flex;
max-width: 1200px;
margin:20px auto;
}
.recommandProjects >div{
background-color: #fff;
border-radius: 10px;
width: 220px;
margin-right: 25px;
cursor: pointer;
border: 1px solid #eee;
&:last-child{
margin-right: 0px;
align-items: center;
justify-content: center;
}
}
}
.recommandProjects > div:hover{
/* recommandProjects */
.recommandProjects.slick-slider{
width: 1230px;
margin:20px auto 40px;
.slick-track{
margin-left: 0px;
}
.slick-arrow.slick-prev,.slick-arrow.slick-next{
&:before{
color: #999;
}
li.slick-active button:before{
color: #999;
}
}
.slick-dots{
bottom: -29px;
li button:before{
color: #909090;
}
}
.slick-slide{
padding:0px 15px;
box-sizing: border-box;
& > div{
background-color: #fff;
border-radius: 10px;
width: 100%;
cursor: pointer;
border: 1px solid #eee;
&:hover{
box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, 0.1);
}
.recommandProjects > div .mainInfo{
}
}
}
.baseInfo{
padding:18px 15px;
display: flex;
font-size: 12px;
color:#888;
.look{
i{
margin-right: 5px;
}
margin-right: 10px;
}
.type{
flex:1;
width:0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: right;
}
}
.mainInfo{
display: flex;
flex-direction: column;
align-items: center;
@ -50,43 +100,47 @@
text-overflow: ellipsis;
max-width:100%;
}
}
.recommandProjects{
.baseInfo{
padding:18px 15px;
display: flex;
font-size: 12px;
color:#888;
.look{
i{
margin-right: 5px;
}
margin-right: 10px;
}
.type{
flex:1;
width:0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: right;
}
}
}
// coderDepot
.Panels{
max-width: 1200px;
margin: 0 auto;
.panelmenu{
padding-top:30px;
.depotBtn{
.mr-5{
margin-right: -5px;
}
.ant-btn{
height: 36px;
line-height: 34px;
width: 83px;
text-align: center;
padding:0px ;
font-weight: 500;
font-size: 14px;
}
.ant-btn-default{
color: #333;
border-color: #d0d0d0;
&:hover{
background: #F3F4F6;
}
}
.ant-btn-primary{
color: #fff;
background-color: #466AFF;
opacity: 0.8;
}
}
}
.addOptionBtn{
height: 32px;
line-height: 32px;
line-height: 30px;
display: flex;
border:1px solid #d9d9d9;
border-radius: 4px;
border-radius: 2px;
a{
padding:0px 13px;
color: rgba(0, 0, 0, 0.65);
@ -95,28 +149,33 @@
& > a:first-child{
border-right: 1px solid #d9d9d9;
}
& > a:last-child{
border-right: none;
}
}
.infoCount{
display: inline-block;
padding:0px 5px;
height: 16px;
line-height: 16px;
background-color: #eee;
color:#999;
width: 24px;
text-align: center;
height: 24px;
line-height: 24px;
background-color:rgba(153, 153, 153, 0.13);;
color:#666;
border-radius: 12px;
margin-left: 10px;
margin-left: 6px;
font-size: 12px;
}
.attrPerson{
padding-top: 15px;
padding-top: 12px;
display: flex;
flex-wrap: wrap;
padding-bottom: 2px;
a{
margin: 10px 10px 0px 0px;
margin: 0px 17px 0px 0px;
img{
border-radius: 50%;
width: 35px;
height: 35px;
width: 40px;
height: 40px;
}
&:nth-child(6){
margin-right: 0px;
@ -129,9 +188,7 @@
height: 7px;
margin-top: 12px;
span{
border-left: 1px solid #fff;
&:first-child{
border-left: none;
border-radius: 10px 0px 0px 10px;
}
&:last-child{
@ -155,10 +212,11 @@
padding-left: 15px;
position: relative;
min-width: 33.5%;
span{
font-size: 12px;
font-weight: 400;
color: #666;
span{
&:last-child{
color: #999;
margin-left: 5px;
}
}
@ -166,68 +224,85 @@
}
.listtable{
margin-top: 20px;
border:1px solid #d9d9d9;
border-radius: 4px;
.listtablehead{
height: 55px;
display: flex;
justify-content: space-between;
align-items: flex-start;
border-bottom: 1px solid #d9d9d9;
padding:7px 20px;
padding:13px 20px;
border-radius: 4px 4px 0px 0px;
background-color: #FAFBFC;
border: 1px solid rgba(42, 97, 255, 0.23);
background-color: #FAFCFF;
.ellipsistxt{
margin-top: 6px;
#ptxt{
margin-bottom: 0px;
word-break: break-all;
overflow: unset;
white-space:pre-wrap; /* css3.0 */
white-space:-moz-pre-wrap; /* Firefox */
white-space:-pre-wrap; /* Opera 4-6 */
white-space:-o-pre-wrap; /* Opera 7 */
word-wrap:break-word;
}
margin-left: 13px;
line-height:18px;
margin-top:6px;
flex:1;
width: 0;
color: #666;
&>p{
word-break:break-all;
}
&.hide{
&.hidetxt{
height: 18px;
overflow: hidden;
position: relative;
padding-right:8px;
}
&.hide::after{
position: absolute;
right: 0px;
bottom: 0px;
content:"...";
// &::after{
// position: absolute;
// right: 0px;
// bottom: 0px;
// content:"...";
// }
}
}
.ellipsis{
margin-left: 8px;
cursor: pointer;
border-radius: 2px;
background-color: #c1c1c1;
height: 16px;
background: rgba(153, 153, 153, 0.2);
border-radius: 2px;
padding:0px 4px;
height: 14px;
line-height: 14px;
margin-top: 9px;
i{
font-size: 15px!important;
color: #fff;
color: #333;
height: 14px;
line-height: 14px;
}
}
}
.listtablebody{
border-radius:0px 0px 4px 4px ;
border: 1px solid #D0D0D0;
border-top: none;
li.listtablepath{
a{color: #40a9ff;}
p{
margin-bottom: 0px!important;
}
li{
height: 42px;
}
& > li{
height: 38px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #d9d9d9;
padding:0px 20px 0px 24px;
&:hover{
background-color: #F3F4F6;
}
& > span:first-child{
width: 30%;
overflow: hidden;
@ -254,23 +329,96 @@
.drawerBtn{
position: fixed;
left: -13px;
border:1px solid #d9d9d9;
width: 34px;
width: 33px;
background: #FFFFFF;
box-shadow: 0px 0px 8px 3px rgba(0, 0, 0, 0.09);
border: 1px solid #666666;
border-radius: 0px 12px 12px 0px;
text-align: right;
height: 70px;
line-height: 70px;
top:50%;
margin-top: -35px;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-left: 7px;
&:hover{
box-shadow: 1px 0px 7px rgba(0,0,0,0.1);
box-shadow: 0px 0px 8px 3px rgba(0, 0, 0, 0.09);
}
span{
writing-mode: vertical-lr;
color: #333;
width: 25px;
font-size: 14px;
}
i{
color: #d9d9d9;
color: #333;
height: 14px;
line-height: 14px;
width: 14px;
margin-left: 2px;
margin-bottom: 3px;
}
}
.downMenu{
box-shadow: 0px 0px 9px rgba(134, 134, 134,0.4);
width: 329px;
background-color: #fff;
box-shadow: 0px 1px 8px 1px rgba(212, 212, 212, 0.5);
padding-bottom: 14px;
.ant-menu-item{
height: 50px;
line-height: 50px;
}
}
.catelogue{
cursor: pointer;
background: #FAFBFC;
border-radius: 4px;
border: 1px solid #D0D0D0;
font-size: 15px;
font-weight: normal;
margin-right: 12px;
padding:0px 10px;
height: 30px;
line-height: 30px;
color: #666!important;
display: flex;
align-items: center;
&:hover{
background-color: #F3F4F6;
}
span{
margin-top: 1px;
}
}
.submoduleStyle{
cursor: default;
i{
cursor: default;
}
&:hover{
color: #05101a;
}
}
.pinfos{
i,a{color: #666;}
&:hover i,&:hover a{
color: #466AFF;
}
}
.graph{
flex:1;
margin:0px 12px;
.ant-typography{
white-space: pre-wrap;
margin-bottom: 0px;
}
}
.ant-anchor-wrapper{
padding-left: 2px;
.ant-anchor-ink::before{
background-color: #fff;
}
}

View File

@ -1,10 +1,11 @@
import React, { Component } from 'react';
import { Tooltip } from 'antd';
import { getImageUrl } from 'educoder';
import { AlignCenter } from '../Component/layout';
import { Link } from 'react-router-dom';
import '../css/index.scss';
import Nodata from '../Nodata';
import './list.css';
import './list.scss';
import img_parise from '../Images/parise.png';
class IndexItem extends Component {
@ -17,7 +18,7 @@ class IndexItem extends Component {
render() {
const { projects } = this.props;
return (
<div className="project-list minH-670">
<div className="project-list minH-670" style={{padding:"0px 20px"}}>
{ projects && projects.length > 0 ? projects.map((item, key) => {
return (
<div className="p-r-Item" key={key}>
@ -27,14 +28,17 @@ class IndexItem extends Component {
<img className="p-r-photo" alt="" src={item.author && item.author.image_url} ></img>
</a>
:
<Link to={`/users/${item.author.login}`} className="show-user-link">
<img className="p-r-photo" alt="" src={getImageUrl(`${item.author && item.author.image_url}`)} ></img>
<Link to={item.author && (item.author.type === "Organization" ? `/organize/${item.author.login}`:`/users/${item.author.login}`)} className="show-user-link">
<img className="p-r-photo" alt="" src={getImageUrl(`/${item.author && item.author.image_url}`)} ></img>
</Link>
}
<div className="p-r-Infos">
<div className="p-r-name">
<Link to={`/projects/${item.author.login}/${item.identifier}`} className="hide-1 color-grey-3 font-18 task-hide " style={{ whiteSpace: "wrap", display: 'flex', width: 400 }}>
<AlignCenter>
<Link to={`/projects/${item.author.login}/${item.identifier}`} title={`${item.author.name}/${item.name}`} className="color-grey-3 font-18 task-hide " style={{maxWidth: 470 }}>
{item.author.name}/{item.name}
</Link>
{ !item.is_public && <span className="privateTag">私有</span> }
{
item.forked_from_project_id ?
<span className="ml5">
@ -43,27 +47,37 @@ class IndexItem extends Component {
: ""
}
{
item.type && item.type !== 0 ?
item.type === 2 ?
item.type && item.type === 2 ?
<Tooltip title="该项目是一个镜像" className="ml5">
<i className="iconfont icon-banbenku font-18 color-green" />
</Tooltip>:
</Tooltip>:""
}
{
item.type && item.type === 1 ?
<span className="ml5">
<i className="iconfont icon-jingxiang font-18 color-green" />
</span>:""
}
</Link>
</AlignCenter>
<span className="p-r-tags">
<span className="pariseTag"><img src={img_parise} alt="" className="pariseImg" /> {item.praises_count}</span>
<span><i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork {item.forked_count}</span>
{
item.praises_count && item.praises_count>0 ?
<span className="pariseTag">
<img src={img_parise} alt="" className="pariseImg" /> {item.praises_count}
</span>:""
}
{
item.forked_count && item.forked_count>0 ?
<span>
<i className="iconfont icon-fork mr3 font-16" style={{ color: "#1B8FFF" }} />fork {item.forked_count}
</span>:""
}
</span>
</div>
<p className="break_word task-hide-2 mt10" style={{ maxHeight: "44px",lineHeight:"22px" }}>{item.description}</p>
<div className="p-r-about">
<span className="p-r-detail">
{/* <span><label>浏览量:</label>{item.visits}</span> */}
{/* {item.category && item.category.id && <span>{item.category.name}</span>} */}
{item.last_update_time ? <span><label>更新于</label>{item.time_ago}</span> : ""}
{item.language && item.language.id ? <span className="color-grey-3">{item.language.name}</span> : ""}
</span>

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import "../Branch/branch.css"
import "../Branch/branch.scss"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["list.scss"],"names":[],"mappings":";AACA;EAAQ;;;AACR;AACE;AAAA;EAEA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;AACA;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EAAsC;;;AACtC;EAAwC;;;AACxC;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIF;AACA;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;AACA;EACE;EACA;;;AAEF;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;;AAIN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;EACA;EACA;;AACA;EACE;;AAEF;EACE;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACE;;;AAEF;EACE;;;AAEF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EAAkB;EAAmB;;;AACrC;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;AACA;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;AACE;EACA;;;AAEF;EACE;;;AAKF;EACE;IACE;;;EAEF;IACE;IACA;;;AAIJ;EACE;IACE;;;EAEF;IACE;IACA;;;EAEF;IACE;;;EAEF;IACE;IACA;;;EAEF;IACE;;;EAEF;IACE;;;AAGJ;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;AAAoB;EACpB;EACA;EACA;EACA;EACA;;;AAEF;EACE;;AACA;EACE;EACA;EACA;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAGA;EACE;;;AAGJ;EACE;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;EAEF;IACE;;;EAEF;IACE;;;EAEF;IACE;;;AAGJ;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACA;;;AAEA;EAAc;;;AAEd;EACE;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EAAa;;;AACb;EACE;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EAAY;;;AAEZ;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAIF;AACA;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;AACA;EACE;;AAEF;EACE","file":"list.css"}

783
src/forge/Main/list.scss Normal file
View File

@ -0,0 +1,783 @@
.lineH2{line-height:2}
.t_project_banner {
/* height: 260px;
background: url(../Images/banner_list.jpg) no-repeat center; */
background-color: #050d34;
}
.ProjectListIndex{
width: 1200px;
margin:20px auto;
display: flex;
align-items: flex-start;
flex-wrap:wrap;
}
.list-left{
width: 26%;
padding-right: 20px;
box-sizing: border-box;
margin-bottom: 20px;
}
.list-left > div{
border:1px solid #eee;
}
.list-left > div.bgcF{
border:none;
}
.list-right{
width:74%;
background: #fff;
padding:10px;
border:1px solid #eee;
}
/* 首页列表的新建和排序的下拉列表 */
.ant-menu-inline, .ant-menu-vertical, .ant-menu-vertical-left{
border-right: none!important;
}
.ant-menu-vertical > .ant-menu-item{
margin:0px!important;
height: 35px;
line-height: 35px;
border-bottom: 1px solid #eee;
font-size: 14px!important;
}
.ant-menu-vertical > .ant-menu-item:last-child{
border-bottom: none;
}
.list-r-operation{
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
padding:25px 30px;
border-bottom: 1px solid #E0E0E0;
}
.list-r-Search{
width: 400px;
}
.padding0-25{
padding:0px 25px;
}
.list-r-Search .ant-btn-lg{
height: 38px;
}
.list-r-Search .ant-input-group-addon{border: none !important;}
.list-r-Search .ant-input-search-button{height: 40px !important;}
.createBtn{
border-radius: 4px;
margin-left: 20px;
display: inline-block;
padding:3px 15px;
background-color: #4CACFF;
color: #fff!important;
}
/* 列表 */
.project-list{
padding:0px 30px;
}
.border-top-grey{
border-top: 1px solid rgba(238,238,238,1);
}
.p-r-Item:last-child{
border-bottom: none !important;
}
.p-r-Item{
display: flex;
border-bottom:1px solid rgba(238,238,238,1);
padding:22px 0px;
justify-content: flex-start;
}
.boxShandow{
box-shadow:0px 2px 20px 10px rgba(0,0,0,0.03);
}
.p-r-photo{
width: 60px;
height: 60px;
border-radius: 50%;
margin-right: 22px;
margin-top: 8px;
}
.p-r-Infos{
flex: 1;
width: 0;
}
.p-r-name{
display: flex;
justify-content: space-between;
align-items: center;
}
.p-r-name > p{
flex: 1;
width: 0;
}
.p-r-btn{
display: flex;
align-items: center;
}
.p-r-btn > span{
height: 35px;
line-height: 35px;
border:1px solid #f4f4f4;
border-radius: 5px;
display: block;
margin-left: 20px;
background-color: #fff;
display: flex;
}
.p-r-btn > span > a{
display: flex;
align-items: center;
padding:0px 12px;
background:#ececec;
}
.p-r-btn > span > a:active{
background: #f4f4f4;
}
.p-r-btn > span > span{
padding:0px 8px;
}
.p-r-tags{
display: flex;
opacity: 1;
}
.p-r-tags.large > span{
height: 30px;
line-height: 30px;
font-size: 14px;
}
.p-r-tags > span{
margin-left: 15px;
padding:0px 10px;
border-radius:15px;
background: #EBF4FE;
color: #333;
height: 24px;
line-height: 24px;
display: block;
font-size: 12px;
display: flex;
}
.p-r-tags > span.pariseTag{
background: #FFF3DC;
}
.p-r-tags.large > span >label{
padding:0px 12px;
}
.p-r-tags > span >label{
padding:0px 8px;
}
.p-r-tags.large > span >span{
padding:0px 6px;
}
.pariseImg{
width: 14px;
height: 12px;
margin-top: 6px;
margin-right: 3px;
}
.p-r-tags > span >span{
display: block;
background: #fff;
border-left: #efefef;
padding:0px 4px;
border-radius: 0px 4px 4px 0px;
color: #999;
}
.p-r-content{
margin-top:10px;
color: #666;
display: flex;
}
.p-r-detail > span{
margin-right: 22px;
color: #888;
}
.p-r-detail > span > label{
color: #999;
}
.p-r-about{
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
margin-top: 8px;
color: #666;
}
.spincontent{
height:400px;
}
.spinstyle .ant-spin-text{
margin-top:30px;
color: #888;
}
/* -----------详情------------ */
.detailHeader-wrapper{
background-color:#FBFCFF;
border-bottom:1px solid #e2e2e2;
}
.headerMenu-wrapper{
display: flex;
flex-direction: row;
cursor: pointer;
li{
position: relative;
text-align: center;
padding:0px;
& > a{
font-size: 14px;
height: 40px;
line-height: 28px;
padding:0px 20px;
display: block;
color: #666;
&> img{
margin-right: 8px;
}
&> span.num{
line-height: 24px;
margin-left: 5px;
margin-top: 2px;
font-size: 12px;
float: right;
color: #666!important;
background-color: rgba(153, 153, 153, 0.13);;
border-radius: 50%;
width: 24px;
height: 24px;
}
}
&.active a,&.active a i{
color: #466AFF!important;
}
&.active::after,&:hover::after{
position: absolute;
bottom:0px;
height:2px;
background-color:rgba(153, 153, 153, 0.2);
content:'';
left: 0px;
width:100%;
}
&.active::after{
background-color: #466AFF;
}
}
}
.detail_tag_btn{
height:34px;
line-height: 32px;
border-radius:5px;
border:1px solid #D0D0D0;
display: flex;
align-items: center;
margin-left: 10px;
padding:0px;
background-color:#FAFBFC;
box-shadow: none;
&:hover{
background-color: #F3F4F6;
}
.detail_tag_btn_name{
padding:0px 18px;
min-width: 82px;
text-align: center;
&:hover>span{
color: #333!important;
}
img{
margin-right: 10px;
}
}
.detail_tag_btn_count{
width: 42px;
text-align: center;
background: #fff;
border-radius: 0px 4px 4px 0px;
height:100%;
border-left: 1px solid #D0D0D0;
}
}
.ant-tooltip {
max-width: fit-content!important;
}
.files-md{
padding:20px;
}
/* 详情-代码 */
.branch-wrapper{
border:1px solid #eee;
border-radius: 4px;
display: flex;
align-items: center;
height: 60px;
padding:0px 30px;
width: 1200px;
margin:0px auto;
background-color: #fff;
margin-top: 20px;
justify-content: space-between;
}
.branch-wrapper > a >i{
color: #5091FF;
margin-right: 5px;
cursor: default;
}
.branch-wrapper a{
display: flex;
align-items: center;
justify-content: center;
text-align: center;
height: 30px;
line-height: 30px;
cursor: pointer;
font-size: 16px;
color: #333333;
}
.branch-wrapper a > span{
position: relative;
min-height: 20px;
display: block;
}
.branch-wrapper a.active > span::after{
position: absolute;
content: '';
bottom: -5px;
width: 30px;
height: 3px;
left: 0px;
background-color:#5091FF;
}
.gitAddressClone{
margin:0px 20px 14px 20px!important;
display: flex;
height: 40px;
align-items: center;
border-radius: 4px;
border:1px solid #eee;
background: #fff;
margin-left: 20px;
position: relative;
}
.gitAddressClone > span{
display: flex;
line-height: 40px;
height: 40px;
padding:0px 12px;
cursor: pointer;
align-items: center;
}
.addressTips{
position: absolute;
font-size: 12px;
color: #FF6E21;
top:-34px;
left: 30px;
background-color: #fff;
border:1px solid #FE881D;
padding:0px 5px;
height: 28px;
line-height: 28px;
}
.addressTips>span{position: relative;display: block;}
.addressTips>span::before{
box-sizing: content-box;
width: 0px;
height: 0px;
position: absolute;
top: 25px;
left:50%;
margin-left: -4px;
padding:0;
border-top:8px solid #FFFFFF;
border-bottom:8px solid transparent;
border-left:8px solid transparent;
border-right:8px solid transparent;
display: block;
content:'';
z-index: 12;
}
.addressTips>span::after{
box-sizing: content-box;
width: 0px;
height: 0px;
position: absolute;
top: 26px;
left:50%;
margin-left: -4px;
padding:0;
border-top:8px solid #FE881D;
border-bottom:8px solid transparent;
border-left:8px solid transparent;
border-right:8px solid transparent;
display: block;
content:'';
z-index: 11;
}
.gitAddressClone > span.addressType{
color: #4CACFF;
}
.gitAddressClone > span:last-child{
border-right: none;
}
.gitAddressClone > input{
border:none;
outline: none;
padding:0px 8px;
height: 40px;
line-height: 40px;
border-radius: 0px;
border: 1px solid #eee;
flex:1;
}
.wrap-commit-table .ant-table-small > .ant-table-content > .ant-table-body{
margin:0px;
}
.wrap-commit-table .ant-table-title{
background-color: rgba(241,248,255,1);
padding: 13px 16px!important;
}
.commitKey{
cursor: pointer;
border:1px solid #FD7700;
background-color:#FFF3DC;
color: #FD7700!important;
padding:0px 12px;
height: 20px;
line-height: 20px;
margin-left:15px;
border-radius: 18px;
max-width: 100%;
}
/* 分支 */
.branchTitle{
padding:8px 10px;
color: #333;
font-size: 16px;
border-bottom: 1px solid #d9d9d9;
}
.branchUl li{
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: space-between;
padding:20px 0px;
border-bottom: 1px solid #eee;
}
.branchUl li:last-child{
border-bottom: none;
}
.operationBtn{
border:1px solid #f4f4f4;
border-radius: 3px;
padding:0px 6px;
background-color:#fff;
color:#666!important;
display: inline-block;
}
.messages{
max-width: 700px;
}
.leftPoint{
margin-left: 20px;
position: relative;
}
.leftPoint::before{
position: absolute;
left: -10px;
top:8px;
border-radius: 50%;
width: 4px;
height: 4px;
background-color: #dadada;
content: '';
}
/* 文件目录、文件内容 */
.subFileName{
position: relative;
margin-left: 15px;
height: 22px;
}
.subFileName::before{
position: absolute;
content: '/';
left: -10px;
top: 0px;
color: #999;
height: 22px;
line-height: 22px;
}
.addFile{
display: flex;
}
.addFile a{
display: block;
background-color: rgba(76, 172, 255,0.8);
color: #fff;
cursor: pointer;
height: 32px;
line-height: 32px;
padding: 0px 10px;
}
.addFile a:first-child{
border-radius: 4px;
}
.addFile a:last-child{
/* border-radius: 0px 4px 4px 0px; */
border-left: 1px solid rgba(247, 247, 247, 0.3);
}
.addFile a:active{
background-color: rgba(76, 172, 255,1);
}
@media screen and (max-width: 750px){
.list-r-Search{
flex: 1;
}
.list-left,.list-right{
width: 100%;
padding: 0px;
}
}
@media screen and (max-width: 400px){
.list-r-Search{
width: 100%;
}
.headerMenu-wrapper{
flex-direction: column;
width: 100%;
}
.headerMenu-wrapper li{
width: 100%;
}
.gitAddressClone{
width:100%;
margin-left: 0px;
}
.gitAddressClone > span{
padding:0px;
}
.messages{
max-width: 100%;
}
}
.commonBox{
border:1px solid #ddd;
margin-top: 30px;
border-radius: 4px;
}
.commonBox .commonBox-title{
padding:0px 20px;
box-sizing: border-box;
font-size: 16px;
background: #FAFBFC;/* F1F8FF */
font-weight: bold;
height: 45px;
line-height: 45px;
border-bottom: 1px solid #d9d9d9;
border-radius: 4px 4px 0px 0px;
}
.readBox{
border:none;
&.commonBox .commonBox-info{
border:1px solid #D0D0D0;
border-top: none;
border-radius: 0px 0px 4px 4px;
padding:20px 38px;
}
}
.commonBox .commonBox-title.boxTitle{
display: flex;
justify-content: space-between;
height: 55px;
line-height: 55px;
background: #FAFCFF;
border-radius: 4px 4px 0px 0px;
border: 1px solid rgba(42, 97, 255, 0.23);
}
.synchronism{
display: block;
height: 34px;
line-height: 34px;
padding:0px 15px;
color: #fff!important;
background-color: #28BD6C;
border-radius: 4px;
}
.files_info{
cursor: pointer;
}
.commonBox {
.commonBox-info{
padding:20px 15px;
}
}
.commonBox-title-read{
vertical-align: middle;
color: #000;
font-size: 14px;
}
@media screen and (max-width: 370px){
.p-r-tags,.p-r-btn{
opacity: 0;
display: none;
}
.p-r-about{
flex-wrap: wrap;
}
.commitKey{
margin-right: 0px;
}
.list-r-Search{
width: 100%;
}
}
.null_data_box{
width: 100%;
border: 1px solid #d4d4d5;
border-radius:3px ;
}
.title{
font-weight: bold;
background: #f4f4f4;
padding: 10px 15px;
box-sizing: border-box;
border-bottom: 1px solid #d4d4d5;
}
.item_title{
font-size:18px;
font-weight: bold;
margin-bottom: 15px;
}
.item{
padding: 15px;
border-bottom: 1px solid #dededf;
}
.item:last-child{
border-bottom:none;
}
.item_title small{
font-weight: 400;
margin-left: 10px;
}
.item_title small a{
color: #4183c6;
}
.Markdown{
background: #f7f7f7;
padding: 10px 20px;
}
.item .gitAddressClone input:focus{
border: 1px solid #2185d0;
}
.content-file{margin-top: 8px;}
.content-file .CodeMirror{
background-color: #f7f7f7;
border: 1px solid #e4e4e4;
border-radius: 4px;
height: auto;
}
.content-file.edit .CodeMirror{
background-color: #fff;
}
.content-file .CodeMirror .CodeMirror-scroll{
min-height: 450px;
}
.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;}
.commitList{
padding:0px 30px;
min-height: 400px;
}
.commitList > div{
border-bottom: 1px solid #EEEEEE;
padding:16px 0px;
}
.commitList > div:last-child{
border-bottom: none;
}
/* 标签列表 */
.div_table{
border:1px solid #eee;
border-radius: 2px;
}
.ul_thead{
padding:0px 30px;
box-sizing: border-box;
background: #FAFAFA;
border-bottom: 1px solid #eee;
height: 50px;
line-height: 50px;
}
.ul_tbody{
padding:0px 30px;
}
.ul_thead li, .ul_tbody li{
display: flex;
align-items: center;
text-align: left
}
.ul_tbody li{
padding:18px 0px;
border-bottom: 1px solid #eee;
}
.ul_tbody li:last-child{
border-bottom: none;
}
.ul_thead li > span , .ul_tbody li > span{
width: 20%;
padding-right: 20px;
}
.ul_thead li > span:nth-child(2), .ul_tbody li > span:nth-child(2){
flex:1;
}
.ul_tbody_third{
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: left;
}
.ul_tbody_forth{
text-align: center;
display: flex;
justify-content: center;
}
.depotNum{
color: #666!important;
span:last-child{
color: #333;
}
&:hover span:last-child{
color: #2A61FF;
}
}

View File

@ -42,7 +42,7 @@ function Contribute(props){
<WhiteBack>
<Spin spinning={isSpin}>
<div className="boxPanel">
<p className="font-18 mb20">贡献者列表</p>
<p className="font-18 padding10-20" style={{borderBottom:"1px solid #eee"}}>贡献者列表</p>
{
list && list.length > 0 ?
<div className="contrbuteList">
@ -50,7 +50,7 @@ function Contribute(props){
list.map((item,key)=>{
return(
<AlignCenter>
<img alt="" style={{borderRadius:"50%",marginRight:"10px"}} src={getImageUrl(`images/${item.image_url}`)} width="50px" height="50px"/>
<img alt="" style={{borderRadius:"50%",marginRight:"10px"}} src={getImageUrl(`/${item.image_url}`)} width="50px" height="50px"/>
<div>
<Link to={`/users/${item.login}`} className="font-16">{item.name}</Link>
<p className="font-12 color-grey-9">提交{item.contributions}</p>

View File

@ -1,28 +1,36 @@
import React, { useEffect, useState } from 'react';
import { Skeleton } from 'antd';
import { Skeleton , Tooltip} from 'antd';
import { Link } from 'react-router-dom';
import { numFormat } from 'educoder';
function DetailBanner({ list , owner , projectsId , isManager , url , pathname , state , urlFlag , projectDetail , platform ,open_devops }){
function DetailBanner({ history,list , owner , projectsId , isManager , url , pathname , state , urlFlag , projectDetail , platform ,open_devops }){
const [ menuName , setMenuName ] = useState(undefined);
useEffect(()=>{
if(list){
// banner
if(pathname && pathname==="source"){
let a = list.filter(item=>item.menu_name === "resources");
if(a && a.length === 0){
history.push(`/projects/${owner}/${projectsId}`);
}
}
setMenuName(list);
}
},[list]);
return(
<div className="f-wrap-between mt15">
<div className="f-wrap-between mt25">
{
menuName && projectDetail ?
<ul className="headerMenu-wrapper">
{
menuName.map((item,key)=>{
Array.isArray(menuName)&& menuName.map((item,key)=>{
return(
<React.Fragment>
<React.Fragment key={item.menu_name}>
{
item.menu_name === "home" &&
<li className={pathname==="about" ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}/about`, state }}>
<i className={(pathname==="" || urlFlag) ? "iconfont icon-zhuye1 color-grey-3 mr5 font-14":"iconfont icon-zhuye1 color-grey-6 font-14 mr5"}></i>
<i className={(pathname==="" || urlFlag) ? "iconfont icon-zhuyeicon color-grey-3 mr5 font-14":"iconfont icon-zhuyeicon color-grey-6 font-14 mr5"}></i>
<span>主页</span>
</Link>
</li>
@ -31,7 +39,7 @@ function DetailBanner({ list , owner , projectsId , isManager , url , pathname ,
item.menu_name === "code" &&
<li className={(pathname==="" || urlFlag) ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}`, state }}>
<i className={(pathname==="" || urlFlag) ? "iconfont icon-daimaku color-grey-3 mr5 font-14":"iconfont icon-daimaku color-grey-6 font-14 mr5"}></i>
<i className={(pathname==="" || urlFlag) ? "iconfont icon-daimakuicon color-grey-3 mr5 font-14":"iconfont icon-daimakuicon color-grey-6 font-14 mr5"}></i>
<span>代码库</span>
</Link>
</li>
@ -39,50 +47,61 @@ function DetailBanner({ list , owner , projectsId , isManager , url , pathname ,
{
item.menu_name === "issues" &&
<li className={pathname==="issues" ? "active" : ""}>
<Tooltip title="易修是Issue的中文名即问题列表" placement="bottom">
<Link to={{ pathname: `/projects/${owner}/${projectsId}/issues`, state }}>
<i className={pathname==="issues" ? "iconfont icon-renwu color-grey-3 mr5 font-14":"iconfont icon-renwu color-grey-6 font-14 mr5"}></i>
<span>易修 (Issue)</span>
{projectDetail && projectDetail.issues_count ? <span className="num">{projectDetail.issues_count}</span> : ""}
<i className={pathname==="issues" ? "iconfont icon-yixiuicon color-grey-3 mr5 font-14":"iconfont icon-yixiuicon color-grey-6 font-14 mr5"}></i>
<span>易修</span>
{projectDetail && projectDetail.issues_count ? <span className="num">{numFormat(projectDetail.issues_count)}</span> : ""}
</Link>
</Tooltip>
</li>
}
{
item.menu_name === "pulls" && projectDetail && parseInt(projectDetail.type) !== 2 && platform ?
<li className={pathname==="pulls" ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}/pulls`, state }}>
<i className={pathname==="pulls" ? "iconfont icon-hebingqingqiu1 color-grey-3 mr5 font-14":"iconfont icon-hebingqingqiu1 color-grey-6 font-14 mr5"}></i>
<i className={pathname==="pulls" ? "iconfont icon-hebingqingqiuicon color-grey-3 mr5 font-14":"iconfont icon-hebingqingqiuicon color-grey-6 font-14 mr5"}></i>
<span>合并请求</span>
{projectDetail && projectDetail.pull_requests_count ? <span className="num">{projectDetail.pull_requests_count}</span> : ""}
{projectDetail && projectDetail.pull_requests_count ? <span className="num">{numFormat(projectDetail.pull_requests_count)}</span> : ""}
</Link>
</li>:""
}
{
item.menu_name === "wiki" &&
<li className={pathname === "wiki" ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}/wiki`, state }}>
<i className={pathname==="wiki" ? "iconfont icon-wiki_icon color-grey-3 mr5 font-14":"iconfont icon-wiki_icon color-grey-6 font-14 mr5"}></i>
<span>Wiki</span>
</Link>
</li>
}
{
item.menu_name === "devops" && platform ?
<li className={pathname==="devops" ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}/devops${open_devops ? `/dispose`:""}`, state }}>
<i className="iconfont icon-gongzuoliu font-13 mr8"></i>工作流(beta版)
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
<i className="iconfont icon-gongzuoliuicon font-13 mr8"></i>工作流(beta版)
{projectDetail && projectDetail.ops_count ? <span>{numFormat(projectDetail.ops_count)}</span> : ""}
</Link>
</li>
:""
}
{
item.menu_name === "source" &&
{/* {
item.menu_name === "resources" &&
<li className={pathname==="source" ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}/source`, state }}>
<i className={pathname==="source" ? "iconfont icon-ziyuanpaihanghetuijian color-grey-3 mr5 font-14":"iconfont icon-ziyuanpaihanghetuijian color-grey-6 font-14 mr5"}></i>
<span>资源库</span>
{projectDetail && projectDetail.source_count ? <span className="num">{projectDetail.source_count}</span> :""}
{projectDetail && projectDetail.source_count ? <span className="num">{numFormat(projectDetail.source_count)}</span> :""}
</Link>
</li>
}
} */}
{
item.menu_name === "versions" &&
<li className={pathname==="milestones" ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}/milestones`, state }}>
<i className={pathname==="milestones" ? "iconfont icon-lichengbei color-grey-3 mr5 font-14":"iconfont icon-lichengbei color-grey-6 font-14 mr5"}></i>
<i className={pathname==="milestones" ? "iconfont icon-lichengbeiicon color-grey-3 mr5 font-14":"iconfont icon-lichengbeiicon color-grey-6 font-14 mr5"}></i>
<span>里程碑</span>
{projectDetail && projectDetail.versions_count ? <span className="num">{projectDetail.versions_count}</span> :""}
{projectDetail && projectDetail.versions_count ? <span className="num">{numFormat(projectDetail.versions_count)}</span> :""}
</Link>
</li>
}
@ -90,24 +109,24 @@ function DetailBanner({ list , owner , projectsId , isManager , url , pathname ,
item.menu_name === "activity" &&
<li className={pathname==="activity" ? "active" : ""}>
<Link to={{ pathname: `/projects/${owner}/${projectsId}/activity`, state }}>
<i className={pathname==="activity" ? "iconfont icon-tongzhi color-grey-3 mr5 font-14":"iconfont icon-tongzhi color-grey-6 font-14 mr5"}></i>
<i className={pathname==="activity" ? "iconfont icon-dongtaiicon color-grey-3 mr5 font-14":"iconfont icon-dongtaiicon color-grey-6 font-14 mr5"}></i>
<span>动态</span>
</Link>
</li>
}
{
item.menu_name === "setting" &&
<li className={pathname === "setting" ? "active" : ""}>
<Link to={`/projects/${owner}/${projectsId}/setting`}>
<i className={url && url.indexOf("/setting") > 0 ? "iconfont icon-cangkushezhiicon color-grey-3 mr5 font-14":"iconfont icon-cangkushezhiicon color-grey-6 font-14 mr5"}></i>
<span>仓库设置</span>
</Link>
</li>
}
</React.Fragment>
)
})
}
{
isManager && platform ?
<li className={pathname === "setting" ? "active" : ""}>
<Link to={`/projects/${owner}/${projectsId}/setting`}>
<i className={url && url.indexOf("/setting") > 0 ? "iconfont icon-cangku color-grey-3 mr5 font-14":"iconfont icon-cangku color-grey-6 font-14 mr5"}></i>
<span>仓库设置</span>
</Link>
</li>:""
}
</ul>
:
<Skeleton paragraph={false} active={true}/>

View File

@ -0,0 +1,28 @@
import React from 'react';
import { Tooltip , message } from 'antd';
import './sub.scss';
function Invite({code,className}) {
function jsCopy(id) {
const copyEle = document.querySelector(id); //
const range = document.createRange(); // range
window.getSelection().removeAllRanges(); //selection
range.selectNode(copyEle); //
window.getSelection().addRange(range); //
document.execCommand("Copy"); // copy
message.success('复制成功');
}
return(
<div className={className}>
<span className="font-16 color-ooo">邀请码</span>
<div>
<span id="devitecode">{code}</span>
<Tooltip title={<p className="edu-txt-center">可以通过邀请码邀请成员加入项目<br/>点击复制邀请码</p>} placement={"bottom"}>
<i className="iconfont icon-fuzhi2 font-16 color-blue ml8" onClick={()=>jsCopy("#devitecode")}></i>
</Tooltip>
</div>
</div>
)
}
export default Invite;

View File

@ -0,0 +1,57 @@
import React , { useState , useEffect } from 'react';
import { Anchor , Input } from 'antd';
import './sub.scss';
import { Base64 } from 'js-base64';
const { Link } = Anchor;
function ReadmeCatelogue({ menuList , hash }) {
const [ goHref , setGoHref ] = useState("");
const [ value , setValue ] = useState("");
const [ menu , setMenu] = useState(menuList);
function onChange(link){
setGoHref(link);
};
function changeValue(e) {
setValue(e.target.value);
if(e.target.value){
let m = menuList.filter(i=>i.text.indexOf(e.target.value)>-1);
setMenu(m);
}else{
setMenu(menuList);
}
}
return(
<div>
<div className="searchBox">
<Input
placeholder={"请输入关键字"}
value={value}
onChange={changeValue}
prefix={<i className="iconfont icon-sousuo_icon1 font-14"></i>}/>
</div>
{
menu && menu.length>0?
<div className="anchorBox">
<Anchor affix={false} onChange={onChange}>
{
menu.map((item,key)=>{
return(
<div style={{paddingLeft:`${item.level *10}px`}} className={goHref===item.href?"items active":"items"}>
<Link href={`#${item.text}`} title={item.text} />
</div>
)
})
}
</Anchor>
</div>
:""
}
</div>
)
}
export default ReadmeCatelogue;

Some files were not shown because too many files have changed in this diff Show More