mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 15:24:52 +09:00
Add account button with log out
Add a button on the right of the top nav bar to access account related functions and add a log out button there. To make it fit on the navbar the text and version is hidden on narrow layouts.
This commit is contained in:
1 parent
9542246414
commit
e1549c1b0c
5 files changed
+106
-6
No files matched your search
@@ -55,8 +55,13 @@ export default function App(props) {
|
||||
connector.on("error", onError);
|
||||
|
||||
if (token && !connected) {
|
||||
connector.token = token;
|
||||
connector.connect();
|
||||
if (props.control.loggingOut) {
|
||||
clearToken();
|
||||
props.control.loggingOut = false;
|
||||
} else {
|
||||
connector.token = token;
|
||||
connector.connect();
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Switch, Route, useHistory } from "react-router-dom";
|
||||
import { Layout, Menu } from "antd";
|
||||
import { Dropdown, Layout, Menu } from "antd";
|
||||
import UserOutlined from "@ant-design/icons/UserOutlined";
|
||||
import webUiPackage from "../../package.json";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ErrorBoundary from "./ErrorBoundary";
|
||||
import ErrorPage from "./ErrorPage";
|
||||
|
||||
@@ -40,6 +42,7 @@ const sidebar = [
|
||||
export default function SiteLayout(props) {
|
||||
let history = useHistory();
|
||||
let [sidebarPath, setSidebarPath] = useState(null);
|
||||
let account = useAccount();
|
||||
|
||||
function SetSidebar(setSidebarProps) {
|
||||
useEffect(() => {
|
||||
@@ -48,14 +51,27 @@ export default function SiteLayout(props) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let accountMenu = <Menu>
|
||||
<Menu.Item danger onClick={() => { account.logOut(); }}>Log out</Menu.Item>
|
||||
</Menu>;
|
||||
|
||||
|
||||
return <Layout style={{ minHeight: "100vh" }}>
|
||||
<Header className="header">
|
||||
<div className="site-logo" />
|
||||
<span className="site-name" style={{ top: -10 }}>Clusterio</span>
|
||||
<span style={{ position: "absolute", top: 10, left: 120, color: "#f00" }}>{ webUiPackage.version }</span>
|
||||
<span className="site-name">Clusterio</span>
|
||||
<span className="site-version">{ webUiPackage.version }</span>
|
||||
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={["1"]}>
|
||||
<Menu.Item key="1">Dashboard</Menu.Item>
|
||||
</Menu>
|
||||
<Dropdown
|
||||
className="account-dropdown-header"
|
||||
placement="bottomRight"
|
||||
trigger="click"
|
||||
overlay={accountMenu}
|
||||
>
|
||||
<UserOutlined/>
|
||||
</Dropdown>
|
||||
</Header>
|
||||
<Layout className="site-layout">
|
||||
<Sider
|
||||
|
||||
@@ -64,15 +64,24 @@ body {
|
||||
|
||||
.header {
|
||||
padding-left: 250px;
|
||||
padding-right: 64px;
|
||||
}
|
||||
|
||||
.site-name {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
left: 112px;
|
||||
font-size: 18pt;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.site-version {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 120px;
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.site-logo {
|
||||
position: absolute;
|
||||
left: 36px;
|
||||
@@ -82,6 +91,50 @@ body {
|
||||
background-size: 64px;
|
||||
}
|
||||
|
||||
@media not all and (min-width: 576px) {
|
||||
.header {
|
||||
padding-left: 88px;
|
||||
}
|
||||
|
||||
.site-logo {
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
.site-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-version {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.account-dropdown-header {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
font-size: 18px;
|
||||
line-height: 72px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.account-dropdown-header::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: transparent;
|
||||
transition: all 0.3s;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.account-dropdown-header:hover::after {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.error-traceback code {
|
||||
display: block;
|
||||
margin: 0;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useContext } from "react";
|
||||
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
/**
|
||||
* @typedef {Object} Account
|
||||
* @property {function()} logout - Logs out of the web interface.
|
||||
*/
|
||||
|
||||
export function useAccount() {
|
||||
let control = useContext(ControlContext);
|
||||
|
||||
return {
|
||||
logOut() {
|
||||
control.loggingOut = true;
|
||||
control.shutdown(notifyErrorHandler("Error logging out"));
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -49,6 +49,12 @@ export class Control extends libLink.Link {
|
||||
libPlugin.attachPluginMessages(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag indicating the connection is in the process of logging out.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.loggingOut = false;
|
||||
|
||||
this.instanceLogHandlers = new Map();
|
||||
|
||||
this.connector.on("connect", () => {
|
||||
@@ -120,7 +126,7 @@ export class Control extends libLink.Link {
|
||||
}
|
||||
|
||||
async shutdown() {
|
||||
this.connector.setTimeout(30);
|
||||
this.connector.setTimeout(5);
|
||||
|
||||
try {
|
||||
await libLink.messages.prepareDisconnect.send(this);
|
||||
|
||||
Reference in new issue
Block a user