# 发布详情窗口增加直接开web终端功能

pull/410/head
vapao 2021-10-28 09:34:06 +08:00
parent 4b2df549ab
commit a7b17f09f3
4 changed files with 54 additions and 19 deletions

View File

@ -6,7 +6,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { observer, useLocalStore } from 'mobx-react'; import { observer, useLocalStore } from 'mobx-react';
import { Card, Progress, Modal, Collapse, Steps, Skeleton } from 'antd'; import { Card, Progress, Modal, Collapse, Steps, Skeleton } from 'antd';
import { ShrinkOutlined, CaretRightOutlined, LoadingOutlined, CloseOutlined } from '@ant-design/icons'; import { ShrinkOutlined, CaretRightOutlined, LoadingOutlined, CloseOutlined, CodeOutlined } from '@ant-design/icons';
import OutView from './OutView'; import OutView from './OutView';
import { http, X_TOKEN } from 'libs'; import { http, X_TOKEN } from 'libs';
import styles from './index.module.less'; import styles from './index.module.less';
@ -98,6 +98,11 @@ function Ext1Console(props) {
terms[key] = term terms[key] = term
} }
function openTerminal(e, item) {
e.stopPropagation()
window.open(`/ssh?id=${item.id}`)
}
let {local, ...hosts} = outputs; let {local, ...hosts} = outputs;
return ( return (
<div> <div>
@ -173,6 +178,7 @@ function Ext1Console(props) {
<StepItem title="执行发布" item={item} step={3}/> <StepItem title="执行发布" item={item} step={3}/>
<StepItem title="发布后任务" item={item} step={4}/> <StepItem title="发布后任务" item={item} step={4}/>
</Steps> </Steps>
<CodeOutlined className={styles.codeIcon} onClick={e => openTerminal(e, item)}/>
</div>}> </div>}>
<OutView setTerm={term => handleSetTerm(term, key)}/> <OutView setTerm={term => handleSetTerm(term, key)}/>
</Collapse.Panel> </Collapse.Panel>

View File

@ -6,7 +6,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { observer, useLocalStore } from 'mobx-react'; import { observer, useLocalStore } from 'mobx-react';
import { Card, Progress, Modal, Collapse, Steps, Skeleton } from 'antd'; import { Card, Progress, Modal, Collapse, Steps, Skeleton } from 'antd';
import { ShrinkOutlined, CaretRightOutlined, LoadingOutlined, CloseOutlined } from '@ant-design/icons'; import { ShrinkOutlined, CaretRightOutlined, LoadingOutlined, CloseOutlined, CodeOutlined } from '@ant-design/icons';
import OutView from './OutView'; import OutView from './OutView';
import { http, X_TOKEN } from 'libs'; import { http, X_TOKEN } from 'libs';
import styles from './index.module.less'; import styles from './index.module.less';
@ -106,6 +106,11 @@ function Ext2Console(props) {
terms[key] = term terms[key] = term
} }
function openTerminal(e, item) {
e.stopPropagation()
window.open(`/ssh?id=${item.id}`)
}
const hostOutputs = Object.values(outputs).filter(x => x.id !== 'local'); const hostOutputs = Object.values(outputs).filter(x => x.id !== 'local');
return ( return (
<div> <div>
@ -180,6 +185,7 @@ function Ext2Console(props) {
<StepItem key={index} title={action.title} item={item} step={index + 1}/> <StepItem key={index} title={action.title} item={item} step={index + 1}/>
))} ))}
</Steps> </Steps>
<CodeOutlined className={styles.codeIcon} onClick={e => openTerminal(e, item)}/>
</div>}> </div>}>
<OutView setTerm={term => handleSetTerm(term, item.id)}/> <OutView setTerm={term => handleSetTerm(term, item.id)}/>
</Collapse.Panel> </Collapse.Panel>

View File

@ -86,6 +86,11 @@
margin-right: 16px; margin-right: 16px;
} }
.codeIcon {
font-size: 22px;
color: #1890ff;
}
.icon { .icon {
font-size: 22px; font-size: 22px;
font-weight: 300; font-weight: 300;

View File

@ -20,6 +20,7 @@ function WebSSH(props) {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [fetching, setFetching] = useState(true); const [fetching, setFetching] = useState(true);
const [rawTreeData, setRawTreeData] = useState([]); const [rawTreeData, setRawTreeData] = useState([]);
const [rawHostList, setRawHostList] = useState([]);
const [treeData, setTreeData] = useState([]); const [treeData, setTreeData] = useState([]);
const [searchValue, setSearchValue] = useState(); const [searchValue, setSearchValue] = useState();
const [hosts, setHosts] = useState([]); const [hosts, setHosts] = useState([]);
@ -30,40 +31,57 @@ function WebSSH(props) {
window.document.title = 'Spug web terminal' window.document.title = 'Spug web terminal'
window.addEventListener('beforeunload', leaveTips) window.addEventListener('beforeunload', leaveTips)
http.get('/api/host/group/?with_hosts=1') http.get('/api/host/group/?with_hosts=1')
.then(res => setRawTreeData(res.treeData)) .then(res => {
.finally(() => setFetching(false)) const tmp = {}
return () => window.removeEventListener('beforeunload', leaveTips) setRawTreeData(res.treeData)
}, []) setTreeData(res.treeData)
useEffect(() => {
if (searchValue) {
const newTreeData = []
const loop = (data) => { const loop = (data) => {
for (let item of data) { for (let item of data) {
if (item.children) { if (item.children) {
loop(item.children) loop(item.children)
} else if (item.isLeaf && includes(item.title, searchValue)) { } else if (item.isLeaf) {
newTreeData.push(item) tmp[item.id] = item
} }
} }
} }
loop(rawTreeData) loop(res.treeData)
setRawHostList(Object.values(tmp))
const query = new URLSearchParams(props.location.search);
const id = query.get('id');
if (id) {
const node = lds.find(Object.values(tmp), {id: Number(id)})
if (node) _openNode(node)
}
})
.finally(() => setFetching(false))
return () => window.removeEventListener('beforeunload', leaveTips)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
useEffect(() => {
if (searchValue) {
const newTreeData = rawHostList.filter(x => includes(x.title, searchValue))
setTreeData(newTreeData) setTreeData(newTreeData)
} else { } else {
setTreeData(rawTreeData) setTreeData(rawTreeData)
} }
}, [rawTreeData, searchValue]) // eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchValue])
function leaveTips(e) { function leaveTips(e) {
e.returnValue = '确定要离开页面?' e.returnValue = '确定要离开页面?'
} }
function _openNode(node) {
node.vId = String(new Date().getTime())
hosts.push(node);
setHosts(lds.cloneDeep(hosts))
setActiveId(node.vId)
}
function handleSelect(e) { function handleSelect(e) {
if (e.nativeEvent.detail > 1 && e.node.isLeaf) { if (e.nativeEvent.detail > 1 && e.node.isLeaf) {
e.node.vId = String(new Date().getTime()) _openNode(e.node)
hosts.push(e.node);
setHosts(lds.cloneDeep(hosts))
setActiveId(e.node.vId)
} }
} }