From 351ea1e753b8984a42e1bcc6ec3e2e58f0f32154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E6=80=9D?= <2897217417@qq.com> Date: Thu, 9 Feb 2023 11:00:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E6=94=AF=E6=A0=87=E7=AD=BE=E6=94=B9?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/forge/Component/PublicModal/Index.jsx | 4 +- src/forge/Main/tag/Index.jsx | 144 +++++++---- src/forge/Main/tag/Index.scss | 90 +++++-- src/forge/Main/tree/Index.jsx | 282 +++++++++++++++++++++- src/forge/Main/tree/Index.scss | 103 +++++++- src/forge/Main/version/New.jsx | 10 +- src/forge/Main/version/version.scss | 5 +- src/forge/Merge/CreateMerge.js | 4 +- src/forge/Newfile/UserSubmitComponent.js | 1 + 9 files changed, 559 insertions(+), 84 deletions(-) diff --git a/src/forge/Component/PublicModal/Index.jsx b/src/forge/Component/PublicModal/Index.jsx index c12e12b18..945c32ba8 100644 --- a/src/forge/Component/PublicModal/Index.jsx +++ b/src/forge/Component/PublicModal/Index.jsx @@ -2,13 +2,13 @@ import React from 'react'; import { Modal } from 'antd'; import './Index.scss'; -function Modals({title,children,btn,onCancel,visible}) { +function Modals({title,children,btn,onCancel,visible, width}) { return( { if (projectsId) { setIsSpin(true); - const url = `/${owner}/${projectsId}/tags.json`; + const url = `/v1/${owner}/${projectsId}/tags.json`; axios.get(url, { params: { limit, @@ -44,7 +48,7 @@ function Tags(props) { } }).catch(error => { }) } - }, [owner, projectsId,page]); + }, [owner, projectsId, page, limit, reload]); const columns = [ { @@ -52,54 +56,53 @@ function Tags(props) { dataIndex: "name", key: 1, ellipsis: true, - width: "200px", + width: "240px", render: (txt, item) => { return (
- {item.name} + {item.name} +
+ { + item.tagger && + + { + item.tagger.id ? + + + + : + + + + } + + } + 最后一次提交于{item.time_ago} +
) } }, - { - title: "创建时间", - dataIndex: "time_ago", - key: 2, - ellipsis: true, - render: (txt, item) => { - return ( - - { - item.tagger && - - { - item.tagger.id ? - - - - : - - - - } - - } - 创建于{txt} - - ) - } - }, { title: "提交ID", dataIndex: "id", key: 3, ellipsis: true, + width: "240px", render: (txt, item) => { return ( - - 提交ID - {truncateCommitId(item.id)} - +
+
+ + sha + + {truncateCommitId(item.id)} + + + + +
+
) } }, @@ -116,24 +119,39 @@ function Tags(props) { title: "下载", dataIndex: "stage_type", key: 5, - ellipsis: true, align: "center", - width: "204px", + width: "460px", render: (txt, item) => { return ( - + TAR - + ZIP + {item.has_release ? 创建发行版 : 创建发行版} + {item.has_release ? : } ) } } ] + // 删除标签确认函数 + function deleteLabel(){ + axios.delete(`/v1/${owner}/${projectsId}/tags/${visible.name}.json`).then(res=>{ + if(res && res.data){ + setVisible(false); + !res.data.status && message.success('删除成功'); + if(page>1 && (source && source.length===1)){ + setPage(page-1); + }else{ + setReload(Math.random()); + } + } + }) + } return (
@@ -147,24 +165,54 @@ function Tags(props) { className="tagTable" dataSource={source} columns={columns} pagination={false}> } - {total > limit ? ( -
- + {total > limit && {setPage(e)}} - > + showSizeChanger={true} + onShowSizeChange={(current, pageSize)=>{setPage(1);setLimit(pageSize);}} + showQuickJumper={true} + >} +
+ {/* {total > limit ? ( +
+ {total > limit && {setPage(e)}} + showSizeChanger={true} + onShowSizeChange={(current, pageSize)=>{setPage(1);setLimit(pageSize);}} + showQuickJumper={true} + >}
) : ( "" - )} + )} */} { source && source.length === 0 && }
+ {setVisible(false)}} + visible={Boolean(visible)} + width="456px" + btn={ +
+ + +
+ } + > +
+ +

确定删除{visible.name}标签?

+
+
) } diff --git a/src/forge/Main/tag/Index.scss b/src/forge/Main/tag/Index.scss index 6adba91e3..6d811717f 100644 --- a/src/forge/Main/tag/Index.scss +++ b/src/forge/Main/tag/Index.scss @@ -1,16 +1,7 @@ .tagTable{ - margin-top: 30px; - thead{ - tr th{ - background-color: #fff; - padding:5px 0px; - width: 172px; - .ant-table-column-title{ - font-size: 16px; - font-weight: 500; - color: #333333; - } - } + margin-top: 9px; + thead tr th{ + display: none; } tbody{ .btn-83{ @@ -21,9 +12,8 @@ background-color: #fff!important; } td{ - padding:0px; + padding:20px 16px 15px; height: 69px; - line-height: 69px; color:#333333; div{ font-weight: 500; @@ -36,23 +26,89 @@ } } } + .disabledBut{ + color: rgba(0, 0, 0, 0.25) !important; + background-color: #f5f5f5; + border-color: #d9d9d9; + cursor: not-allowed; + } } .tagSpin{ min-height: 300px; + position: relative; } .tagBranch{ padding-right: 15px; text-overflow: ellipsis; overflow: hidden; .tagClass{ - color:#333333; + font-weight:700; + color:#40424a; } } .tagModel{ font-weight: 400; + color:#898d9d; + overflow: hidden; + text-overflow: ellipsis; .tagModelImg img{ - width: 25px; - height: 25px; + width: 18px; + height: 18px; border-radius: 50%; } +} +.f6_bor_but, .f6_bor_but:focus{ + color:#f60011; + background-color:rgba(196, 0, 14, 0.09); + border:1px solid #f60011; + border-radius:5px; + &:hover{ + color:#f60011; + background-color:rgba(196, 0, 14, 0.18); + border-color:#ff727c; + } + &:active{ + color:#f60011; + background-color:rgba(196, 0, 14, 0.22); + border-color:#f60011; + } +} +.treeCopyTag{ + flex:1; + display: flex; + justify-content: center; + .treeCopyTagBox{ + height: 32px; + background: #FAFBFC; + border-radius: 4px; + border: 1px solid #D0D0D0; + z-index: 1; + display: flex; + align-items: center; + // position: relative; + &>span{ + padding:0px 15px; + border-right: 1px solid rgba(153, 153, 153, 0.4); + height: 100%; + img{ + margin-right: 4px; + } + a{ + color: #466AFF; + &:hover{ + text-decoration: underline; + } + } + } + &>i{ + margin:0px 12px; + color: #333!important; + } + input{ + position: absolute; + z-index: 0; + opacity: 0; + top: 65px; + } + } } \ No newline at end of file diff --git a/src/forge/Main/tree/Index.jsx b/src/forge/Main/tree/Index.jsx index f1b9b920b..378ec8576 100644 --- a/src/forge/Main/tree/Index.jsx +++ b/src/forge/Main/tree/Index.jsx @@ -3,22 +3,53 @@ import CopyTool from '../../Component/CopyTool'; import { truncateCommitId } from '../../common/util'; import { Link } from 'react-router-dom'; import { getImageUrl , turnbar } from 'educoder'; -import { Dropdown , Menu , Spin } from 'antd'; +import { Button, Dropdown , Input, Menu , message, Modal, Select, Spin, Table, Tooltip } from 'antd'; +import Modals from '../../Component/PublicModal/Index'; import './Index.scss'; import Tree from '../img/tree.png'; import Axios from 'axios'; function Index(props) { + const [ reload, setReload] = useState(undefined); const [ list , setList ] = useState([]); const [ isSpin , setIsSpin ] = useState(true); + // 删除分支 + const [visible, setVisible] = useState(false); + // 新建分支 + const [addBranch, setAddBranch] = useState(false); + const [newBranchName, setNewBranchName] = useState(undefined); + const [newFormBranchName, setNewFormBranchName] = useState(undefined); + const [newBranchError, setNewBranchError] = useState(undefined); + // 通过分支名搜索分支 + const [name, setName] = useState(undefined); + // 分页 + const [current, setCurrent] = useState(1); + const [total, setTotal] = useState(0); + const [pageSize, setPageSize] = useState(10); const { projectsId , owner } = props.match.params; - const { isManager , isDeveloper , projectDetail , defaultBranch } = props; - + const { isManager , isDeveloper , projectDetail , defaultBranch, getDetail } = props; + useEffect(()=>{ - getList(); - },[]) + // getList(); + const url = `/v1/${owner}/${projectsId}/branches.json`; + Axios.get(url,{ + params:{ + keyword: name, + page: current, + limit: pageSize + } + }).then(result=>{ + if(result){ + const {branches, total_count} = result.data; + setTotal(total_count) + setList(branches); + setNewFormBranchName(branches[0].name); + } + setIsSpin(false); + }).catch(error=>{setIsSpin(false);}) + },[name, reload, pageSize, current]) useEffect(()=>{ if(projectDetail && document.title.indexOf('所有分支-') === -1){ @@ -35,6 +66,105 @@ function Index(props) { ) + const columns = [ + { + title: "分支名称", + dataIndex: "name", + key: 1, + ellipsis: true, + width: "160px", + className: "branchNameColumn", + render: (txt, item) => { + return ( + {txt} + ) + } + }, + { + title: "更新信息", + dataIndex: "commit", + key: 3, + ellipsis: true, + width: "240px", + render: (txt, item) => { + return ( +
+ { + txt && txt.committer && txt.committer.id? + + + {txt && txt.committer && txt.committer.name} + + : + + + {txt && txt.committer && txt.committer.name} + + } + 更新于{txt && txt.time_ago} +
+ ) + } + }, + { + title: "commit信息", + dataIndex: "commit_id", + key: 4, + ellipsis: true, + width: "300px", + render: (txt, item) => { + return
+
+ + sha + {truncateCommitId(txt)} + + + +
+
+ } + }, + { + title: "分支类型", + dataIndex: "default_branch", + key: 5, + render: (txt, item) => { + return isManager ? txt === item.name ? 默认分支 : : txt === item.name ? '默认分支' : '普通分支' + } + }, + { + title: "操作", + dataIndex: "name", + key: 6, + align: "center", + width: "320px", + className: "branchActionColumn", + render: (txt, item) => { + return ( +
+ { + (isManager || isDeveloper) && (projectDetail && projectDetail.type!==2) && + + 合并请求 + } + + 下载 + + {txt === item.default_branch ? : } +
+ ) + } + } + ]; + function getList() { const url = `/${owner}/${projectsId}/branches_slice.json`; Axios.get(url).then(result=>{ @@ -45,10 +175,109 @@ function Index(props) { }).catch(error=>{setIsSpin(false);}) } + // 删除分支确认函数 + function deleteLabel(){ + Axios.delete(`/v1/${owner}/${projectsId}/branches/${visible.name}.json`).then(res=>{ + if(res && res.data){ + if(current>1 && (list && list.length===1)){ + setCurrent(current-1); + }else{ + setReload(Math.random()); + } + setVisible(false); + !res.data.status && message.success('删除成功'); + } + }) + } + + // 新建分支确认函数 + function createBranch(){ + setNewBranchError(undefined); + if(!newBranchName){ + setNewBranchError("请输入新建分支名称"); + }else{ + Axios.post(`/v1/${owner}/${projectsId}/branches.json`, { + new_branch_name: newBranchName, + old_branch_name: newFormBranchName + }).then(res=>{ + if(res && res.data){ + // 重新请求仓库详情接口,更新分支总数信息 + getDetail(); + setReload(Math.random()); + setAddBranch(false); + message.success('新建分支成功'); + } + }) + } + } + + // 新建分支名检查格式 + function checkNewBranchName(e) { + setNewBranchError(undefined); + const value = e.target.value; + if (value) { + const str = '^*/'; + let reg = /\\/g; + if(reg.test(value)){ + setNewBranchError('分支名不能包含下列任何字符:^ * \\ /'); + }else{ + for(var i=0;i -1){ + setNewBranchError('分支名不能包含下列任何字符:^ * \\ /'); + return; + }else{ + setNewBranchName(e.target.value); + } + } + } + } + } + + // 更新默认仓库分支 + function updateDefaultBranch(value, info){ + Axios.patch(`/v1/${owner}/${projectsId}/branches/update_default_branch.json`,{ + name: info.name + }).then(res=>{ + if(res && res.data){ + setReload(Math.random()); + !res.data.status && message.success('操作成功'); + } + }) + } + + // 改变pagesize + function onShowSizeChange(current, pageSize){ + window.scrollTo(0, 0); + setCurrent(1); + setPageSize(pageSize); + } + + // 切换页数 + function changePage(page, pageSize){ + window.scrollTo(0, 0); + setCurrent(page); + } + return(
- { +
+ {setName(value)}} allowClear/> +
+ {isManager && 分支设置} + +
+
+ +
+ {/* { list && list.length>0 && list.map((item,key)=>{ return( @@ -112,8 +341,47 @@ function Index(props) { ) }) - } + } */}
+ {setVisible(false)}} + visible={Boolean(visible)} + width="456px" + btn={ +
+ + +
+ } + > +
+ +

确定删除{visible.name}分支?

+
+
+ {setAddBranch(false)}} + visible={addBranch} + width="388px" + footer={ + + } + className="createNewBranchModal" + > +
+
分支名称
+ +
{newBranchError}
+
分支起点
+ +
+
) } diff --git a/src/forge/Main/tree/Index.scss b/src/forge/Main/tree/Index.scss index f65a1c68f..ff2eadd4f 100644 --- a/src/forge/Main/tree/Index.scss +++ b/src/forge/Main/tree/Index.scss @@ -1,3 +1,98 @@ +.treeinfo{ + .branchLastUpdateUserImage{ + height: 20px; + width: 20px; + margin-right: 5px; + } +} +.f6_bor_but, .f6_bor_but:focus{ + color:#f60011; + background-color:rgba(196, 0, 14, 0.09); + border:1px solid #f60011; + border-radius:5px; + &:hover{ + color:#f60011; + background-color:rgba(196, 0, 14, 0.18); + border-color:#ff727c; + } + &:active{ + color:#f60011; + background-color:rgba(196, 0, 14, 0.22); + border-color:#f60011; + } +} +.branchListTable{ + .ant-table-thead > tr > th{ + border-top: 1px solid rgba(42, 97, 255, 0.23); + border-bottom: 1px solid rgba(42, 97, 255, 0.23) !important; + background-color:#fafcff; + } + .ant-table-column-title{ + color:#40424a; + } + .ant-table-thead > tr:first-child > th:last-child{ + border-right: 1px solid rgba(42, 97, 255, 0.23); + } + .ant-table-thead > tr:first-child > th:first-child{ + border-left: 1px solid rgba(42, 97, 255, 0.23); + } + .ant-table-tbody > tr > td{ + border-color: #eeeeee; + padding: 18.5px 16px; + } + .branchNameColumn{ + border-left: 1px solid #d0d0d0; + } + .branchActionColumn{ + border-right: 1px solid #d0d0d0; + } + .task-hide{ + color: $primary-color; + } + .ant-table-empty .ant-table-placeholder{ + border-left: 1px solid #d0d0d0; + border-right: 1px solid #d0d0d0; + } +} +.branchListActionBox{ + display: flex; + justify-content: space-between; + align-items: center; + margin: 20px 0 30px; +} +.createNewBranchModal{ + .ant-modal-title{ + text-align: left; + color:#333333; + font-size:17px; + font-weight: normal !important; + } + .ant-modal-header{ + border-bottom: none; + background-color:rgba(70, 106, 255, 0.05); + } + .ant-modal-close{right: 5px;} + .ant-modal-close-x{font-size: 26px;} + .ant-modal-footer{ + border-top: none; + text-align: center; + padding-bottom: 53px; + } + .ant-modal-content{ + background-image:linear-gradient(359.37deg,#ebf3ff 0%,#f8fbff 55.01%,#f1f5ff 100%); + } + .createBranchLabel{ + color:#27282d; + margin-bottom: 12px; + } + .createBranchInput, .createBranchInput .ant-select-selection{ + border-color:#9eaacb; + background-color: transparent !important; + } + .newBranchError{ + color:#df0002; + } +} .branchSort{ font-weight: 500; color: #333333; @@ -49,14 +144,16 @@ } .treecopy{ flex:1; - display: flex; - justify-content: center; + display: flex; + // justify-content: center; + &>div:not(.treeCopyBox){ + position: relative; + } &>div{ height: 32px; background: #FAFBFC; border-radius: 4px; border: 1px solid #D0D0D0; - position: relative; z-index: 1; display: flex; align-items: center; diff --git a/src/forge/Main/version/New.jsx b/src/forge/Main/version/New.jsx index 3196af523..e3b46772a 100644 --- a/src/forge/Main/version/New.jsx +++ b/src/forge/Main/version/New.jsx @@ -23,7 +23,7 @@ const Span = styled.span` export default Form.create()( forwardRef( ( - { form, projectDetail , match, showNotification, history }, + { form, projectDetail , match, showNotification, history, getDetail }, ref ) => { const { getFieldDecorator, validateFields, setFieldsValue } = form; @@ -35,7 +35,8 @@ export default Form.create()( const [options , setOptions] = useState(undefined); const stable = history && history.location && history.location.state&&history.location.state.stable; const { projectsId, versionId , owner } = match.params; - + const urlSearch = new URLSearchParams(history.location.search); + useEffect(()=>{ if(projectDetail && projectDetail.default_branch){ setBranch(projectDetail.default_branch); @@ -121,6 +122,8 @@ export default Form.create()( }) .then(result => { if (result) { + // 重新请求仓库详情接口,更新标签总数信息 + getDetail(); showNotification("版本发布成功!"); history.push(`/${owner}/${projectsId}/releases`); } @@ -153,7 +156,8 @@ export default Form.create()( callback(); } }}], - validateFirst: true + validateFirst: true, + initialValue: urlSearch.get('tag') })( a>span{ display: inline-block; & img{ - width: 20px; - height: 20px; + width: 30px; + height: 30px; } } } diff --git a/src/forge/Merge/CreateMerge.js b/src/forge/Merge/CreateMerge.js index 932ecf06a..ffcd4537c 100644 --- a/src/forge/Merge/CreateMerge.js +++ b/src/forge/Merge/CreateMerge.js @@ -214,8 +214,8 @@ class CreateMerge extends Component { const url = `/${owner}/${identifier}/branches.json`; let check = await axios.get(url).then((result) => { if(result.data){ - let pfilter = (result.data || []).filter(i => i.name === branch).length === 0; - let mfilter = (result.data || []).filter(i => i.name === mergebranch).length === 0; + let pfilter = (result.data || []).filter(i => i.name === decodeURIComponent(branch)).length === 0; + let mfilter = (result.data || []).filter(i => i.name === decodeURIComponent(mergebranch)).length === 0; if(type === "pull"){ this.setState({ pullBranches:result.data, diff --git a/src/forge/Newfile/UserSubmitComponent.js b/src/forge/Newfile/UserSubmitComponent.js index aa3f626e3..66e2e1b47 100644 --- a/src/forge/Newfile/UserSubmitComponent.js +++ b/src/forge/Newfile/UserSubmitComponent.js @@ -244,6 +244,7 @@ class UserSubmitComponent extends Component { )}