diff --git a/.eslintrc.js b/.eslintrc.js index 14045381..ba9eaec6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -21,7 +21,7 @@ module.exports = { }, }, { - "files": ["packages/master/web/**/*.jsx"], + "files": ["packages/web_ui/src/**/*.jsx", "plugins/*/web/**/*.jsx"], "env": { "browser": true, }, diff --git a/packages/web_ui/src/bootstrap.jsx b/packages/web_ui/src/bootstrap.jsx index f534ccac..4036075c 100644 --- a/packages/web_ui/src/bootstrap.jsx +++ b/packages/web_ui/src/bootstrap.jsx @@ -8,6 +8,7 @@ import libConfig from "@clusterio/lib/config"; import App from "./components/App"; import { Control, ControlConnector } from "./util/websocket"; + async function loadScript(url) { let script = document.createElement("script"); script.src = url; @@ -61,17 +62,11 @@ async function load() { let wsUrl = new URL(window.webRoot, document.location); wsUrl.protocol = wsUrl.protocol.replace("http", "ws"); - let controlConnector = new ControlConnector(wsUrl, 10, localStorage.getItem("master_token")); + let controlConnector = new ControlConnector(wsUrl, 10); // XXX come up with a better way of sharing this window.control = new Control(controlConnector, []); - try { - await controlConnector.connect(); - } catch (err) { - // XXX: What now? - console.log(err); - } - ReactDOM.render(, document.getElementById("root")); + ReactDOM.render(, document.getElementById("root")); } load().catch(console.log); diff --git a/packages/web_ui/src/components/App.jsx b/packages/web_ui/src/components/App.jsx index 10c155b0..113cd2cf 100644 --- a/packages/web_ui/src/components/App.jsx +++ b/packages/web_ui/src/components/App.jsx @@ -1,13 +1,85 @@ -import React from "react"; +import events from "events"; +import React, { useEffect, useState } from "react"; import { BrowserRouter } from "react-router-dom"; import basename from "../basename"; -import Layout from "../layout"; +import SiteLayout from "../layout"; +import ControlContext from "./ControlContext"; +import LoginForm from "./LoginForm"; + +import { Card, Spin } from "antd"; + + +export default function App(props) { + let [connected, setConnected] = useState(false); + let [token, setToken] = useState(localStorage.getItem("master_token") || null); + let connector = props.control.connector; + + function clearToken() { + setToken(null); + localStorage.removeItem("master_token"); + } + + useEffect(() => { + console.log("Effect called"); + + function onConnect() { + localStorage.setItem("master_token", token); + setConnected(true); + } + + function onClose() { + setConnected(false); + } + + function onError(err) { + console.error("Unexpected error in connector", err); + clearToken(); + setConnected(false); + } + + connector.on("connect", onConnect); + connector.on("close", onClose); + connector.on("error", onError); + + if (token && !connected) { + connector.token = token; + connector.connect(); + } + + return () => { + connector.off("error", onError); + connector.off("close", onClose); + connector.off("connect", onConnect); + }; + }); + + let page; + if (connected) { + page = ; + + } else if (token) { + page =
+ +

Connecting

+ +
+
; + + } else { + page =
+ +

Clusterio

+ +
+
; + } -export default function App() { return ( - - - + + + {page} + + ); } diff --git a/packages/web_ui/src/components/ControlContext.jsx b/packages/web_ui/src/components/ControlContext.jsx new file mode 100644 index 00000000..979faf93 --- /dev/null +++ b/packages/web_ui/src/components/ControlContext.jsx @@ -0,0 +1,3 @@ +import React from "react"; + +export default React.createContext(); diff --git a/packages/web_ui/src/components/LoginForm.jsx b/packages/web_ui/src/components/LoginForm.jsx new file mode 100644 index 00000000..6a5a13cf --- /dev/null +++ b/packages/web_ui/src/components/LoginForm.jsx @@ -0,0 +1,27 @@ +import React from "react"; +import { Form, Input, Button } from "antd"; +import LockOutlined from "@ant-design/icons/LockOutlined"; + +export default function LoginForm(props) { + return ( +
{ props.setToken(values.token); }} + > + + } + type="password" + placeholder="Authentication Token" + /> + + +
+ ); +} + diff --git a/packages/web_ui/src/index.css b/packages/web_ui/src/index.css index fa33de59..f79dd7ad 100644 --- a/packages/web_ui/src/index.css +++ b/packages/web_ui/src/index.css @@ -23,3 +23,9 @@ code { cursor: pointer; } +.login-container { + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; +} diff --git a/packages/web_ui/src/layout/index.jsx b/packages/web_ui/src/layout/index.jsx index 76f6ce24..1dd23a73 100644 --- a/packages/web_ui/src/layout/index.jsx +++ b/packages/web_ui/src/layout/index.jsx @@ -12,7 +12,6 @@ import { PermissionsTable } from "../pages/permissions/permissionsTable"; import { InstanceView } from "../pages/instances/instance"; import { UserView } from "../pages/users/user"; import { RoleView } from "../pages/roles/role"; -import { Settings } from "../pages/settings/settings"; const { Content, Footer, Sider } = Layout; const { SubMenu } = Menu; @@ -118,10 +117,6 @@ class SiteLayout extends Component { Permissions - - Settings - - ) : ( @@ -149,7 +144,6 @@ class SiteLayout extends Component { -