mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
Update web dependencies
- react: Update to new root rendering method - react-router: Replace useHistory with useNavigate - react-router: Replace <Switch> with <Routes> - reimplement sticky notice from scratch in ModPackViewPage - remove isomorphic-ws as it's latest version doesn't work and only saves one line of code. - remove import of antd.dark.css - fix misc css breakages.
This commit is contained in:
1 parent
8d98eaf3a5
commit
fd709fd98c
22 files changed
+143
-127
No files matched your search
@@ -35,9 +35,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@clusterio/web_ui": "^2.0.0-alpha.13",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.4.14",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-dev-middleware": "^6.1.1",
|
||||
"webpack-merge": "^5.9.0"
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const events = require("events");
|
||||
const WebSocket = require("isomorphic-ws");
|
||||
// eslint-disable-next-line node/no-process-env
|
||||
const WebSocket = process.env.APP_ENV === "browser" ? window.WebSocket : require("ws");
|
||||
|
||||
const libData = require("../data");
|
||||
const libErrors = require("../errors");
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
"chalk": "^4.1.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fs-extra": "^11.1.1",
|
||||
"isomorphic-ws": "^5.0.0",
|
||||
"jimp": "^0.22.8",
|
||||
"jsonwebtoken": "^9.0.1",
|
||||
"jszip": "^3.10.1",
|
||||
|
||||
@@ -15,30 +15,30 @@
|
||||
"node": ">=12"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.2.2",
|
||||
"@babel/core": "^7.13.8",
|
||||
"@babel/preset-react": "^7.12.13",
|
||||
"@ant-design/icons": "^5.1.4",
|
||||
"@babel/core": "^7.22.9",
|
||||
"@babel/preset-react": "^7.22.5",
|
||||
"@clusterio/lib": "^2.0.0-alpha.13",
|
||||
"antd": "^4.16.0",
|
||||
"antd": "^5.7.3",
|
||||
"assert": "^2.0.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"babel-loader": "^9.1.3",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"buffer": "^6.0.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"css-loader": "^5.1.0",
|
||||
"events": "^3.2.0",
|
||||
"buffer": "^6.0.3",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"css-loader": "^6.8.1",
|
||||
"events": "^3.3.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"null-loader": "^4.0.1",
|
||||
"os-browserify": "^0.3.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"process": "^0.11.10",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.14.2",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"style-loader": "^3.3.3",
|
||||
"terser-webpack-plugin": "^5.3.9",
|
||||
"util": "^0.12.3",
|
||||
"util": "^0.12.5",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-manifest-plugin": "^5.0.0"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import "./index.css";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { createRoot } from "react-dom/client";
|
||||
|
||||
import { libConfig, libLink, libLogging, libPlugin } from "@clusterio/lib";
|
||||
const { ConsoleTransport, WebConsoleFormat, logger } = libLogging;
|
||||
@@ -111,5 +111,6 @@ export default async function bootstrap() {
|
||||
let controlConnector = new ControlConnector(wsUrl, 120);
|
||||
let control = new Control(controlConnector, plugins);
|
||||
|
||||
ReactDOM.render(<App control={control}/>, document.getElementById("root"));
|
||||
const root = createRoot(document.getElementById("root"));
|
||||
root.render(<App control={control}/>);
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import SiteLayout from "./SiteLayout";
|
||||
import ControlContext from "./ControlContext";
|
||||
import LoginForm from "./LoginForm";
|
||||
|
||||
import { Card, Spin, Typography } from "antd";
|
||||
import { Card, ConfigProvider, Spin, Typography, theme } from "antd";
|
||||
|
||||
const { Paragraph } = Typography;
|
||||
const { logger } = libLogging;
|
||||
@@ -93,11 +93,15 @@ export default function App(props) {
|
||||
|
||||
return (
|
||||
<ErrorBoundary Component={ErrorCard}>
|
||||
<ControlContext.Provider value={props.control}>
|
||||
<BrowserRouter basename={webRoot}>
|
||||
{page}
|
||||
</BrowserRouter>
|
||||
</ControlContext.Provider>
|
||||
<ConfigProvider
|
||||
theme={{ algorithm: theme.darkAlgorithm }}
|
||||
>
|
||||
<ControlContext.Provider value={props.control}>
|
||||
<BrowserRouter basename={webRoot}>
|
||||
{page}
|
||||
</BrowserRouter>
|
||||
</ControlContext.Provider>
|
||||
</ConfigProvider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useRef, useState, useEffect } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, InputNumber, Modal, Table, Tag, Typography } from "antd";
|
||||
import CopyOutlined from "@ant-design/icons/lib/icons/CopyOutlined";
|
||||
|
||||
@@ -178,7 +178,7 @@ function CopyButton({ text, message }) {
|
||||
|
||||
export default function HostsPage() {
|
||||
let account = useAccount();
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [hostList] = useHostList();
|
||||
|
||||
return <PageLayout nav={[{ name: "Hosts" }]}>
|
||||
@@ -226,7 +226,7 @@ export default function HostsPage() {
|
||||
pagination={false}
|
||||
onRow={(record, rowIndex) => ({
|
||||
onClick: event => {
|
||||
history.push(`/hosts/${record.id}/view`);
|
||||
navigate(`/hosts/${record.id}/view`);
|
||||
},
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { message, Button, Space, Table } from "antd";
|
||||
import CopyOutlined from "@ant-design/icons/CopyOutlined";
|
||||
|
||||
@@ -12,7 +12,7 @@ const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "ba
|
||||
|
||||
export default function InstanceList(props) {
|
||||
let account = useAccount();
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [hostList] = useHostList();
|
||||
|
||||
function hostName(hostId) {
|
||||
@@ -102,7 +102,7 @@ export default function InstanceList(props) {
|
||||
pagination={false}
|
||||
onRow={(record, rowIndex) => ({
|
||||
onClick: event => {
|
||||
history.push(`/instances/${record.id}/view`);
|
||||
navigate(`/instances/${record.id}/view`);
|
||||
},
|
||||
})}
|
||||
/>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Alert, Button, Descriptions, Dropdown, Menu, Modal, Space, Spin, Typography } from "antd";
|
||||
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
|
||||
import DownOutlined from "@ant-design/icons/DownOutlined";
|
||||
@@ -60,7 +60,7 @@ export default function InstanceViewPage(props) {
|
||||
let params = useParams();
|
||||
let instanceId = Number(params.id);
|
||||
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
|
||||
let account = useAccount();
|
||||
let control = useContext(ControlContext);
|
||||
@@ -84,7 +84,7 @@ export default function InstanceViewPage(props) {
|
||||
action={
|
||||
<Button
|
||||
type="text"
|
||||
onClick={() => { history.push("/instances"); }}
|
||||
onClick={() => { navigate("/instances"); }}
|
||||
>
|
||||
Go back to instances list
|
||||
</Button>
|
||||
@@ -163,7 +163,7 @@ export default function InstanceViewPage(props) {
|
||||
control.send(
|
||||
new libData.InstanceDeleteRequest(instanceId)
|
||||
).then(() => {
|
||||
history.push("/instances");
|
||||
navigate("/instances");
|
||||
}).catch(notifyErrorHandler("Error deleting instance"));
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, Input, Modal } from "antd";
|
||||
|
||||
import { libConfig, libData } from "@clusterio/lib";
|
||||
@@ -15,7 +15,7 @@ import { notifyErrorHandler } from "../util/notify";
|
||||
|
||||
function CreateInstanceButton(props) {
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [open, setOpen] = useState(false);
|
||||
let [form] = Form.useForm();
|
||||
|
||||
@@ -32,7 +32,7 @@ function CreateInstanceButton(props) {
|
||||
let serializedConfig = instanceConfig.serialize("controller");
|
||||
await control.send(new libData.InstanceCreateRequest(serializedConfig));
|
||||
setOpen(false);
|
||||
history.push(`/instances/${instanceConfig.get("instance.id")}/view`);
|
||||
navigate(`/instances/${instanceConfig.get("instance.id")}/view`);
|
||||
}
|
||||
|
||||
return <>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Fragment, memo, useCallback, useEffect, useContext, useRef, useState } from "react";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import {
|
||||
Button, Card, Checkbox, Col, ConfigProvider, Descriptions, Form, Input, Pagination,
|
||||
Popconfirm, Row, Table, Tag, Typography, Select, Skeleton, Space, Spin, Switch, Modal, Tooltip,
|
||||
@@ -599,7 +599,7 @@ function applyModPackChanges(modPack, changes) {
|
||||
|
||||
export default function ModPackViewPage() {
|
||||
let account = useAccount();
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let control = useContext(ControlContext);
|
||||
let params = useParams();
|
||||
let modPackId = Number(params.id);
|
||||
@@ -709,7 +709,7 @@ export default function ModPackViewPage() {
|
||||
control.send(
|
||||
new libData.ModPackDeleteRequest(modPack.id)
|
||||
).then(() => {
|
||||
history.push("/mods");
|
||||
navigate("/mods");
|
||||
}).catch(notifyErrorHandler("Error deleting mod pack"));
|
||||
}}
|
||||
>
|
||||
@@ -783,40 +783,35 @@ export default function ModPackViewPage() {
|
||||
</Form>
|
||||
|
||||
<div
|
||||
className="ant-notification ant-notification-bottom"
|
||||
className="sticky-notice"
|
||||
style={{
|
||||
visibility: changes.length ? "visible" : "hidden",
|
||||
inset: "auto auto 24px auto",
|
||||
position: "sticky",
|
||||
marginTop: 16,
|
||||
}}
|
||||
>
|
||||
<div className="ant-notification-notice" style={{ width: "auto", maxWidth: 384, marginBottom: 0 }}>
|
||||
<Row style={{ alignItems: "center", rowGap: 12 }}>
|
||||
<Col flex="auto">You have unsaved changes</Col>
|
||||
<Col flex="0 0 auto" style={{ marginLeft: "auto" }}>
|
||||
<Space>
|
||||
<Button
|
||||
onClick={() => {
|
||||
<Row style={{ alignItems: "center", rowGap: 12 }}>
|
||||
<Col flex="auto">You have unsaved changes</Col>
|
||||
<Col flex="0 0 auto" style={{ marginLeft: "auto" }}>
|
||||
<Space>
|
||||
<Button
|
||||
onClick={() => {
|
||||
form.resetFields();
|
||||
setChanges([]);
|
||||
}}
|
||||
>Revert</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.ModPackUpdateRequest(modifiedModPack)
|
||||
).then(() => {
|
||||
form.resetFields();
|
||||
setChanges([]);
|
||||
}}
|
||||
>Revert</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.ModPackUpdateRequest(modifiedModPack)
|
||||
).then(() => {
|
||||
form.resetFields();
|
||||
setChanges([]);
|
||||
}).catch(notifyErrorHandler("Error deleting mod pack"));
|
||||
}}
|
||||
>Apply</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
}).catch(notifyErrorHandler("Error deleting mod pack"));
|
||||
}}
|
||||
>Apply</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</PageLayout>;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Fragment, useState, useContext } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, Input, Modal, Popconfirm, Space, Table, Typography, Upload } from "antd";
|
||||
import ImportOutlined from "@ant-design/icons/ImportOutlined";
|
||||
import PlusOutlined from "@ant-design/icons/PlusOutlined";
|
||||
@@ -25,7 +25,7 @@ const { logger } = libLogging;
|
||||
|
||||
function ImportModPackButton() {
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [open, setOpen] = useState(false);
|
||||
let [form] = Form.useForm();
|
||||
function close() {
|
||||
@@ -49,7 +49,7 @@ function ImportModPackButton() {
|
||||
}
|
||||
const modPack = libData.ModPack.fromModPackString(values.string);
|
||||
await control.send(new libData.ModPackCreateRequest(modPack));
|
||||
history.push(`/mods/mod-packs/${modPack.id}/view`);
|
||||
navigate(`/mods/mod-packs/${modPack.id}/view`);
|
||||
})().catch(notifyErrorHandler("Error creating mod pack"));
|
||||
}}
|
||||
>
|
||||
@@ -74,7 +74,7 @@ function ImportModPackButton() {
|
||||
|
||||
function CreateModPackButton() {
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [open, setOpen] = useState(false);
|
||||
let [form] = Form.useForm();
|
||||
function close() {
|
||||
@@ -101,7 +101,7 @@ function CreateModPackButton() {
|
||||
modPack.factorioVersion = values.factorioVersion;
|
||||
if (values.description) { modPack.description = values.description; }
|
||||
await control.send(new libData.ModPackCreateRequest(modPack.toJSON()));
|
||||
history.push(`/mods/mod-packs/${modPack.id}/view`);
|
||||
navigate(`/mods/mod-packs/${modPack.id}/view`);
|
||||
})().catch(notifyErrorHandler("Error creating mod pack"));
|
||||
}}
|
||||
>
|
||||
@@ -131,7 +131,7 @@ function CreateModPackButton() {
|
||||
export default function ModsPage() {
|
||||
let account = useAccount();
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [modList] = useModList();
|
||||
let [modPackList] = useModPackList();
|
||||
|
||||
@@ -217,7 +217,7 @@ export default function ModsPage() {
|
||||
rowKey={modPack => modPack.id}
|
||||
onRow={(modPack, rowIndex) => ({
|
||||
onClick: event => {
|
||||
history.push(`/mods/mod-packs/${modPack.id}/view`);
|
||||
navigate(`/mods/mod-packs/${modPack.id}/view`);
|
||||
},
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Table } from "antd";
|
||||
|
||||
import notify from "../util/notify";
|
||||
@@ -11,7 +11,7 @@ const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "ba
|
||||
|
||||
export default function PluginsPage() {
|
||||
let plugins = useContext(ControlContext).plugins;
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [pluginList, setPluginList] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -79,7 +79,7 @@ export default function PluginsPage() {
|
||||
pagination={false}
|
||||
onRow={plugin => ({
|
||||
onClick: event => {
|
||||
history.push(`/plugins/${plugin.meta.name}/view`);
|
||||
navigate(`/plugins/${plugin.meta.name}/view`);
|
||||
},
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useContext, useState } from "react";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Button, Checkbox, Form, Input, Popconfirm, Spin } from "antd";
|
||||
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function RoleViewPage() {
|
||||
let params = useParams();
|
||||
let roleId = Number(params.id);
|
||||
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
|
||||
let account = useAccount();
|
||||
let control = useContext(ControlContext);
|
||||
@@ -108,7 +108,7 @@ export default function RoleViewPage() {
|
||||
control.send(
|
||||
new libData.RoleDeleteRequest(roleId)
|
||||
).then(() => {
|
||||
history.push("/roles");
|
||||
navigate("/roles");
|
||||
}).catch(notifyErrorHandler("Error deleting role"));
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, Input, Modal, Table } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
@@ -16,7 +16,7 @@ const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "ba
|
||||
|
||||
function CreateRoleButton() {
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [open, setOpen] = useState(false);
|
||||
let [form] = Form.useForm();
|
||||
|
||||
@@ -31,7 +31,7 @@ function CreateRoleButton() {
|
||||
new libData.RoleCreateRequest(values.roleName, values.description || "", [])
|
||||
);
|
||||
setOpen(false);
|
||||
history.push(`/roles/${result.id}/view`);
|
||||
navigate(`/roles/${result.id}/view`);
|
||||
}
|
||||
|
||||
return <>
|
||||
@@ -62,7 +62,7 @@ function CreateRoleButton() {
|
||||
export default function RolesPage() {
|
||||
let account = useAccount();
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
|
||||
let [roles, setRoles] = useState([]);
|
||||
|
||||
@@ -94,7 +94,7 @@ export default function RolesPage() {
|
||||
rowKey={role => role.id}
|
||||
onRow={(role, rowIndex) => ({
|
||||
onClick: event => {
|
||||
history.push(`/roles/${role.id}/view`);
|
||||
navigate(`/roles/${role.id}/view`);
|
||||
},
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { Switch, Route, useHistory } from "react-router-dom";
|
||||
import { Route, Routes, useNavigate } from "react-router-dom";
|
||||
import { Dropdown, Layout, Menu } from "antd";
|
||||
import UserOutlined from "@ant-design/icons/UserOutlined";
|
||||
import webUiPackage from "../../package.json";
|
||||
@@ -14,7 +14,7 @@ const { Header, Sider } = Layout;
|
||||
|
||||
|
||||
export default function SiteLayout(props) {
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [currentSidebarPath, setCurrentSidebarPath] = useState(null);
|
||||
let account = useAccount();
|
||||
let plugins = useContext(ControlContext).plugins;
|
||||
@@ -29,7 +29,7 @@ export default function SiteLayout(props) {
|
||||
let accountMenuProps = {
|
||||
onClick: ({ key }) => {
|
||||
if (key === "user") {
|
||||
history.push(`/users/${account.name}/view`);
|
||||
navigate(`/users/${account.name}/view`);
|
||||
} else if (key === "logOut") {
|
||||
account.logOut();
|
||||
}
|
||||
@@ -107,22 +107,24 @@ export default function SiteLayout(props) {
|
||||
defaultOpenKeys={[...menuGroups.keys()]}
|
||||
selectedKeys={[currentSidebarPath]}
|
||||
style={{ height: "100%", borderRight: 0 }}
|
||||
onClick={({ key }) => history.push(key)}
|
||||
onClick={({ key }) => navigate(key)}
|
||||
items={menuItems}
|
||||
/>
|
||||
</Sider>
|
||||
<Layout className="site-layout-content-container">
|
||||
<Switch>
|
||||
{combinedPages.map(({path, sidebarPath, content}) => <Route exact path={path} key={path}>
|
||||
<SetSidebar path={sidebarPath ? sidebarPath : path} />
|
||||
<ErrorBoundary Component={ErrorPage}>
|
||||
{content}
|
||||
</ErrorBoundary>
|
||||
</Route>)}
|
||||
<Route>
|
||||
<SetSidebar path={null} />
|
||||
</Route>
|
||||
</Switch>
|
||||
<Routes>
|
||||
{combinedPages.map(({path, sidebarPath, content}) => <Route
|
||||
path={path}
|
||||
key={path}
|
||||
element={<>
|
||||
<SetSidebar path={sidebarPath ? sidebarPath : path} />
|
||||
<ErrorBoundary Component={ErrorPage}>
|
||||
{content}
|
||||
</ErrorBoundary>
|
||||
</>}
|
||||
/>)}
|
||||
<Route element={<SetSidebar path={null} />} />
|
||||
</Routes>
|
||||
</Layout>
|
||||
</Layout>
|
||||
</Layout>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useContext, useState } from "react";
|
||||
import { useHistory, useParams } from "react-router-dom";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import {
|
||||
Button, Col, Descriptions, Form, Input, Popconfirm,
|
||||
Row, Table, Tag, Select, Space, Spin, Switch,
|
||||
@@ -29,7 +29,7 @@ export default function UserViewPage() {
|
||||
let params = useParams();
|
||||
let userName = params.name;
|
||||
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
|
||||
let account = useAccount();
|
||||
let control = useContext(ControlContext);
|
||||
@@ -147,7 +147,7 @@ export default function UserViewPage() {
|
||||
control.send(
|
||||
new libData.UserDeleteRequest(userName)
|
||||
).then(() => {
|
||||
history.push("/users");
|
||||
navigate("/users");
|
||||
}).catch(notifyErrorHandler("Error deleting user"));
|
||||
}}
|
||||
>
|
||||
@@ -333,7 +333,7 @@ export default function UserViewPage() {
|
||||
rowKey={([id]) => id}
|
||||
onRow={([id], rowIndex) => ({
|
||||
onClick: event => {
|
||||
history.push(`/instances/${id}/view`);
|
||||
navigate(`/instances/${id}/view`);
|
||||
},
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useContext, useState } from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, Input, Modal, Space, Table, Tag } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
@@ -18,7 +18,7 @@ const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "ba
|
||||
|
||||
function CreateUserButton() {
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [open, setOpen] = useState(false);
|
||||
let [form] = Form.useForm();
|
||||
|
||||
@@ -31,7 +31,7 @@ function CreateUserButton() {
|
||||
|
||||
await control.send(new libData.UserCreateRequest(values.userName));
|
||||
setOpen(false);
|
||||
history.push(`/users/${values.userName}/view`);
|
||||
navigate(`/users/${values.userName}/view`);
|
||||
}
|
||||
|
||||
return <>
|
||||
@@ -59,7 +59,7 @@ function CreateUserButton() {
|
||||
export default function UsersPage() {
|
||||
let account = useAccount();
|
||||
let control = useContext(ControlContext);
|
||||
let history = useHistory();
|
||||
let navigate = useNavigate();
|
||||
let [userList] = useUserList();
|
||||
|
||||
let [roles, setRoles] = useState(new Map());
|
||||
@@ -120,7 +120,7 @@ export default function UsersPage() {
|
||||
rowKey={user => user.name}
|
||||
onRow={(user, rowIndex) => ({
|
||||
onClick: event => {
|
||||
history.push(`/users/${user.name}/view`);
|
||||
navigate(`/users/${user.name}/view`);
|
||||
},
|
||||
})}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
@import '~antd/dist/antd.dark.css';
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
@@ -157,7 +155,8 @@ body {
|
||||
height: 64px;
|
||||
font-size: 18px;
|
||||
line-height: 72px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.account-dropdown-header::after {
|
||||
@@ -339,8 +338,8 @@ body {
|
||||
border: none;
|
||||
}
|
||||
|
||||
tr.no-expanded-padding > td,
|
||||
.ant-table.ant-table-small .ant-table-tbody > tr.no-expanded-padding > td {
|
||||
div.ant-table tr.no-expanded-padding > td,
|
||||
div.ant-table.ant-table-small .ant-table-tbody > tr.no-expanded-padding > td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -368,3 +367,18 @@ tr.ant-table-row.deleted {
|
||||
tr.ant-table-row.deleted {
|
||||
background: #441c18;
|
||||
}
|
||||
|
||||
.sticky-notice {
|
||||
position: sticky;
|
||||
inset: auto auto 24px auto;
|
||||
background: #1f1f1f;
|
||||
padding: 24px;
|
||||
width: auto;
|
||||
margin: 16px auto 0;
|
||||
box-shadow:
|
||||
0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 8px;
|
||||
max-width: 384px;
|
||||
}
|
||||
@@ -25,9 +25,9 @@
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.13",
|
||||
"@clusterio/web_ui": "^2.0.0-alpha.13",
|
||||
"antd": "^4.16.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"antd": "^5.7.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^5.9.0"
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.13",
|
||||
"@clusterio/web_ui": "^2.0.0-alpha.13",
|
||||
"antd": "^4.16.0",
|
||||
"antd": "^5.7.3",
|
||||
"phin": "^3.7.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^5.9.0"
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
"devDependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.13",
|
||||
"@clusterio/web_ui": "^2.0.0-alpha.13",
|
||||
"antd": "^4.16.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"antd": "^5.7.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^5.9.0"
|
||||
|
||||
Reference in new issue
Block a user