mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 07:04:53 +09:00
In order to import a path inside packages/lib/ in the webpack shared
module environment it has to be declared as shared in both the web_ui
webpack config and the plugin's webpack config. This is rather error
prone and easy to miss. Move the burden of specifying which entrypoints
are valid in lib to lib itself by changing all imports in the web
interface code to import from @clusterio/lib instead sub paths.
For web code this means imports is done like this from now on:
import { libConfig, libLink } from "@clusterio/lib";
For info.js which has to be loadable by both Node.js and web code the
imports are done as follows:
const { libConfig, libLink } = require("@clusterio/lib");
While the Node.js only code can either continue to import sub paths
directly or use the info.js style.
125 lines
3.7 KiB
React
125 lines
3.7 KiB
React
import React, { useContext, useState } from "react";
|
|
import { useHistory, useParams } from "react-router-dom";
|
|
import { Button, Descriptions, Popconfirm, Space, Spin, Typography } from "antd";
|
|
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
|
|
|
|
import { libLink } from "@clusterio/lib";
|
|
|
|
import ControlContext from "./ControlContext";
|
|
import PageLayout from "./PageLayout";
|
|
import InstanceConfigTree from "./InstanceConfigTree";
|
|
import InstanceConsole from "./InstanceConsole";
|
|
import InstanceRcon from "./InstanceRcon";
|
|
import AssignInstanceModal from "./AssignInstanceModal";
|
|
import StartStopInstanceButton from "./StartStopInstanceButton";
|
|
import LoadScenarioModal from "./LoadScenarioModal";
|
|
import SavesList from "./SavesList";
|
|
import { notifyErrorHandler } from "../util/notify";
|
|
import { useInstance } from "../model/instance";
|
|
import { useSlave } from "../model/slave";
|
|
|
|
const { Title, Paragraph } = Typography;
|
|
|
|
|
|
export default function InstanceViewPage(props) {
|
|
let params = useParams();
|
|
let instanceId = Number(params.id);
|
|
|
|
let history = useHistory();
|
|
|
|
let control = useContext(ControlContext);
|
|
let [instance] = useInstance(instanceId);
|
|
let [slave] = useSlave(Number(instance["assigned_slave"]));
|
|
|
|
let [exportingData, setExportingData] = useState(false);
|
|
|
|
let nav = [{ name: "Instances", path: "/instances" }, { name: instance.name || "Unknown" }];
|
|
if (instance.loading) {
|
|
return <PageLayout nav={nav}><Spin size="large" /></PageLayout>;
|
|
}
|
|
|
|
if (instance.missing) {
|
|
return <PageLayout nav={nav}>
|
|
<h2>Instance not found</h2>
|
|
<p>Instance with id {instanceId} was not found on the master server.</p>
|
|
</PageLayout>;
|
|
}
|
|
|
|
let instanceButtons = <Space>
|
|
<StartStopInstanceButton instance={instance} />
|
|
<LoadScenarioModal instance={instance} />
|
|
<Button
|
|
loading={exportingData}
|
|
disabled={instance.status !== "stopped"}
|
|
onClick={() => {
|
|
setExportingData(true);
|
|
libLink.messages.exportData.send(
|
|
control, { instance_id: instanceId }
|
|
).catch(
|
|
notifyErrorHandler("Error exporting data")
|
|
).finally(() => {
|
|
setExportingData(false);
|
|
});
|
|
}}
|
|
>
|
|
Export data
|
|
</Button>
|
|
<Popconfirm
|
|
title="Permanently delete instance and server saves?"
|
|
okText="Delete"
|
|
placement="bottomRight"
|
|
okButtonProps={{ danger: true }}
|
|
onConfirm={() => {
|
|
libLink.messages.deleteInstance.send(
|
|
control, { instance_id: instanceId }
|
|
).then(() => {
|
|
history.push("/instances");
|
|
}).catch(notifyErrorHandler("Error deleting instance"));
|
|
}}
|
|
>
|
|
<Button
|
|
danger
|
|
disabled={!["unknown", "unassigned", "stopped"].includes(instance["status"])}
|
|
>
|
|
<DeleteOutlined />
|
|
</Button>
|
|
</Popconfirm>
|
|
</Space>;
|
|
|
|
let assigned = instance["assigned_slave"] !== null;
|
|
return <PageLayout nav={nav}>
|
|
<Descriptions
|
|
bordered
|
|
size="small"
|
|
title={instance["name"]}
|
|
extra={instanceButtons}
|
|
>
|
|
<Descriptions.Item label="Slave">
|
|
{!assigned
|
|
? <em>Unassigned</em>
|
|
: slave["name"] || instance["assigned_slave"]
|
|
}
|
|
<AssignInstanceModal
|
|
id={instanceId}
|
|
slaveId={instance["assigned_slave"]}
|
|
buttonProps={{
|
|
size: "small",
|
|
style: { float: "Right" },
|
|
type: assigned ? "default" : "primary",
|
|
disabled: !["unknown", "unassigned", "stopped"].includes(instance["status"]),
|
|
}}
|
|
buttonContent={assigned ? "Reassign" : "Assign"}
|
|
/>
|
|
</Descriptions.Item>
|
|
<Descriptions.Item label="Status">{instance["status"]}</Descriptions.Item>
|
|
</Descriptions>
|
|
|
|
<SavesList instance={instance} />
|
|
<Title level={5} style={{ marginTop: 16 }}>Console</Title>
|
|
<InstanceConsole id={instanceId} />
|
|
<InstanceRcon id={instanceId} disabled={instance["status"] !== "running"} />
|
|
|
|
<InstanceConfigTree id={instanceId} />
|
|
</PageLayout>;
|
|
}
|