mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 23:04:52 +09:00
Update webui config to use bulk set
This commit is contained in:
4 files changed
+33
-91
No files matched your search
@@ -9,6 +9,7 @@ import * as lib from "@clusterio/lib";
|
||||
import ControlContext from "./ControlContext";
|
||||
import { InputComponent, InputComponentProps } from "../BaseWebPlugin";
|
||||
import type { Control } from "../util/websocket";
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
@@ -67,8 +68,7 @@ function renderInput(inputComponents: Record<string, InputComponent>, def: lib.F
|
||||
type BaseConfigTreeProps = {
|
||||
ConfigClass: typeof lib.ControllerConfig | typeof lib.HostConfig | typeof lib.InstanceConfig;
|
||||
retrieveConfig: () => Promise<lib.ConfigSchema>;
|
||||
setField: (field:string, value:any) => Promise<void>;
|
||||
setProp: (field:string, prop:string, value:any) => Promise<void>;
|
||||
setConfig: (fields: Record<string, string | Record<string, string>>) => Promise<void>;
|
||||
id?: number;
|
||||
onApply?: () => void;
|
||||
available?: boolean;
|
||||
@@ -157,32 +157,25 @@ export default function BaseConfigTree(props: BaseConfigTreeProps) {
|
||||
loading={applying}
|
||||
onClick={async () => {
|
||||
setApplying(true);
|
||||
for (let field of changedFields) {
|
||||
let value = form.getFieldValue(field);
|
||||
let request;
|
||||
const fields: Record<string, string | Record<string, string>> = {};
|
||||
for (const field of changedFields) {
|
||||
const value = form.getFieldValue(field);
|
||||
if (propsMap.has(field)) {
|
||||
let [fieldName, prop] = propsMap.get(field)!;
|
||||
request = props.setProp(fieldName, prop, value);
|
||||
const [fieldName, prop] = propsMap.get(field)!;
|
||||
const fieldValue = (fields[fieldName] ?? {}) as Record<string, string>;
|
||||
fields[fieldName] = fieldValue;
|
||||
fieldValue[prop] = value ? JSON.parse(value) : undefined;
|
||||
|
||||
} else {
|
||||
request = props.setField(field, value === null ? "" : String(value));
|
||||
fields[field] = value === null ? "" : String(value);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await request;
|
||||
setChangedFields(changed => {
|
||||
let newChanged = new Set(changed);
|
||||
newChanged.delete(field);
|
||||
return newChanged;
|
||||
});
|
||||
|
||||
} catch (err: any) {
|
||||
setErrorFields(errors => {
|
||||
let newErrors = new Map(errors);
|
||||
newErrors.set(field, err.message);
|
||||
return newErrors;
|
||||
});
|
||||
}
|
||||
try {
|
||||
await props.setConfig(fields);
|
||||
setChangedFields(new Set());
|
||||
} catch (err: any) {
|
||||
notifyErrorHandler(err.message);
|
||||
}
|
||||
|
||||
await updateConfig();
|
||||
@@ -325,26 +318,23 @@ function computeTreeData(
|
||||
}
|
||||
|
||||
if (!def.validator) { return; }
|
||||
|
||||
// TODO this needs to use stage and stageProp to avoid deadlocks
|
||||
const staging = config.staging;
|
||||
staging.setProp(fieldName, prop, fieldValue);
|
||||
config.stageProp(fieldName, prop, fieldValue);
|
||||
|
||||
for (const dependsOn of def.dependsOn ?? []) {
|
||||
const dependsOnDef = ConfigClass.fieldDefinitions[dependsOn as any] as typeof def;
|
||||
try {
|
||||
if (propsMap.has(dependsOn)) {
|
||||
const [name, otherProp] = propsMap.get(dependsOn)!;
|
||||
staging.setProp(name, otherProp, JSON.parse(getFieldValue(dependsOn)));
|
||||
config.stageProp(name, otherProp, JSON.parse(getFieldValue(dependsOn)));
|
||||
} else if (dependsOnDef.type !== "object") {
|
||||
staging.set(dependsOn, getFieldValue(dependsOn));
|
||||
config.stage(dependsOn, getFieldValue(dependsOn));
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to fetch field: ${dependsOn}`);
|
||||
}
|
||||
}
|
||||
|
||||
def.validator(fieldValue, staging);
|
||||
def.validator(fieldValue, config.staging);
|
||||
}})]}
|
||||
>
|
||||
<Input className="json-input" disabled={!canWrite} />
|
||||
@@ -418,26 +408,23 @@ function computeTreeData(
|
||||
rules={[({getFieldValue}) => ({
|
||||
validator: async (_, fieldValue) => {
|
||||
if (!def.validator) { return; }
|
||||
|
||||
// TODO this needs to use stage and stageProp to avoid deadlocks
|
||||
const staging = config.staging;
|
||||
staging.set(fieldName, fieldValue);
|
||||
config.stage(fieldName, fieldValue);
|
||||
|
||||
for (const dependsOn of def.dependsOn ?? []) {
|
||||
const dependsOnDef = ConfigClass.fieldDefinitions[dependsOn as any] as typeof def;
|
||||
try {
|
||||
if (propsMap.has(dependsOn)) {
|
||||
const [name, prop] = propsMap.get(dependsOn)!;
|
||||
staging.setProp(name, prop, JSON.parse(getFieldValue(dependsOn)));
|
||||
config.stageProp(name, prop, JSON.parse(getFieldValue(dependsOn)));
|
||||
} else if (dependsOnDef.type !== "object") {
|
||||
staging.set(dependsOn, getFieldValue(dependsOn));
|
||||
config.stage(dependsOn, getFieldValue(dependsOn));
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to fetch field: ${dependsOn}`);
|
||||
}
|
||||
}
|
||||
|
||||
def.validator(fieldValue, staging);
|
||||
def.validator(fieldValue, config.staging);
|
||||
},
|
||||
})]}
|
||||
>
|
||||
|
||||
@@ -13,30 +13,13 @@ export default function ControllerConfigTree() {
|
||||
return await control.send(new lib.ControllerConfigGetRequest());
|
||||
}
|
||||
|
||||
async function setField(field: string, value: any) {
|
||||
await control.send(new lib.ControllerConfigSetFieldRequest(
|
||||
field,
|
||||
String(value),
|
||||
));
|
||||
}
|
||||
|
||||
async function setProp(field: string, prop: string, value: any) {
|
||||
if (value) {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
value = undefined;
|
||||
}
|
||||
await control.send(new lib.ControllerConfigSetPropRequest(field, prop, value));
|
||||
async function setConfig(fields: Record<string, string | Record<string, string>>) {
|
||||
await control.send(new lib.ControllerConfigSetRequest(fields));
|
||||
}
|
||||
|
||||
return <BaseConfigTree
|
||||
ConfigClass={lib.ControllerConfig}
|
||||
retrieveConfig={retrieveConfig}
|
||||
setField={setField}
|
||||
setProp={setProp}
|
||||
setConfig={setConfig}
|
||||
/>;
|
||||
}
|
||||
@@ -13,28 +13,14 @@ export default function HostConfigTree(props: { id: number, available: boolean }
|
||||
return await control.sendTo({ hostId: props.id }, new lib.HostConfigGetRequest());
|
||||
}
|
||||
|
||||
async function setField(field: string, value: any) {
|
||||
await control.sendTo({ hostId: props.id }, new lib.HostConfigSetFieldRequest(field, value));
|
||||
}
|
||||
|
||||
async function setProp(field: string, prop: string, value: any) {
|
||||
if (value) {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
value = undefined;
|
||||
}
|
||||
await control.sendTo({ hostId: props.id }, new lib.HostConfigSetPropRequest(field, prop, value));
|
||||
async function setConfig(fields: Record<string, string | Record<string, string>>) {
|
||||
await control.send(new lib.HostConfigSetRequest(fields));
|
||||
}
|
||||
|
||||
return <BaseConfigTree
|
||||
ConfigClass={lib.HostConfig}
|
||||
retrieveConfig={retrieveConfig}
|
||||
setField={setField}
|
||||
setProp={setProp}
|
||||
setConfig={setConfig}
|
||||
id={props.id}
|
||||
available={props.available}
|
||||
/>;
|
||||
|
||||
@@ -17,28 +17,14 @@ export default function InstanceConfigTree(props: InstanceConfigTreeProps) {
|
||||
return await control.send(new lib.InstanceConfigGetRequest(props.id));
|
||||
}
|
||||
|
||||
async function setField(field: string, value: any) {
|
||||
await control.send(new lib.InstanceConfigSetFieldRequest(props.id, field, value));
|
||||
}
|
||||
|
||||
async function setProp(field: string, prop: string, value: any) {
|
||||
if (value) {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
value = undefined;
|
||||
}
|
||||
await control.send(new lib.InstanceConfigSetPropRequest(props.id, field, prop, value));
|
||||
async function setConfig(fields: Record<string, string | Record<string, string>>) {
|
||||
await control.send(new lib.InstanceConfigSetRequest(props.id, fields));
|
||||
}
|
||||
|
||||
return <BaseConfigTree
|
||||
ConfigClass={lib.InstanceConfig}
|
||||
retrieveConfig={retrieveConfig}
|
||||
setField={setField}
|
||||
setProp={setProp}
|
||||
setConfig={setConfig}
|
||||
id={props.id}
|
||||
/>;
|
||||
}
|
||||
Reference in new issue
Block a user