提交 1.3.0-beta4
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "next-terminal",
|
||||
"version": "1.3.0-beta3",
|
||||
"version": "1.3.0-beta4",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/charts": "^1.4.2",
|
||||
|
3
web/src/components/access/Guacd.css
Normal file
3
web/src/components/access/Guacd.css
Normal file
@ -0,0 +1,3 @@
|
||||
#display > div {
|
||||
margin: 0 auto;
|
||||
}
|
@ -19,6 +19,7 @@ import Draggable from "react-draggable";
|
||||
import FileSystem from "../devops/FileSystem";
|
||||
import GuacdClipboard from "./GuacdClipboard";
|
||||
import {debounce} from "../../utils/fun";
|
||||
import './Guacd.css';
|
||||
|
||||
let fixedSize = false;
|
||||
|
||||
@ -74,17 +75,15 @@ const Guacd = () => {
|
||||
tunnel.onerror = onError;
|
||||
|
||||
// Get display div from document
|
||||
const display = document.getElementById("display");
|
||||
const displayEle = document.getElementById("display");
|
||||
|
||||
// Add client to display div
|
||||
const element = client.getDisplay().getElement();
|
||||
display.appendChild(element);
|
||||
displayEle.appendChild(element);
|
||||
|
||||
let scale = 1;
|
||||
let dpi = 96;
|
||||
if (protocol === 'telnet') {
|
||||
dpi = dpi * 2;
|
||||
scale = 0.5;
|
||||
}
|
||||
|
||||
let token = getToken();
|
||||
@ -99,21 +98,31 @@ const Guacd = () => {
|
||||
let paramStr = qs.stringify(params);
|
||||
|
||||
client.connect(paramStr);
|
||||
let display = client.getDisplay();
|
||||
display.onresize = function (width, height) {
|
||||
display.scale(Math.min(
|
||||
window.innerHeight / display.getHeight(),
|
||||
window.innerWidth / display.getHeight()
|
||||
))
|
||||
}
|
||||
|
||||
const mouse = new Guacamole.Mouse(element);
|
||||
|
||||
mouse.onmousedown = mouse.onmouseup = function (mouseState) {
|
||||
mouse.onmousedown = mouse.onmouseup = mouse.onmousemove = function (mouseState) {
|
||||
client.getDisplay().showCursor(false);
|
||||
mouseState.x = mouseState.x / display.getScale();
|
||||
mouseState.y = mouseState.y / display.getScale();
|
||||
client.sendMouseState(mouseState);
|
||||
};
|
||||
|
||||
mouse.onmousemove = function (mouseState) {
|
||||
mouseState.x = mouseState.x / scale;
|
||||
mouseState.y = mouseState.y / scale;
|
||||
client.sendMouseState(mouseState);
|
||||
const touch = new Guacamole.Mouse.Touchpad(element); // or Guacamole.Touchscreen
|
||||
|
||||
touch.onmousedown = touch.onmousemove = touch.onmouseup = function (state) {
|
||||
client.sendMouseState(state);
|
||||
};
|
||||
|
||||
const sink = new Guacamole.InputSink();
|
||||
display.appendChild(sink.getElement());
|
||||
displayEle.appendChild(sink.getElement());
|
||||
sink.focus();
|
||||
|
||||
const keyboard = new Guacamole.Keyboard(sink.getElement());
|
||||
@ -130,7 +139,6 @@ const Guacd = () => {
|
||||
|
||||
setGuacd({
|
||||
client,
|
||||
scale,
|
||||
sink,
|
||||
});
|
||||
}
|
||||
@ -162,17 +170,12 @@ const Guacd = () => {
|
||||
}, [guacd])
|
||||
|
||||
const onWindowResize = () => {
|
||||
console.log(guacd, fixedSize);
|
||||
if (guacd.client && !fixedSize) {
|
||||
const display = guacd.client.getDisplay();
|
||||
let scale = guacd.scale;
|
||||
display.scale(scale);
|
||||
let width = window.innerWidth;
|
||||
let height = window.innerHeight;
|
||||
|
||||
guacd.client.sendSize(width / scale, height / scale);
|
||||
|
||||
setBox({width, height})
|
||||
display.scale(Math.min(
|
||||
window.innerHeight / display.getHeight(),
|
||||
window.innerWidth / display.getHeight()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -438,7 +441,6 @@ const Guacd = () => {
|
||||
<div>
|
||||
|
||||
<div className="container" style={{
|
||||
overflow: 'hidden',
|
||||
width: box.width,
|
||||
height: box.height,
|
||||
margin: '0 auto'
|
||||
|
@ -88,19 +88,6 @@ const Term = () => {
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (term && websocket && fitAddon && websocket.readyState === WebSocket.OPEN) {
|
||||
fit();
|
||||
focus();
|
||||
let terminalSize = {
|
||||
cols: term.cols,
|
||||
rows: term.rows
|
||||
}
|
||||
websocket.send(new Message(Message.Resize, window.btoa(JSON.stringify(terminalSize))).toString());
|
||||
}
|
||||
|
||||
}, [box.width, box.height]);
|
||||
|
||||
const onWindowResize = () => {
|
||||
setBox({width: window.innerWidth, height: window.innerHeight});
|
||||
};
|
||||
@ -225,9 +212,20 @@ const Term = () => {
|
||||
|
||||
useEffect(() => {
|
||||
document.title = assetName;
|
||||
window.addEventListener('beforeunload', handleUnload);
|
||||
|
||||
init(assetId);
|
||||
}, [assetId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (term && websocket && fitAddon && websocket.readyState === WebSocket.OPEN) {
|
||||
fit();
|
||||
focus();
|
||||
let terminalSize = {
|
||||
cols: term.cols,
|
||||
rows: term.rows
|
||||
}
|
||||
websocket.send(new Message(Message.Resize, window.btoa(JSON.stringify(terminalSize))).toString());
|
||||
}
|
||||
window.addEventListener('beforeunload', handleUnload);
|
||||
|
||||
let resize = debounce(() => {
|
||||
onWindowResize();
|
||||
@ -242,7 +240,7 @@ const Term = () => {
|
||||
window.removeEventListener('resize', resize);
|
||||
window.removeEventListener('beforeunload', handleUnload);
|
||||
}
|
||||
}, [assetId]);
|
||||
}, [box.width, box.height]);
|
||||
|
||||
const cmdMenuItems = commands.map(item => {
|
||||
return {
|
||||
|
@ -44,6 +44,7 @@ function downloadImportExampleCsv() {
|
||||
|
||||
const importExampleContent = <>
|
||||
<a onClick={downloadImportExampleCsv}>下载示例</a>
|
||||
<div>导入资产时,账号、密码和密钥、密码属于二选一,都填写时优先选择私钥和密码。</div>
|
||||
</>
|
||||
|
||||
const Asset = () => {
|
||||
@ -295,9 +296,9 @@ const Asset = () => {
|
||||
setSelectedRowKeys([]);
|
||||
}
|
||||
|
||||
const handleImportAsset = (file) => {
|
||||
const handleImportAsset = async (file) => {
|
||||
|
||||
let [success, data] = api.importAsset(file);
|
||||
let [success, data] = await api.importAsset(file);
|
||||
if (success === false) {
|
||||
notification['error']({
|
||||
message: '导入资产失败',
|
||||
@ -320,7 +321,7 @@ const Asset = () => {
|
||||
});
|
||||
}
|
||||
actionRef.current.reload();
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const handleChangeOwner = (row) => {
|
||||
@ -397,6 +398,7 @@ const Asset = () => {
|
||||
<Upload
|
||||
maxCount={1}
|
||||
beforeUpload={handleImportAsset}
|
||||
showUploadList={false}
|
||||
>
|
||||
<Button key='import'>导入</Button>
|
||||
</Upload>
|
||||
@ -461,6 +463,8 @@ const Asset = () => {
|
||||
actionRef.current.reload();
|
||||
} finally {
|
||||
setConfirmLoading(false);
|
||||
setSelectedRowKey(undefined);
|
||||
setCopied(false);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
@ -116,7 +116,10 @@ const ManagerLayout = () => {
|
||||
<Popconfirm
|
||||
key='login-btn-pop'
|
||||
title="您确定要退出登录吗?"
|
||||
onConfirm={accountApi.logout}
|
||||
onConfirm={async ()=>{
|
||||
await accountApi.logout();
|
||||
navigate('/login');
|
||||
}}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
placement="left"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, {Suspense, useEffect} from 'react';
|
||||
import {Link, Outlet, useLocation} from "react-router-dom";
|
||||
import {Link, Outlet, useLocation, useNavigate} from "react-router-dom";
|
||||
import {Breadcrumb, Button, Dropdown, Layout, Menu, Popconfirm} from "antd";
|
||||
import {
|
||||
CodeOutlined,
|
||||
@ -27,6 +27,8 @@ const breadcrumbNameMap = {
|
||||
const UserLayout = () => {
|
||||
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
let _current = location.pathname.split('/')[1];
|
||||
|
||||
useEffect(() => {
|
||||
@ -63,7 +65,10 @@ const UserLayout = () => {
|
||||
<Popconfirm
|
||||
key='login-btn-pop'
|
||||
title="您确定要退出登录吗?"
|
||||
onConfirm={accountApi.logout}
|
||||
onConfirm={async ()=>{
|
||||
await accountApi.logout();
|
||||
navigate('/login');
|
||||
}}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
placement="left"
|
||||
|
Reference in New Issue
Block a user