From 52238de9b318afb2e05fd375784472ae12b3f053 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 22 Nov 2021 10:19:43 +0100 Subject: [PATCH 1/6] Expose react-router-dom to allow plugins to use useHistory() See https://githubmemory.com/repo/module-federation/module-federation-examples/issues/716 --- packages/master/webpack.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/master/webpack.config.js b/packages/master/webpack.config.js index 1d80580b..4c45a621 100644 --- a/packages/master/webpack.config.js +++ b/packages/master/webpack.config.js @@ -25,6 +25,8 @@ module.exports = (env = {}) => merge(common(env), { "antd": { singleton: true }, "react": { singleton: true }, "react-dom": { singleton: true }, + "react-router": { singleton: true }, + "react-router-dom": { singleton: true }, }, }), ], From 9138efca6f3544c78255264d8db297dd1cb00413 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 22 Nov 2021 10:20:06 +0100 Subject: [PATCH 2/6] Clear log console when changing props --- packages/web_ui/src/components/LogConsole.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web_ui/src/components/LogConsole.jsx b/packages/web_ui/src/components/LogConsole.jsx index aa76c7a7..a9fd58d7 100644 --- a/packages/web_ui/src/components/LogConsole.jsx +++ b/packages/web_ui/src/components/LogConsole.jsx @@ -69,6 +69,7 @@ export default function LogConsole(props) { parent.scrollTop = parent.scrollHeight - parent.clientHeight; if (account.hasPermission("core.log.query")) { + setPastLines([{"Loading past entries..."}
]); libLink.messages.queryLog.send(control, { ...logFilter, max_level: null, From b192c82dcc5472fcd101f5417a3b0bbfb17e3ef9 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 22 Nov 2021 10:20:44 +0100 Subject: [PATCH 3/6] Export induvidual components from the web interface for plugin use --- packages/web_ui/src/components/InstanceStatusTag.jsx | 2 +- packages/web_ui/src/index.jsx | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/web_ui/src/components/InstanceStatusTag.jsx b/packages/web_ui/src/components/InstanceStatusTag.jsx index cd37ca1b..1f82c6fa 100644 --- a/packages/web_ui/src/components/InstanceStatusTag.jsx +++ b/packages/web_ui/src/components/InstanceStatusTag.jsx @@ -1,7 +1,7 @@ import { Tag } from "antd"; import React from "react"; -const statusColors = { +export const statusColors = { unknown: "#8c8c8c", unassigned: "#eb2f96", stopped: "#cf1322", diff --git a/packages/web_ui/src/index.jsx b/packages/web_ui/src/index.jsx index ae2b6bbc..92c7975b 100644 --- a/packages/web_ui/src/index.jsx +++ b/packages/web_ui/src/index.jsx @@ -5,6 +5,7 @@ export * from "./model/instance.jsx"; export * from "./model/slave.jsx"; export * from "./model/locale.jsx"; export * from "./model/item_metadata.jsx"; +export * from "./model/account.jsx"; export { default as ControlContext } from "./components/ControlContext"; @@ -18,6 +19,9 @@ export { default as LogConsole } from "./components/LogConsole"; export { default as AssignInstanceModal } from "./components/AssignInstanceModal"; export { default as InstanceList } from "./components/InstanceList"; export { default as InstanceRcon } from "./components/InstanceRcon"; +export { default as InstanceStatusTag } from "./components/InstanceStatusTag"; +export { default as StartStopInstanceButton } from "./components/StartStopInstanceButton"; +export { statusColors } from "./components/InstanceStatusTag"; export { default as PageLayout } from "./components/PageLayout"; export { default as SavesList } from "./components/SavesList"; From 1cf3e39d72758ab1be383b751af9b56bd1375796 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 22 Nov 2021 12:44:48 +0100 Subject: [PATCH 4/6] Avoid savesProvider throwing errors on missing instanceId --- packages/web_ui/src/model/saves.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/web_ui/src/model/saves.jsx b/packages/web_ui/src/model/saves.jsx index 83bad774..1f2454f4 100644 --- a/packages/web_ui/src/model/saves.jsx +++ b/packages/web_ui/src/model/saves.jsx @@ -14,10 +14,15 @@ export function useSaves(instanceId) { setSaves(result.list); }).catch(err => { logger.error(`Failed to list instance saves: ${err}`); + setSaves([]); }); } useEffect(() => { + if (!Number.isInteger(instanceId)) { + setSaves([]); + return undefined; + } updateSaves(); function updateHandler(data) { From 6af34dc3a6eafc856edf52f048b144867028822b Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 22 Nov 2021 13:17:39 +0100 Subject: [PATCH 5/6] Update BaseConfigTree when props.id changes --- .../web_ui/src/components/BaseConfigTree.jsx | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/web_ui/src/components/BaseConfigTree.jsx b/packages/web_ui/src/components/BaseConfigTree.jsx index e693d9cb..15581814 100644 --- a/packages/web_ui/src/components/BaseConfigTree.jsx +++ b/packages/web_ui/src/components/BaseConfigTree.jsx @@ -16,8 +16,13 @@ export default function BaseConfigTree(props) { let newConfig = new props.ConfigClass("control"); await newConfig.load(serializedConfig); setConfig(newConfig); + return newConfig; } - useEffect(() => { updateConfig(); }, [props.id]); + useEffect(() => { + updateConfig().then(config => { + form.setFieldsValue(getInitialValues(config, props)); + }); + }, [props.id]); function renderInput(def) { if (def.type === "boolean") { @@ -250,3 +255,28 @@ export default function BaseConfigTree(props) { ; } + +function getInitialValues(config, props) { + let initialValues = {}; + for (let [name, GroupClass] of props.ConfigClass.groups) { + let group = config.group(name); + for (let def of GroupClass.definitions.values()) { + if (!group.canAccess(def.name)) { + continue; + } + + let value = group.get(def.name); + let fieldName = `${group.name}.${def.name}`; + + if (def.type === "object") { + for (let prop of Object.keys(value)) { + let propPath = `${group.name}.${def.name}.${prop}`; + initialValues[propPath] = JSON.stringify(value[prop]); + } + } else { + initialValues[fieldName] = value; + } + } + } + return initialValues; +} From a3d98595e2bb6a3c1a893edbcff5d4cf8230bd4a Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Mon, 22 Nov 2021 13:28:29 +0100 Subject: [PATCH 6/6] Fix linter errors --- .../web_ui/src/components/BaseConfigTree.jsx | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/packages/web_ui/src/components/BaseConfigTree.jsx b/packages/web_ui/src/components/BaseConfigTree.jsx index 15581814..5f78d44d 100644 --- a/packages/web_ui/src/components/BaseConfigTree.jsx +++ b/packages/web_ui/src/components/BaseConfigTree.jsx @@ -3,6 +3,30 @@ import { Button, Card, Checkbox, Form, Input, InputNumber, Space, Spin, Tree, Ty const { Title } = Typography; +function getInitialValues(config, props) { + let initialValues = {}; + for (let [name, GroupClass] of props.ConfigClass.groups) { + let group = config.group(name); + for (let def of GroupClass.definitions.values()) { + if (!group.canAccess(def.name)) { + continue; + } + + let value = group.get(def.name); + let fieldName = `${group.name}.${def.name}`; + + if (def.type === "object") { + for (let prop of Object.keys(value)) { + let propPath = `${group.name}.${def.name}.${prop}`; + initialValues[propPath] = JSON.stringify(value[prop]); + } + } else { + initialValues[fieldName] = value; + } + } + } + return initialValues; +} export default function BaseConfigTree(props) { let [config, setConfig] = useState(null); @@ -19,8 +43,8 @@ export default function BaseConfigTree(props) { return newConfig; } useEffect(() => { - updateConfig().then(config => { - form.setFieldsValue(getInitialValues(config, props)); + updateConfig().then(updatedConfig => { + form.setFieldsValue(getInitialValues(updatedConfig, props)); }); }, [props.id]); @@ -255,28 +279,3 @@ export default function BaseConfigTree(props) { ; } - -function getInitialValues(config, props) { - let initialValues = {}; - for (let [name, GroupClass] of props.ConfigClass.groups) { - let group = config.group(name); - for (let def of GroupClass.definitions.values()) { - if (!group.canAccess(def.name)) { - continue; - } - - let value = group.get(def.name); - let fieldName = `${group.name}.${def.name}`; - - if (def.type === "object") { - for (let prop of Object.keys(value)) { - let propPath = `${group.name}.${def.name}.${prop}`; - initialValues[propPath] = JSON.stringify(value[prop]); - } - } else { - initialValues[fieldName] = value; - } - } - } - return initialValues; -}