Merge branch 'gitlink_ssr_head' of https://gitlink.org.cn/Gitlink/forgeplus-react into gitlink_ssr_head

This commit is contained in:
caishi 2026-01-20 16:33:22 +08:00
commit 05c71c90dc
9 changed files with 179 additions and 47 deletions

View File

@ -1,4 +1,4 @@
import React , { useState , useEffect , useRef } from 'react';
import React , { useState , useEffect , useRef, Fragment } from 'react';
import { Dropdown} from 'antd';
import './branch.scss';
import SelectOverlay from './SelectOverlay';
@ -6,7 +6,7 @@ import { findDOMNode } from 'react-dom';
import { turnbar } from 'educoder';
import { truncateCommitId } from "../common/util";
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true , commitflag=false })=>{
export default (({ projectsId , branch , owner , changeBranch , branchList , tagflag = true , commitflag=false, children })=>{
const [ showValue , setShowValue ] = useState(branch);
const [ visible , setVisible ] = useState(false);
@ -56,14 +56,16 @@ export default (({ projectsId , branch , owner , changeBranch , branchList , tag
</div>
);
return(
<Dropdown placement='bottomLeft' visible={visible} overlay={menu} overlayClassName="branch-tagBox-list" trigger={['click']} >
<Dropdown placement='bottomLeft' visible={visible} overlay={menu} overlayClassName="branch-tagBox-list" trigger={['click']} getPopupContainer={trigger => trigger.parentNode}>
<div className="branch-tagBox" ref={refBox} onClick={()=>setVisible(visible ? false : true)}>
{/* {nav === 0 ?"分支":"标签"} */}
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
<span className="ant-dropdown-link task-hide" style={{fontWeight:"500",minWidth:"45px",maxWidth:"180px"}}>
{showValue}
</span>
<i className="showtag iconfont icon-sanjiaoxing-down font-15 color-grey-9 mr5 ml5 mt1" />
{children || <Fragment>
<span className="color-grey-9 mr3 ml8"><i className="iconfont icon-fenzhi2 font-18"></i></span>
<span className="ant-dropdown-link task-hide" style={{fontWeight:"500",minWidth:"45px",maxWidth:"180px"}}>
{showValue}
</span>
<i className="showtag iconfont icon-sanjiaoxing-down font-15 color-grey-9 mr5 ml5 mt1" />
</Fragment>}
</div>
</Dropdown>
)

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Modal } from 'antd';
import './Index.scss';
function Modals({title,children,btn,onCancel,visible, width}) {
function Modals({title,children,btn,onCancel,visible, width, destroyOnClose=false}) {
return(
<Modal
visible={visible}
@ -12,6 +12,7 @@ function Modals({title,children,btn,onCancel,visible, width}) {
footer={btn}
centered={true}
wrapClassName={"deleteBox"}
destroyOnClose={destroyOnClose}
>
{children}
</Modal>

View File

@ -0,0 +1,22 @@
import { Button } from 'antd';
import React from 'react';
import './Index.scss';
function Empty({operation,addFunc}) {
return(
<div className="emptyPanel_tag color-grey-3 mt30">
<i className="iconfont icon-biaoqianicon font-50 color-grey-3" style={{height:"50px",lineHeight:"50px",marginBottom:"13px"}}></i>
<span className="weight font-26 mb15">这里还没有任何标签</span>
<span className="weight400" style={{textAlign:"center",lineHeight:"20px"}}>标签Tags是对代码库中特定提交的引用通常用于标识发布版本 V1.0或重要节点<br/>您可以在提交记录或发行版功能中创建和管理标签</span>
<div className="operation">
{
operation ?
<Button type={"primary"} onClick={addFunc} className="btnblue" style={{width:"118px",height:"36px"}}>新建标签</Button>
:
<span className="color-grey-3 weight font-16">该项目暂时还没有任何标签</span>
}
</div>
</div>
)
}
export default Empty;

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import SubMenu from '../sub/SubMenu';
import { Table, Tooltip, Spin,Pagination, Button, message } from 'antd';
import { Table, Tooltip, Spin,Pagination, Button, message, Form } from 'antd';
import axios from 'axios';
import { Link } from 'react-router-dom';
import { truncateCommitId } from '../../common/util';
@ -11,6 +11,8 @@ import Tree from '../img/tree.png'
import moment from 'moment';
import CopyTool from '../../Component/CopyTool';
import Modals from '../../Component/PublicModal/Index';
import Empty from './Empty';
import New from './New';
function Tags(props) {
const [reload, setReload] = useState(undefined);
@ -21,9 +23,12 @@ function Tags(props) {
const [limit,setLimit] =useState(10);
//
const [visible, setVisible] = useState(false);
//
const [visibleByAdd, setVisibleByAdd] = useState(false);
const { projectsId, owner } = props.match.params;
const { projectDetail, current_user} = props;
const permission = projectDetail && projectDetail.permission;
const hasPermission = (current_user && current_user.login) && (permission && permission!=="Reporter");
useEffect(()=>{
if(projectDetail && document.title.indexOf('所有标签-') === -1){
@ -173,8 +178,16 @@ function Tags(props) {
return (
<div>
<SubMenu tab={"tags"} projectsId={projectsId} owner={owner} />
<div className='mt30'>
{
(current_user && current_user.login) && (permission && permission!=="Reporter") && (source && source.length > 0) &&
<div className="edu-txt-right">
<Button type={"primary"} onClick={()=>{setVisibleByAdd(true)}} className="btnblue" style={{height:"36px"}}>新建标签</Button>
</div>
}
</div>
<Spin spinning={isSpin}>
<div className="tagSpin">
<div className="tagSpin mb30">
{
source && source.length > 0 &&
<Table
@ -182,34 +195,20 @@ function Tags(props) {
className="tagTable"
dataSource={source} columns={columns} pagination={false}></Table>
}
<div className="mt30 mb50 edu-txt-right">
{total > limit && <Pagination
current={page}
total={total}
pageSize={limit}
onChange={(e)=>{setPage(e)}}
showSizeChanger={true}
onShowSizeChange={(current, pageSize)=>{setPage(1);setLimit(pageSize);}}
showQuickJumper={true}
></Pagination>}
</div>
{/* {total > limit ? (
<div className="mt30 mb50 edu-txt-right">
{total > limit && <Pagination
current={page}
total={total}
pageSize={limit}
onChange={(e)=>{setPage(e)}}
showSizeChanger={true}
onShowSizeChange={(current, pageSize)=>{setPage(1);setLimit(pageSize);}}
showQuickJumper={true}
></Pagination>}
</div>
) : (
""
)} */}
{source && source.length > 0 && <div className="mt30 mb50 edu-txt-right">
<Pagination
current={page}
total={total}
pageSize={limit}
onChange={(e)=>{setPage(e)}}
showSizeChanger={true}
onShowSizeChange={(current, pageSize)=>{setPage(1);setLimit(pageSize);}}
showQuickJumper={true}
hideOnSinglePage={true}
></Pagination>
</div>}
{
source && source.length === 0 && <Nonedata _html={'暂无数据~'} />
source && source.length === 0 && <Empty operation={hasPermission} addFunc={()=>{setVisibleByAdd(true)}}/>
}
</div>
</Spin>
@ -230,6 +229,7 @@ function Tags(props) {
<p style={{color: '#333'}}>确定删除{visible.name}标签?</p>
</div>
</Modals>
<New visibleByAdd={visibleByAdd} setVisibleByAdd={setVisibleByAdd} onOK={()=>{setReload(Math.random())}} projectsId={projectsId} owner={owner} />
</div>
)
}

View File

@ -1,5 +1,4 @@
.tagTable{
margin-top: 9px;
thead tr th{
display: none;
}
@ -112,4 +111,33 @@
top: 65px;
}
}
}
.emptyPanel_tag{
width: 100%;
background: #FAFCFF;
border-radius: 4px;
border: 1px solid rgba(42, 97, 255, 0.23);
min-height: 418px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.operation{
width: 400px;
border-top: 1px solid #eee;
padding-top: 34px;
text-align: center;
margin-top: 30px;
}
}
.tag_target_select .ant-select-arrow{
display: none;
}
.tag_target{
.branch-tagBox{
border: none;
}
.overlayBranch{
width: 456px;
}
}

View File

@ -0,0 +1,74 @@
import { Button, Form, Input, message, Select } from 'antd';
import React, { Fragment, useState } from 'react';
import './Index.scss';
import Modals from '../../Component/PublicModal/Index';
import SelectOverlay from '../../Branch/SelectOverlay';
import SelectByBranch from '../../Branch/Select';
import axios from 'axios';
function NewTag({ form, visibleByAdd, setVisibleByAdd, owner, projectsId, onOK }) {
const { getFieldDecorator, validateFields, setFieldsValue, getFieldsValue } = form;
const { target} = getFieldsValue();
//
function addTag(){
validateFields((error,values)=>{
if(!error){
axios.post(`/v1/${owner}/${projectsId}/tags`,values).then(result=>{
if(result && result.data){
message.success("新增成功");
setVisibleByAdd(false);
onOK && onOK();
}
}).catch(error=>{})
}
})
}
return (
<Modals
title="新建标签"
onCancel={() => { setVisibleByAdd(false) }}
visible={Boolean(visibleByAdd)}
width="556px"
btn={
<div>
<Button size={"large"} onClick={() => { setVisibleByAdd(false) }}>取消</Button>
<Button type={'primary'} size={"large"} onClick={addTag}>确认</Button>
</div>
}
destroyOnClose={true}
>
<Form form={form}>
<Form.Item label="标签名称">
{getFieldDecorator("tag_name",{
rules:[{ required: true, message: '请输入标签名称' }]
})(
<Input placeholder={"请输入标签名称"} maxLength={50}/>
)}
</Form.Item>
<Form.Item label="标签起点" className='tag_target'>
{getFieldDecorator("target", {
rules:[{ required: true, message: '请选择标签起点' }]
})(
<SelectByBranch projectsId={projectsId} owner={owner} tagflag={true} changeBranch={(branch)=>{
setFieldsValue({
target: branch
})
}}>
<Select value={target} placeholder="请选择标签起点" dropdownRender={()=>{return <Fragment></Fragment>}} className='tag_target_select'/>
</SelectByBranch>
)}
</Form.Item>
<Form.Item label="标签描述">
{getFieldDecorator("message",{
rules:[{ required: true, message: '请输入标签描述' }]
})(
<Input.TextArea autoSize={{minRows: 3}} placeholder={"请输入标签描述"} maxLength={200}/>
)}
</Form.Item>
</Form>
</Modals>
)
}
export default Form.create()(NewTag);

View File

@ -91,7 +91,7 @@ function version(props) {
cancelText="否"
onConfirm={() =>{deleteRelease(item.version_id)}}
>
<i className ="iconfont icon-shanchuicon1 font-16 ml15"></i>
<i className ="iconfont icon-shanchuicon1 font-16 ml15 pointer"></i>
</Popconfirm>
}
</span>

View File

@ -280,8 +280,6 @@ ul.ant-menu.menuStyle{
padding:0px;
margin:0px 30px 0px 0px !important;
font-size: 17px;
height: 32px;
line-height: 0px;
border-bottom: 2px solid transparent!important;
position: relative;
a{
@ -297,9 +295,16 @@ ul.ant-menu.menuStyle{
}
}
.menuNum{
margin-left: 5px;
font-size: 12px;
margin-left: 3px;
color: #FF6E21;
color: #666;
background-color: hsla(0, 0%, 60%, .13);
border-radius: 50%;
height: 24px;
line-height: 24px;
min-width: 24px;
text-align: center;
padding: 0 5px;
}
&.ant-menu-item-selected::before{
position: absolute;

View File

@ -391,7 +391,7 @@ class Infos extends Component {
<Menu.Item key="2">
<Link to={`/${user && user.login}/projects`}>
<i className="iconfont icon-xiangmu"></i>
{ user && user.user_projects_count > 0 ? <span className="menuNum">({user.user_projects_count})</span> :"" }
{ user && user.user_projects_count > 0 ? <span className="menuNum">{user.user_projects_count}</span> :"" }
</Link>
</Menu.Item>
{
@ -399,7 +399,7 @@ class Infos extends Component {
<Menu.Item key="3">
<Link to={`/${user && user.login}/notice`}>
<i className="iconfont icon-daibanshixiang"></i>
{undo_events && undo_events >0 ? <span className="menuNum">({undo_events})</span>:""}</Link>
{undo_events && undo_events >0 ? <span className="menuNum">{undo_events}</span>:""}</Link>
</Menu.Item>
:""
}
@ -411,7 +411,7 @@ class Infos extends Component {
<Menu.Item key="5">
<Link to={`/${user && user.login}/organizes`}>
<i className="iconfont icon-zuzhi"></i>
{ user && user.user_org_count && user.user_org_count > 0 ? <span className="menuNum">({user.user_org_count})</span>:""}
{ user && user.user_org_count && user.user_org_count > 0 ? <span className="menuNum">{user.user_org_count}</span>:""}
</Link>
</Menu.Item>
{/* 当前用户+配置了贡献确权 */}