From a67a4a41dab8f23aef7ea3723d16f67e242f6d85 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 9 Dec 2023 17:18:59 +0100 Subject: [PATCH 1/4] Use separate build for web version of lib Use a separate ES Module based build for the web version of the lib package. This fixes the rebuild on watched files changing in lib failing with a TS1479 error. --- packages/controller/tsconfig.web.json | 2 +- packages/lib/.npmignore | 1 + packages/lib/src/ExponentialBackoff.ts | 2 -- packages/lib/tsconfig.web.json | 30 +++++++++++++++++++ packages/web_ui/tsconfig.web.json | 2 +- plugins/global_chat/tsconfig.web.json | 2 +- plugins/inventory_sync/tsconfig.web.json | 2 +- plugins/player_auth/tsconfig.web.json | 2 +- plugins/research_sync/tsconfig.web.json | 2 +- plugins/statistics_exporter/tsconfig.web.json | 2 +- plugins/subspace_storage/tsconfig.web.json | 2 +- tsconfig.json | 1 + 12 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 packages/lib/tsconfig.web.json diff --git a/packages/controller/tsconfig.web.json b/packages/controller/tsconfig.web.json index 01d0c42f..6685a163 100644 --- a/packages/controller/tsconfig.web.json +++ b/packages/controller/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../lib" }, + { "path": "../lib/tsconfig.web.json" }, { "path": "../web_ui/tsconfig.web.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], diff --git a/packages/lib/.npmignore b/packages/lib/.npmignore index e69de29b..5dfa68f1 100644 --- a/packages/lib/.npmignore +++ b/packages/lib/.npmignore @@ -0,0 +1 @@ +dist/web/build diff --git a/packages/lib/src/ExponentialBackoff.ts b/packages/lib/src/ExponentialBackoff.ts index 1e5550b5..38b13eb9 100644 --- a/packages/lib/src/ExponentialBackoff.ts +++ b/packages/lib/src/ExponentialBackoff.ts @@ -77,5 +77,3 @@ export default class ExponentialBackoff { return Math.random() * this.base * 2 ** this._exp * 1000; } } - -module.exports = ExponentialBackoff; diff --git a/packages/lib/tsconfig.web.json b/packages/lib/tsconfig.web.json new file mode 100644 index 00000000..a4349659 --- /dev/null +++ b/packages/lib/tsconfig.web.json @@ -0,0 +1,30 @@ +{ + "extends": "../../tsconfig.web.json", + "include": [ + "browser.ts", + "package.json", + "./src/api.ts", + "./src/config/*.ts", + "./src/data/*.ts", + "./src/errors.ts", + "./src/factorio/exchange_string.ts", + "./src/helpers.ts", + "./src/hash.ts", + "./src/ini.ts", + "./src/link/*.ts", + "./src/logging.ts", + "./src/permissions.ts", + "./src/prometheus.ts", + "./src/plugin.ts", + "./src/schema.ts", + "./src/subscriptions.ts", + "./src/zip_ops.ts", + "./src/ExponentialBackoff.ts", + "./src/RateLimiter.ts", + "./src/TypedEventEmitter.ts", + ], + "compilerOptions": { + "rootDir": ".", + "outDir": "dist/web/build", + } +} diff --git a/packages/web_ui/tsconfig.web.json b/packages/web_ui/tsconfig.web.json index 3beee793..65754630 100644 --- a/packages/web_ui/tsconfig.web.json +++ b/packages/web_ui/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../lib" }, + { "path": "../lib/tsconfig.web.json" }, ], "include": [ "src/**/*.tsx", "src/**/*.ts", "package.json", "global.d.ts" ], "compilerOptions": { diff --git a/plugins/global_chat/tsconfig.web.json b/plugins/global_chat/tsconfig.web.json index 64a8f2a5..c37f9141 100644 --- a/plugins/global_chat/tsconfig.web.json +++ b/plugins/global_chat/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../../packages/lib" }, + { "path": "../../packages/lib/tsconfig.web.json" }, { "path": "../../packages/web_ui/tsconfig.web.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], diff --git a/plugins/inventory_sync/tsconfig.web.json b/plugins/inventory_sync/tsconfig.web.json index 64a8f2a5..c37f9141 100644 --- a/plugins/inventory_sync/tsconfig.web.json +++ b/plugins/inventory_sync/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../../packages/lib" }, + { "path": "../../packages/lib/tsconfig.web.json" }, { "path": "../../packages/web_ui/tsconfig.web.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], diff --git a/plugins/player_auth/tsconfig.web.json b/plugins/player_auth/tsconfig.web.json index 64a8f2a5..c37f9141 100644 --- a/plugins/player_auth/tsconfig.web.json +++ b/plugins/player_auth/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../../packages/lib" }, + { "path": "../../packages/lib/tsconfig.web.json" }, { "path": "../../packages/web_ui/tsconfig.web.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], diff --git a/plugins/research_sync/tsconfig.web.json b/plugins/research_sync/tsconfig.web.json index 64a8f2a5..c37f9141 100644 --- a/plugins/research_sync/tsconfig.web.json +++ b/plugins/research_sync/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../../packages/lib" }, + { "path": "../../packages/lib/tsconfig.web.json" }, { "path": "../../packages/web_ui/tsconfig.web.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], diff --git a/plugins/statistics_exporter/tsconfig.web.json b/plugins/statistics_exporter/tsconfig.web.json index f70c4e0d..decec50c 100644 --- a/plugins/statistics_exporter/tsconfig.web.json +++ b/plugins/statistics_exporter/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../../packages/lib" }, + { "path": "../../packages/lib/tsconfig.web.json" }, { "path": "../../packages/web_ui/tsconfig.web.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], diff --git a/plugins/subspace_storage/tsconfig.web.json b/plugins/subspace_storage/tsconfig.web.json index 64a8f2a5..c37f9141 100644 --- a/plugins/subspace_storage/tsconfig.web.json +++ b/plugins/subspace_storage/tsconfig.web.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.web.json", "references": [ - { "path": "../../packages/lib" }, + { "path": "../../packages/lib/tsconfig.web.json" }, { "path": "../../packages/web_ui/tsconfig.web.json" }, ], "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], diff --git a/tsconfig.json b/tsconfig.json index f2af308f..c9f896d7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "files": [], "references": [ { "path": "./packages/lib" }, + { "path": "./packages/lib/tsconfig.web.json" }, { "path": "./packages/controller" }, { "path": "./packages/controller/tsconfig.web.json" }, { "path": "./packages/host" }, From e530bbc83a1cc828f3c04d1e6b49c6ca906ff6fd Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Wed, 13 Dec 2023 00:07:38 +0100 Subject: [PATCH 2/4] Replace deprecated usage of Breadcrumb.Item --- packages/web_ui/src/components/PageLayout.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/web_ui/src/components/PageLayout.tsx b/packages/web_ui/src/components/PageLayout.tsx index 37cae78b..8a9ce1e7 100644 --- a/packages/web_ui/src/components/PageLayout.tsx +++ b/packages/web_ui/src/components/PageLayout.tsx @@ -13,11 +13,15 @@ type PageLayoutProps = { }; export default function PageLayout(props: PageLayoutProps) { return <> - - {props.nav.map((part, index) => - {part.path ? {part.name} : part.name} - )} - + ( + route.href ? {route.title} : route.title + )} + items={props.nav.map( + (part, index) => ({ href: part.path, title: part.name })) + } + /> {props.children} From 880216b7751f9aa638515689c78336bc03ef4132 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 6 Jan 2024 19:44:23 +0100 Subject: [PATCH 3/4] Add typing to column render methods The render method for columns in Antd Table take the three arguments value, record, index. If dataIndex is set then value is the property given by dataIndex in record, otherwise value and record is the same. Unfortunately only record has the proper type while value is the type any. Change usage of `render: value =>` to `render: (_, value) =>` to get proper typing for the render methods defined on columns. --- packages/web_ui/src/components/HostsPage.tsx | 2 +- packages/web_ui/src/components/InstanceList.tsx | 8 ++++---- packages/web_ui/src/components/ModPackViewPage.tsx | 10 +++++----- packages/web_ui/src/components/ModsPage.tsx | 8 ++++---- packages/web_ui/src/components/PluginsPage.tsx | 4 ++-- packages/web_ui/src/components/SavesList.tsx | 8 ++++---- packages/web_ui/src/components/UserViewPage.tsx | 8 ++++---- packages/web_ui/src/components/UsersPage.tsx | 8 ++++---- plugins/subspace_storage/web/index.tsx | 4 ++-- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/web_ui/src/components/HostsPage.tsx b/packages/web_ui/src/components/HostsPage.tsx index cbec5dc2..d80a4119 100644 --- a/packages/web_ui/src/components/HostsPage.tsx +++ b/packages/web_ui/src/components/HostsPage.tsx @@ -218,7 +218,7 @@ export default function HostsPage() { { title: "Connected", key: "connected", - render: host => {host.connected ? "Connected" : "Disconnected"} diff --git a/packages/web_ui/src/components/InstanceList.tsx b/packages/web_ui/src/components/InstanceList.tsx index 09868175..b3239b7b 100644 --- a/packages/web_ui/src/components/InstanceList.tsx +++ b/packages/web_ui/src/components/InstanceList.tsx @@ -55,14 +55,14 @@ export default function InstanceList(props: InstanceListProps) { { title: "Assigned Host", key: "assignedHost", - render: instance => hostName(instance.assignedHost), + render: (_, instance) => hostName(instance.assignedHost), sorter: (a, b) => strcmp(hostName(a.assignedHost), hostName(b.assignedHost)), responsive: ["sm"], }, { title: "Public address", key: "publicAddress", - render: instance => { + render: (_, instance) => { let publicAddress = instancePublicAddress(instance); return publicAddress ? <> {publicAddress} @@ -83,7 +83,7 @@ export default function InstanceList(props: InstanceListProps) { { title: "Status", key: "status", - render: instance => , + render: (_, instance) => , sorter: (a, b) => strcmp(a["status"], b["status"]), }, ]; @@ -91,7 +91,7 @@ export default function InstanceList(props: InstanceListProps) { if (account.hasAnyPermission("core.instance.start", "core.instance.stop")) { columns.push({ key: "action", - render: instance => , diff --git a/packages/web_ui/src/components/ModPackViewPage.tsx b/packages/web_ui/src/components/ModPackViewPage.tsx index ef86552b..ae2d2821 100644 --- a/packages/web_ui/src/components/ModPackViewPage.tsx +++ b/packages/web_ui/src/components/ModPackViewPage.tsx @@ -185,14 +185,14 @@ function SearchModsTable(props: SearchModsTableProps) { { title: "Title", key: "title", - render: (result:ModResult) => result.versions[0].title, + render: (_, result) => result.versions[0].title, defaultSortOrder: "ascend", sorter: true, }, { title: "Author", key: "author", - render: (result:ModResult) => result.versions[0].author, + render: (_, result) => result.versions[0].author, responsive: ["lg"], sorter: true, }, @@ -200,7 +200,7 @@ function SearchModsTable(props: SearchModsTableProps) { title: "Version", key: "version", align: "right", - render: (result:ModResult) => ( + render: (_, result) => ( actions(result.versions[modResultSelectedVersion.get(result.name) || 0]) ), }, @@ -352,7 +352,7 @@ function ModsTable(props: ModsTableProps) { { title: "Name", key: "name", - render: mod => <> + render: (_, mod: any) => <> {mod.error === "missing" && {" "} } diff --git a/packages/web_ui/src/components/ModsPage.tsx b/packages/web_ui/src/components/ModsPage.tsx index d193feae..553be20e 100644 --- a/packages/web_ui/src/components/ModsPage.tsx +++ b/packages/web_ui/src/components/ModsPage.tsx @@ -206,7 +206,7 @@ export default function ModsPage() { { title: "Mods", key: "roles", - render: modPack => modPack.mods.size, + render: (_, modPack) => modPack.mods.size, }, ]} dataSource={[...modPacks.values()]} @@ -233,7 +233,7 @@ export default function ModsPage() { title: "Version", key: "version", align: "right", - render: mod => <> + render: (_, mod) => <> {`${mod.version} `} {`/ ${mod.factorioVersion}`} , @@ -248,7 +248,7 @@ export default function ModsPage() { title: "Size", key: "size", responsive: ["lg"], - render: mod => lib.formatBytes(mod.size), + render: (_, mod) => lib.formatBytes(mod.size), align: "right", sorter: (a, b) => a.size - b.size, }, @@ -256,7 +256,7 @@ export default function ModsPage() { title: "Action", key: "action", responsive: ["lg"], - render: mod => actions(mod), + render: (_, mod) => actions(mod), }, ]} expandable={{ diff --git a/packages/web_ui/src/components/PluginsPage.tsx b/packages/web_ui/src/components/PluginsPage.tsx index e3339f38..bd976f66 100644 --- a/packages/web_ui/src/components/PluginsPage.tsx +++ b/packages/web_ui/src/components/PluginsPage.tsx @@ -50,14 +50,14 @@ export default function PluginsPage() { { title: "Name", key: "name", - render: plugin => (plugin.info ? plugin.info.title : plugin.meta.name), + render: (_, plugin) => (plugin.info ? plugin.info.title : plugin.meta.name), defaultSortOrder: "ascend", sorter: (a, b) => strcmp(a.info ? a.info.title : a.meta.name, b.info ? b.info.title : b.meta.name), }, { title: "Version", key: "version", - render: plugin => { + render: (_, plugin) => { if (!plugin.package) { return "Error loading module"; } diff --git a/packages/web_ui/src/components/SavesList.tsx b/packages/web_ui/src/components/SavesList.tsx index 69e79b30..2cbe4c8e 100644 --- a/packages/web_ui/src/components/SavesList.tsx +++ b/packages/web_ui/src/components/SavesList.tsx @@ -211,10 +211,10 @@ export default function SavesList(props: { instance: lib.InstanceDetails }) { columns={[ { title: "Name", - render: save => <> + render: (_, save) => <> {save.name} {save.loaded && } - {save.default && } + {save.loadByDefault && } , sorter: (a, b) => a.name.localeCompare(b.name), }, @@ -222,14 +222,14 @@ export default function SavesList(props: { instance: lib.InstanceDetails }) { title: "Size", key: "size", responsive: ["sm"], - render: save => lib.formatBytes(save.size), + render: (_, save) => lib.formatBytes(save.size), align: "right", sorter: (a, b) => a.size - b.size, }, { title: "Last Modified", key: "mtimeMs", - render: save => new Date(save.mtimeMs).toLocaleString(), + render: (_, save) => new Date(save.mtimeMs).toLocaleString(), sorter: (a, b) => a.mtimeMs - b.mtimeMs, defaultSortOrder: "descend", }, diff --git a/packages/web_ui/src/components/UserViewPage.tsx b/packages/web_ui/src/components/UserViewPage.tsx index 07620da2..7ac4c72b 100644 --- a/packages/web_ui/src/components/UserViewPage.tsx +++ b/packages/web_ui/src/components/UserViewPage.tsx @@ -304,27 +304,27 @@ export default function UserViewPage() { { title: "Instance", key: "instance", - render: ([id]) => instanceName(id), + render: (_, [id]) => instanceName(id), defaultSortOrder: "ascend", sorter: (a, b) => strcmp(instanceName(a[0]), instanceName(b[0])), }, { title: "Online time", key: "onlineTime", - render: ([, stats]) => formatDuration(stats.onlineTimeMs || 0), + render: (_, [, stats]) => formatDuration(stats.onlineTimeMs || 0), sorter: (a, b) => (a[1].onlineTimeMs || 0) - (b[1].onlineTimeMs || 0), }, { title: "Join count", key: "joinCoint", - render: ([, stats]) => stats.joinCount || 0, + render: (_, [, stats]) => stats.joinCount || 0, sorter: (a, b) => (a[1].joinCount || 0) - (b[1].joinCount || 0), responsive: ["sm"], }, { title: "Last seen", key: "lastSeen", - render: ([id]) => formatLastSeen(user, id), + render: (_, [id]) => formatLastSeen(user, id), sorter: (a, b) => sortLastSeen(user, user, a[0], b[0]), }, ]} diff --git a/packages/web_ui/src/components/UsersPage.tsx b/packages/web_ui/src/components/UsersPage.tsx index b7469d40..c7ef96b3 100644 --- a/packages/web_ui/src/components/UsersPage.tsx +++ b/packages/web_ui/src/components/UsersPage.tsx @@ -82,7 +82,7 @@ export default function UsersPage() { { title: "Name", key: "name", - render: (user: lib.User) => + render: (_, user) => {user.name} {user.isAdmin && Admin} @@ -96,14 +96,14 @@ export default function UsersPage() { { title: "Roles", key: "roles", - render: (user: lib.User) => ( + render: (_, user) => ( [...user.roleIds].map(id => {(roles.get(id) || { name: id }).name}) ), }, { title: "Online time", key: "onlineTime", - render: (user: lib.User) => (user.playerStats?.onlineTimeMs + render: (_, user) => (user.playerStats?.onlineTimeMs ? formatDuration(user.playerStats.onlineTimeMs) : null), sorter: (a, b) => (a.playerStats?.onlineTimeMs ?? 0) - (b.playerStats?.onlineTimeMs ?? 0), @@ -112,7 +112,7 @@ export default function UsersPage() { { title: "Last seen", key: "lastSeen", - render: (user: lib.User) => formatLastSeen(user), + render: (_, user) => formatLastSeen(user), sorter: (a, b) => sortLastSeen(a, b), responsive: ["lg"], }, diff --git a/plugins/subspace_storage/web/index.tsx b/plugins/subspace_storage/web/index.tsx index 3950b627..345795f2 100644 --- a/plugins/subspace_storage/web/index.tsx +++ b/plugins/subspace_storage/web/index.tsx @@ -92,7 +92,7 @@ function StoragePage() { if (aName > bName) { return 1; } return 0; }, - render: item => { + render: (_, item) => { let localeName = getLocaleName(item[0]); let hasMeta = itemMetadata.get(item[0]); @@ -108,7 +108,7 @@ function StoragePage() { align: "right", defaultSortOrder: "descend", sorter: (a, b) => a[1] - b[1], - render: item => numberFormat.format(item[1]), + render: (_, item) => numberFormat.format(item[1]), }, ]} dataSource={filter ? storage.filter(filter) : storage} From b976de926b7fdefe236f85d4491425bdc8db8db2 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Thu, 11 Jan 2024 00:38:45 +0100 Subject: [PATCH 4/4] Fix unassigning instances broken in Web UI --- packages/web_ui/src/components/AssignInstanceModal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web_ui/src/components/AssignInstanceModal.tsx b/packages/web_ui/src/components/AssignInstanceModal.tsx index f6525522..6749cb55 100644 --- a/packages/web_ui/src/components/AssignInstanceModal.tsx +++ b/packages/web_ui/src/components/AssignInstanceModal.tsx @@ -26,14 +26,14 @@ export default function AssignInstanceModal(props: AssignInstanceModalProps) { let control = useContext(ControlContext); function handleAssign() { - let hostId = form.getFieldValue("host"); + let hostId: number | string | undefined = form.getFieldValue("host"); if (hostId === undefined) { setOpen(false); return; } - if (hostId === "null") { - hostId = null; + if (typeof hostId === "string") { + hostId = undefined; } setApplying(true);