|
|
@ -3,20 +3,27 @@ import React, { useEffect, useState } from 'react' |
|
|
|
import { connect, createStore } from "react-redux"; |
|
|
|
import Immutable from 'immutable'; |
|
|
|
import { pepProject } from '../../actions/global'; |
|
|
|
import { SplitButtonGroup, Dropdown, Button, Nav, Avatar, Input, Tooltip, Tabs, TabPane } from '@douyinfe/semi-ui'; |
|
|
|
import { IconTreeTriangleDown, IconSearch } from '@douyinfe/semi-icons'; |
|
|
|
import { SplitButtonGroup, Dropdown, Button, Nav, Avatar, Input, Tooltip, Tabs, TabPane, Space, Popconfirm, Modal } from '@douyinfe/semi-ui'; |
|
|
|
import { IconTreeTriangleDown, IconSearch, IconEdit, IconDelete } from '@douyinfe/semi-icons'; |
|
|
|
import CustomProjGroupModal from './components/customProjGroupModal' |
|
|
|
import PerfectScrollbar from "perfect-scrollbar"; |
|
|
|
import "./index.less"; |
|
|
|
|
|
|
|
let newScrollbar; |
|
|
|
const Header = (props) => { |
|
|
|
const { dispatch, history, user, actions, socket, headerItems, tochange } = props; |
|
|
|
const { install } = actions |
|
|
|
const { dispatch, history, user, actions, socket, headerItems, tochange, projectGroup } = props; |
|
|
|
const { install, projectGroup: projectGroupAC } = actions |
|
|
|
const [pomsList, setPomsList] = useState([]) |
|
|
|
const [pomsName, setPomsName] = useState('全局') |
|
|
|
const [pepProjectId, setPepProjectId] = useState() |
|
|
|
const [keyword, setKeyword] = useState('') |
|
|
|
const [Scrollbar, setScrollbar] = useState(false) |
|
|
|
const [prjDropdownVis, setPrjDropdownVis] = useState(false) |
|
|
|
const [prjDropDownTabKey, setPrjDropDownTabKey] = useState('项目') |
|
|
|
const [customProjGroupModalVis, setCustomProjGroupModalVis] = useState(false) |
|
|
|
const [customProjGroupDelPopVis, setCustomProjGroupDelPopVis] = useState(false) |
|
|
|
const [customProjGroupEditData, setCustomProjGroupEditData] = useState(null) |
|
|
|
|
|
|
|
let userRole = user?.pomsUserInfo?.role |
|
|
|
let modalRole = [] |
|
|
|
if (userRole) { |
|
|
@ -33,6 +40,10 @@ const Header = (props) => { |
|
|
|
if (userRole?.includes('SuperAdmin') || userRole?.includes('admin')) modalRole = headerItems |
|
|
|
} |
|
|
|
|
|
|
|
const getProjGroup = () => { |
|
|
|
dispatch(projectGroupAC.getProjectGroup()) |
|
|
|
} |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
if (JSON.parse(sessionStorage.getItem('pomsUser'))?.token) { |
|
|
|
dispatch(install.getProjectPoms({ global: 1 })).then((res) => { //获取已绑定项目 |
|
|
@ -41,6 +52,7 @@ const Header = (props) => { |
|
|
|
setPomsList(data) |
|
|
|
} |
|
|
|
}) |
|
|
|
getProjGroup() |
|
|
|
} |
|
|
|
}, []) |
|
|
|
|
|
|
@ -60,7 +72,15 @@ const Header = (props) => { |
|
|
|
dispatch(pepProject(pepProjectId)) |
|
|
|
}, [pepProjectId]) |
|
|
|
|
|
|
|
|
|
|
|
const semiPortalZindex = () => { |
|
|
|
const semiPortal = document.getElementsByClassName('semi-portal') |
|
|
|
for (let sp of semiPortal) { |
|
|
|
if (sp.style.zIndex == 1060) { |
|
|
|
sp.style.zIndex = 990 |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return ( |
|
|
|
<> |
|
|
|
<div id="top-slider"> |
|
|
@ -86,7 +106,11 @@ const Header = (props) => { |
|
|
|
logo: ( |
|
|
|
<img |
|
|
|
src="/assets/images/install/long_logo.png" |
|
|
|
style={{ display: "inline-block", width: 200, height: 40, marginLeft: -24 }} |
|
|
|
style={{ display: "inline-block", width: 200, height: 40, marginLeft: -24, cursor: 'pointer' }} |
|
|
|
onClick={() => { |
|
|
|
// history.push('/projectGroup/static') |
|
|
|
window.open('/projectGroup/static', '_blank'); |
|
|
|
}} |
|
|
|
/> |
|
|
|
), |
|
|
|
text: ( |
|
|
@ -97,26 +121,42 @@ const Header = (props) => { |
|
|
|
setScrollbar(!Scrollbar) |
|
|
|
setKeyword('') |
|
|
|
}} |
|
|
|
clickToHide={true} |
|
|
|
// trigger="click" |
|
|
|
// clickToHide={true} |
|
|
|
trigger={'custom'} |
|
|
|
visible={prjDropdownVis} |
|
|
|
onClickOutSide={(e) => { |
|
|
|
if (customProjGroupModalVis || customProjGroupDelPopVis) { |
|
|
|
return |
|
|
|
} |
|
|
|
setPrjDropdownVis(false) |
|
|
|
}} |
|
|
|
position="rightBottom" |
|
|
|
stopPropagation={true} |
|
|
|
render={ |
|
|
|
<Dropdown.Menu style={{ minWidth: 270, maxWidth: 714, padding: 20, fontSize: 12 }}> |
|
|
|
<Tabs type="button"> |
|
|
|
<Dropdown.Menu style={{ minWidth: 270, maxWidth: 714, padding: 20, fontSize: 12, position: 'relative', }}> |
|
|
|
<Tabs type="button" |
|
|
|
activeKey={prjDropDownTabKey} |
|
|
|
onChange={ |
|
|
|
(v) => setPrjDropDownTabKey(v) |
|
|
|
} |
|
|
|
> |
|
|
|
<TabPane tab="项目" itemKey="项目"> |
|
|
|
<div style={{ width: '100%', height: 1, background: "#d5cfcf8c", margin: "10px 0" }}></div> |
|
|
|
<Input suffix={<IconSearch />} onChange={(v) => setKeyword(v)} showClear onClick={(e)=>e.stopPropagation()}></Input> |
|
|
|
<Input suffix={<IconSearch />} onChange={(v) => setKeyword(v)} showClear onClick={(e) => e.stopPropagation()}></Input> |
|
|
|
<div id='overall' style={{ width: '100%', height: 260, position: "relative", marginTop: 10 }}> |
|
|
|
{pomsList?.length > 0 ? |
|
|
|
pomsList.filter(u => u.pepProjectName?.includes(keyword))?.map(v => { |
|
|
|
return <Dropdown.Item |
|
|
|
key={'pomsList' + v.pepProjectId} |
|
|
|
style={{ width: 224, overflow: 'hidden', borderBottom: '', display: "inline-block", whiteSpace: 'nowrap', color: 'rgb(0, 90, 189)' }}> |
|
|
|
|
|
|
|
{ |
|
|
|
v.pepProjectName?.length > 15 ? <Tooltip content={<div>{v.pepProjectName}</div>}> |
|
|
|
<div style={{}} > |
|
|
|
<div onClick={() => { |
|
|
|
setPomsName(v.pepProjectName) |
|
|
|
setPepProjectId(v.pepProjectId) |
|
|
|
setPrjDropdownVis(false) |
|
|
|
}}> |
|
|
|
{v.pepProjectName?.length > 15 ? `${v.pepProjectName?.substr(0, 15)}` : v.pepProjectName} |
|
|
|
</div> |
|
|
@ -125,6 +165,7 @@ const Header = (props) => { |
|
|
|
: <div onClick={() => { |
|
|
|
setPomsName(v.pepProjectName) |
|
|
|
setPepProjectId(v.pepProjectId) |
|
|
|
setPrjDropdownVis(false) |
|
|
|
}}>{v.pepProjectName}</div> |
|
|
|
} |
|
|
|
</Dropdown.Item> |
|
|
@ -135,11 +176,91 @@ const Header = (props) => { |
|
|
|
<TabPane tab={<div onClick={() => { |
|
|
|
setPomsName('全局') |
|
|
|
setPepProjectId('') |
|
|
|
setPrjDropdownVis(false) |
|
|
|
}}>全局</div>} itemKey="全局"> |
|
|
|
</TabPane> |
|
|
|
<TabPane tab={<div onClick={() => { |
|
|
|
setPepProjectId('') |
|
|
|
}}>自定义分组</div>} itemKey="自定义分组"> |
|
|
|
<div style={{ width: '100%', height: 1, background: "#d5cfcf8c", margin: "10px 0" }} /> |
|
|
|
<div style={{ display: 'flex' }}> |
|
|
|
<Button type="primary" onClick={() => { |
|
|
|
semiPortalZindex() |
|
|
|
setCustomProjGroupModalVis(true) |
|
|
|
}}>设置新分组</Button> |
|
|
|
<Input style={{ |
|
|
|
flex: 1, marginLeft: 14 |
|
|
|
}} suffix={<IconSearch />} onChange={(v) => setKeyword(v)} showClear onClick={(e) => e.stopPropagation()}></Input> |
|
|
|
</div> |
|
|
|
<div id='overall' className='customGroupPop' style={{ width: '100%', height: 260, position: "relative", marginTop: 10 }}> |
|
|
|
{ |
|
|
|
projectGroup.filter(u => u.name?.includes(keyword))?.map(v => { |
|
|
|
return ( |
|
|
|
<Dropdown.Item |
|
|
|
className='customGroupItem' |
|
|
|
key={'projectGroup' + v.id} |
|
|
|
style={{ |
|
|
|
width: 224, overflow: 'hidden', borderBottom: '', display: "inline-block", whiteSpace: 'nowrap', color: 'rgb(0, 90, 189)' |
|
|
|
}} |
|
|
|
onClick={(e) => { |
|
|
|
e.stopPropagation() |
|
|
|
setPomsName(v.name) |
|
|
|
setPepProjectId(v.pomsProjectIds.join(',')) |
|
|
|
setPrjDropdownVis(false) |
|
|
|
}} |
|
|
|
> |
|
|
|
{ |
|
|
|
v.name?.length > 10 ? |
|
|
|
<Tooltip content={<div>{v.name}</div>}> |
|
|
|
<span > |
|
|
|
{v.name?.substr(0, 10)}... |
|
|
|
</span> |
|
|
|
</Tooltip> |
|
|
|
: |
|
|
|
<span > |
|
|
|
{v.name} |
|
|
|
</span> |
|
|
|
} |
|
|
|
<Space style={{ float: 'right', position: 'relative', top: 3, }}> |
|
|
|
<IconEdit className="edit-icon" onClick={(e) => { |
|
|
|
e.stopPropagation() |
|
|
|
semiPortalZindex() |
|
|
|
setCustomProjGroupEditData(v) |
|
|
|
setCustomProjGroupModalVis(true) |
|
|
|
}} /> |
|
|
|
<IconDelete className="del-icon" onClick={(e) => { |
|
|
|
e.stopPropagation() |
|
|
|
semiPortalZindex() |
|
|
|
setCustomProjGroupDelPopVis(v.id) |
|
|
|
Modal.warning({ |
|
|
|
title: '确定删除该自定义分组?', content: '此修改将不可逆', |
|
|
|
onCancel: () => { |
|
|
|
setCustomProjGroupDelPopVis(null) |
|
|
|
}, |
|
|
|
onOk: () => { |
|
|
|
dispatch(projectGroupAC.delProjectGroup(v.id)).then((res) => { |
|
|
|
if (res.success) { |
|
|
|
setCustomProjGroupDelPopVis(null) |
|
|
|
|
|
|
|
getProjGroup() |
|
|
|
} |
|
|
|
}) |
|
|
|
}, |
|
|
|
style: { zIndex: 1090 } |
|
|
|
}); |
|
|
|
}} /> |
|
|
|
</Space> |
|
|
|
</Dropdown.Item> |
|
|
|
|
|
|
|
) |
|
|
|
}) |
|
|
|
} |
|
|
|
</div> |
|
|
|
</TabPane> |
|
|
|
</Tabs> |
|
|
|
</Dropdown.Menu> |
|
|
|
} trigger="click" position="bottomRight"> |
|
|
|
} |
|
|
|
> |
|
|
|
<Button theme="solid" type="primary" style={{ height: 24, background: '#005ABD' }}>{ |
|
|
|
pomsName.length > 15 ? <Tooltip content={<div>{pomsName}</div>}> |
|
|
|
<div style={{}}> |
|
|
@ -147,7 +268,7 @@ const Header = (props) => { |
|
|
|
</div> |
|
|
|
</Tooltip> : pomsName |
|
|
|
}</Button> |
|
|
|
<Button style={{ width: 16, height: 24, background: '#005ABD' }} theme="solid" type="primary" icon={<IconTreeTriangleDown />}></Button> |
|
|
|
<Button style={{ width: 16, height: 24, background: '#005ABD' }} theme="solid" type="primary" icon={<IconTreeTriangleDown />} onClick={() => { setPrjDropdownVis(!prjDropdownVis) }}></Button> |
|
|
|
</Dropdown> |
|
|
|
</SplitButtonGroup> |
|
|
|
</> |
|
|
@ -176,7 +297,6 @@ const Header = (props) => { |
|
|
|
<img src="/assets/images/background/console.png" style={{ width: 24, marginRight: -10 }} /> |
|
|
|
<Nav.Item key={index + 'a'} itemKey={item.itemKey} text={item.text} onClick={() => { tochange(item) }} /> |
|
|
|
</div> |
|
|
|
|
|
|
|
) |
|
|
|
} |
|
|
|
}) : ""} |
|
|
@ -253,17 +373,32 @@ const Header = (props) => { |
|
|
|
</> |
|
|
|
} |
|
|
|
/> |
|
|
|
{ |
|
|
|
<CustomProjGroupModal |
|
|
|
visible={customProjGroupModalVis} |
|
|
|
pomsList={pomsList} |
|
|
|
editData={customProjGroupEditData} |
|
|
|
cancel={({ refresh } = {}) => { |
|
|
|
setCustomProjGroupModalVis(false) |
|
|
|
setCustomProjGroupEditData(null) |
|
|
|
if (refresh) { |
|
|
|
getProjGroup() |
|
|
|
} |
|
|
|
}} |
|
|
|
/> |
|
|
|
} |
|
|
|
</div> |
|
|
|
</> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
function mapStateToProps (state) { |
|
|
|
const { global, auth, webSocket } = state; |
|
|
|
const { global, auth, webSocket, projectGroup } = state; |
|
|
|
return { |
|
|
|
actions: global.actions, |
|
|
|
user: auth.user, |
|
|
|
socket: webSocket.socket, |
|
|
|
projectGroup: projectGroup.data || [] |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|