import { useContext, useEffect, useState } from "react"; import { Button, Checkbox, Form, FormInstance, Input, Modal, Radio, Select } from "antd"; import * as lib from "@clusterio/lib"; import { useAccount } from "../model/account"; import { notifyErrorHandler } from "../util/notify"; import ControlContext from "./ControlContext"; type NpmActionProps = { setApplyAction(func: () => Promise): void, form: FormInstance, target: lib.AddressShorthand, } function NpmRemoteUpdate({ setApplyAction, form, target }: NpmActionProps) { const control = useContext(ControlContext); setApplyAction(async () => { if (target === "controller") { return await control.send(new lib.ControllerUpdateRequest()); } return await control.sendTo(target, new lib.HostUpdateRequest()); }); return <> ; } function NpmPluginUpdate({ setApplyAction, form, target }: NpmActionProps) { const control = useContext(ControlContext); const [plugins, setPlugins] = useState([]); setApplyAction(async () => { const values = form.getFieldsValue(); if (!values.plugin || values.plugin === "") { throw new Error("Plugin not provided"); } await control.sendTo(target, new lib.PluginUpdateRequest(values.plugin)); }); useEffect(() => { control.sendTo(target, new lib.PluginListRequest()).then(newPlugins => { setPlugins(newPlugins); }).catch(notifyErrorHandler("Error fetching role list")); }, [target]); return <> ; } export function NpmButton(props: { target: lib.AddressShorthand, canRestart?: boolean, disabled?: boolean }) { const control = useContext(ControlContext); const account = useAccount(); const [open, setOpen] = useState(false); const [formAction, setFormAction] = useState(undefined); const [form] = Form.useForm(); const [allows, setAllows] = useState({ remoteUpdates: true, pluginUpdates: true, pluginInstall: true, }); useEffect(() => { if (props.target === "controller") { if (!account.hasPermission("core.controller.get_config")) { setAllows({ remoteUpdates: true, pluginUpdates: true, pluginInstall: true }); return; // If a user doesn't have config perms, then assume true to allow the sending the request } control.send(new lib.ControllerConfigGetRequest()).then(async (serializedConfig) => { const config = lib.ControllerConfig.fromJSON(serializedConfig, "control"); setAllows({ remoteUpdates: config.get("controller.allow_remote_updates"), pluginUpdates: config.get("controller.allow_plugin_updates"), pluginInstall: config.get("controller.allow_plugin_install"), }); }).catch(notifyErrorHandler("Failed to fetch controller config for remote updates")); } else { if (!account.hasPermission("core.host.get_config")) { setAllows({ remoteUpdates: true, pluginUpdates: true, pluginInstall: true }); return; // If a user doesn't have config perms, then assume true to allow the sending the request } control.sendTo(props.target, new lib.HostConfigGetRequest()).then(async (serializedConfig) => { const config = lib.HostConfig.fromJSON(serializedConfig, "control"); setAllows({ remoteUpdates: config.get("host.allow_remote_updates"), pluginUpdates: config.get("host.allow_plugin_updates"), pluginInstall: config.get("host.allow_plugin_install"), }); }).catch(notifyErrorHandler("Failed to fetch host config for remote updates")); } }, [props.target]); function onValuesChange({ action } : { action?: string }) { if (action) { setFormAction(action); } } let applyAction: () => Promise; const setApplyAction = (func: () => Promise) => { applyAction = func; }; async function onOk() { if (!applyAction) { form.setFields([{ name: "action", errors: ["Action is required"] }]); return; } await applyAction(); const values = form.getFieldsValue(); if (values.restart) { // Ternary not used because TS disliked it if (props.target === "controller") { await control.sendTo(props.target, new lib.ControllerRestartRequest()); } else { await control.sendTo(props.target, new lib.HostRestartRequest()); } } setFormAction(undefined); setOpen(false); } return <> { onOk().catch(notifyErrorHandler(`Error running ${formAction}`)); }} onCancel={() => { setOpen(false); }} destroyOnClose >
{account.hasPermission(`core.${props.target === "controller" ? "controller" : "host"}.update`) ? Update Clusterio : undefined} {account.hasPermission("core.plugin.update") ? Update Plugin : undefined} {account.hasPermission("core.plugin.install") ? Install Plugin : undefined} { formAction !== undefined && account.hasPermission(`core.${props.target === "controller" ? "controller" : "host"}.restart`) && } {formAction === "remote_update" ? : undefined} {formAction === "plugin_update" ? : undefined} {formAction === "plugin_install" ? : undefined}
; } export function hasNpmButtonPermission(controller: boolean) { const account = useAccount(); return account.hasAnyPermission( controller ? "core.controller.update" : "core.host.update", "core.plugin.update", "core.plugin.install" ); }