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:
Hornwitser committed 2023-07-27 17:50:14 +02:00
1 parent 8d98eaf3a5
commit fd709fd98c
22 files changed
+143 -127

No files matched your search

+3 -3
View File
@@ -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 -1
View File
@@ -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");
-1
View File
@@ -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",
+14 -14
View File
@@ -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"
+3 -2
View File
@@ -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}/>);
}
+10 -6
View File
@@ -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>
);
}
+3 -3
View File
@@ -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>;
+7 -7
View File
@@ -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"));
}}
>
+5 -5
View File
@@ -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`);
},
})}
/>
+17 -15
View File
@@ -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`);
},
})}
/>
+5 -5
View File
@@ -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`);
},
})}
/>
+19 -5
View File
@@ -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;
}
+3 -3
View File
@@ -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"
+3 -3
View File
@@ -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"
+3 -3
View File
@@ -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"