Files
factorio-clusterio/packages/web_ui/src/components/LoadScenarioModal.tsx
T
BastiaanandClaude Opus 5 558999faa8 Parse the Map Settings field in the load scenario modal (#1032)
The Map Settings block parsed values.mapGenSettings, so filling in only
Map Settings failed with "undefined" is not valid JSON and the modal
would not submit, while filling in both sent the map gen settings JSON
to Factorio as --map-settings.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-13 14:45:50 +01:00

139 lines
4.1 KiB
TypeScript

import React, { useContext, useState } from "react";
import { Button, Form, Input, Modal } from "antd";
import * as lib from "@clusterio/lib";
import ControlContext from "./ControlContext";
import { notifyErrorHandler } from "../util/notify";
type LoadScenarioModalProps = {
instance: lib.InstanceDetails;
};
export default function LoadScenarioModal(props: LoadScenarioModalProps) {
let [open, setOpen] = useState(false);
let [loadingScenario, setLoadingScenario] = useState(false);
let [form] = Form.useForm();
let control = useContext(ControlContext);
function loadScenario() {
let values = form.getFieldsValue();
let scenario = values.scenario || "base/freeplay";
let seed = values.seed === undefined ? undefined : Number.parseInt(values.seed, 10);
let mapGenSettings;
let mapSettings;
if (values.exchangeString && values.exchangeString.trim()) {
let result;
try {
result = lib.readMapExchangeString(values.exchangeString);
} catch (err: any) {
form.setFields([{ name: "exchangeString", errors: [err.message] }]);
return;
}
form.setFields([{ name: "exchangeString", errors: [] }]);
mapGenSettings = result.map_gen_settings;
mapSettings = result.map_settings;
}
if (values.mapGenSettings && values.mapGenSettings.trim()) {
try {
mapGenSettings = JSON.parse(values.mapGenSettings);
} catch (err: any) {
form.setFields([{ name: "mapGenSettings", errors: [err.message] }]);
return;
}
form.setFields([{ name: "mapGenSettings", errors: [] }]);
}
if (values.mapSettings && values.mapSettings.trim()) {
try {
mapSettings = JSON.parse(values.mapSettings);
} catch (err: any) {
form.setFields([{ name: "mapSettings", errors: [err.message] }]);
return;
}
form.setFields([{ name: "mapSettings", errors: [] }]);
}
setLoadingScenario(true);
control.sendTo(
{ instanceId: props.instance.id },
new lib.InstanceLoadScenarioRequest(scenario, seed, mapGenSettings, mapSettings),
).then(() => {
setOpen(false);
}).catch(
notifyErrorHandler("Error loading scenario")
).finally(() => {
setLoadingScenario(false);
});
}
function convertExchangeString() {
let exchangeString = form.getFieldValue("exchangeString");
let result;
try {
result = lib.readMapExchangeString(exchangeString);
} catch (err: any) {
form.setFields([{ name: "exchangeString", errors: [err.message] }]);
return;
}
form.setFields([{ name: "exchangeString", errors: [], value: "" }]);
form.setFieldsValue({
mapGenSettings: JSON.stringify(result.map_gen_settings, null, "\t"),
mapSettings: JSON.stringify(result.map_settings, null, "\t"),
});
}
function handleCancel() {
setOpen(false);
}
return <>
<Button
loading={loadingScenario}
disabled={props.instance.status !== "stopped"}
onClick={() => {
setOpen(true);
}}
>
Load scenario
</Button>
<Modal
title="Load Scenario"
width={560}
okText="Load"
open={open}
confirmLoading={loadingScenario}
onOk={loadScenario}
onCancel={handleCancel}
destroyOnHidden
>
<Form form={form} layout="vertical">
<Form.Item name="scenario" label="Scenario">
<Input placeholder="base/freeplay" />
</Form.Item>
<Form.Item name="seed" label="Seed">
<Input type="number" />
</Form.Item>
<Form.Item name="exchangeString" label="Map Exchange String">
<Input.TextArea allowClear={true} autoSize={{ minRows: 3 }} />
</Form.Item>
<div style={{ textAlign: "right", marginTop: -8 }}>
<Button onClick={() => convertExchangeString()}>Convert to settings</Button>
</div>
<Form.Item
name="mapGenSettings"
label="Map Gen Settings"
tooltip="JSON data to pass to Factorio with --map-gen-settings, overrides Map Exchange String"
>
<Input.TextArea allowClear={true} autoSize={{ minRows: 1 }} />
</Form.Item>
<Form.Item
name="mapSettings"
label="Map Settings"
tooltip="JSON data to pass to Factorio with --map-settings, overrides Map Exchange String"
>
<Input.TextArea allowClear={true} autoSize={{ minRows: 1 }} />
</Form.Item>
</Form>
</Modal>
</>;
}