# 发布详情窗口增加直接开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 { observer, useLocalStore } from 'mobx-react';
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 { http, X_TOKEN } from 'libs';
import styles from './index.module.less';
@ -98,6 +98,11 @@ function Ext1Console(props) {
terms[key] = term
}
function openTerminal(e, item) {
e.stopPropagation()
window.open(`/ssh?id=${item.id}`)
}
let {local, ...hosts} = outputs;
return (
<div>
@ -173,6 +178,7 @@ function Ext1Console(props) {
<StepItem title="执行发布" item={item} step={3}/>
<StepItem title="发布后任务" item={item} step={4}/>
</Steps>
<CodeOutlined className={styles.codeIcon} onClick={e => openTerminal(e, item)}/>
</div>}>
<OutView setTerm={term => handleSetTerm(term, key)}/>
</Collapse.Panel>

View File

@ -6,7 +6,7 @@
import React, { useEffect, useState } from 'react';
import { observer, useLocalStore } from 'mobx-react';
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 { http, X_TOKEN } from 'libs';
import styles from './index.module.less';
@ -106,6 +106,11 @@ function Ext2Console(props) {
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');
return (
<div>
@ -180,6 +185,7 @@ function Ext2Console(props) {
<StepItem key={index} title={action.title} item={item} step={index + 1}/>
))}
</Steps>
<CodeOutlined className={styles.codeIcon} onClick={e => openTerminal(e, item)}/>
</div>}>
<OutView setTerm={term => handleSetTerm(term, item.id)}/>
</Collapse.Panel>

View File

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

View File

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