mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 15:24:52 +09:00
132 lines
3.6 KiB
TypeScript
132 lines
3.6 KiB
TypeScript
import React, { useContext, useState } from "react";
|
|
import { Popconfirm } from "antd";
|
|
|
|
import * as lib from "@clusterio/lib";
|
|
|
|
import ControlContext from "./ControlContext";
|
|
import { useAccount } from "../model/account";
|
|
import { notifyErrorHandler } from "../util/notify";
|
|
import VariableDropdownButton, { VariableDropdownButtonProps } from "./VariableDropdownButton";
|
|
|
|
type InstanceControlButtonProps = Omit<VariableDropdownButtonProps, "actions"> & {
|
|
instance: lib.InstanceDetails;
|
|
onFinish?: () => void;
|
|
};
|
|
|
|
export const InstanceControlButtonPermissions = [
|
|
"core.instance.start", "core.instance.restart", "core.instance.stop", "core.instance.kill",
|
|
] as const;
|
|
|
|
export default function InstanceControlButton(props: InstanceControlButtonProps) {
|
|
const account = useAccount();
|
|
const control = useContext(ControlContext);
|
|
const [switching, setSwitching] = useState<boolean>(false);
|
|
const [popconfirm, setPopconfirm] = useState<string | null>(null);
|
|
|
|
const instanceId = props.instance.id;
|
|
const instanceStatus = props.instance.status;
|
|
const showStart = ["stopped", "stopping"].includes(instanceStatus);
|
|
const showStop = ["running", "starting"].includes(instanceStatus);
|
|
|
|
function actionFinish() {
|
|
setSwitching(false);
|
|
if (props.onFinish) {
|
|
props.onFinish();
|
|
}
|
|
}
|
|
|
|
const actions: VariableDropdownButtonProps["actions"] = [];
|
|
|
|
if (account.hasPermission("core.instance.start") && showStart !== switching) {
|
|
actions.push({
|
|
key: "start",
|
|
label: "Start",
|
|
onClick: () => {
|
|
setSwitching(true);
|
|
control.sendTo(
|
|
{ instanceId },
|
|
new lib.InstanceStartRequest(undefined),
|
|
).catch(
|
|
notifyErrorHandler("Error starting instance")
|
|
).finally(actionFinish);
|
|
},
|
|
});
|
|
|
|
} else if (account.hasPermission("core.instance.stop")) { // else if because it is stop or start
|
|
actions.push({
|
|
key: "stop",
|
|
label: "Stop",
|
|
danger: true,
|
|
onClick: () => {
|
|
setSwitching(true);
|
|
control.sendTo(
|
|
{ instanceId },
|
|
new lib.InstanceStopRequest(),
|
|
).catch(
|
|
notifyErrorHandler("Error stopping instance")
|
|
).finally(actionFinish);
|
|
},
|
|
});
|
|
}
|
|
|
|
if (account.hasPermission("core.instance.restart")) {
|
|
actions.push({
|
|
key: "restart",
|
|
label: "Restart",
|
|
disabled: instanceStatus !== "running",
|
|
onClick: () => {
|
|
setSwitching(true);
|
|
control.sendTo(
|
|
{ instanceId },
|
|
new lib.InstanceRestartRequest(undefined),
|
|
).catch(
|
|
notifyErrorHandler("Error restarting instance")
|
|
).finally(actionFinish);
|
|
},
|
|
});
|
|
}
|
|
|
|
if (account.hasPermission("core.instance.kill")) {
|
|
actions.push({
|
|
key: "kill",
|
|
label: "Kill",
|
|
danger: true,
|
|
disabled: instanceStatus === "stopped",
|
|
onClick: () => setPopconfirm("kill"),
|
|
});
|
|
}
|
|
|
|
return <div style={{ position: "relative", display: "inline-block" }}>
|
|
<VariableDropdownButton
|
|
{...props}
|
|
type="primary"
|
|
actions={actions}
|
|
loading={switching}
|
|
disabled={!(showStart || showStop)}
|
|
/>
|
|
<Popconfirm
|
|
title={<>
|
|
Killing this instance may leave you save and player data corrupted.
|
|
Are you sure you want to kill the instance?
|
|
</>}
|
|
open={popconfirm === "kill"}
|
|
placement="bottomRight"
|
|
okText="Kill"
|
|
okButtonProps={{ danger: true }}
|
|
onCancel={() => setPopconfirm(null)}
|
|
onConfirm={() => {
|
|
control.sendTo(
|
|
{ instanceId },
|
|
new lib.InstanceKillRequest(),
|
|
).catch(
|
|
notifyErrorHandler("Error killing instance")
|
|
).finally(actionFinish);
|
|
setPopconfirm(null);
|
|
}}
|
|
>
|
|
{/* Used to position the popup under the button */}
|
|
<span style={{ position: "absolute", right: 0, top: "100%", width: 1, height: 1 }} />
|
|
</Popconfirm>
|
|
</div>;
|
|
}
|