From 7769c1f89e015807fd1a1b589ba18f344eda3dd9 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sun, 31 Oct 2021 08:58:26 +0100 Subject: [PATCH] Add SlaveViewPage Add slave overview page displaying instances assigned and some basic properties. --- .../web_ui/src/components/InstanceList.jsx | 58 +++++++++++++++++++ .../web_ui/src/components/InstancesPage.jsx | 46 +-------------- .../web_ui/src/components/SlaveViewPage.jsx | 56 ++++++++++++++++++ packages/web_ui/src/components/SlavesPage.jsx | 7 +++ packages/web_ui/src/index.jsx | 1 + packages/web_ui/src/pages.jsx | 6 ++ 6 files changed, 131 insertions(+), 43 deletions(-) create mode 100644 packages/web_ui/src/components/InstanceList.jsx create mode 100644 packages/web_ui/src/components/SlaveViewPage.jsx diff --git a/packages/web_ui/src/components/InstanceList.jsx b/packages/web_ui/src/components/InstanceList.jsx new file mode 100644 index 00000000..4a010ffa --- /dev/null +++ b/packages/web_ui/src/components/InstanceList.jsx @@ -0,0 +1,58 @@ +import React from "react"; +import { useHistory } from "react-router-dom"; +import { Table } from "antd"; + +import { useSlaveList } from "../model/slave"; + +const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare; + + +export default function InstanceList(props) { + let history = useHistory(); + let [slaveList] = useSlaveList(); + + function slaveName(slaveId) { + let slave = slaveList.find(s => s.id === slaveId); + if (slave) { + return slave.name; + } + return String(slaveId); + } + + let columns = [ + { + title: "Name", + dataIndex: "name", + defaultSortOrder: "ascend", + sorter: (a, b) => strcmp(a["name"], b["name"]), + }, + { + title: "Assigned Slave", + key: "assigned_slave", + render: instance => slaveName(instance["assigned_slave"]), + sorter: (a, b) => strcmp(slaveName(a["assigned_slave"]), slaveName(b["assigned_slave"])), + }, + { + title: "Status", + dataIndex: "status", + sorter: (a, b) => strcmp(a["status"], b["status"]), + }, + ]; + + if (props.hideAssignedSlave) { + columns.splice(1, 1); + } + + return instance["id"]} + pagination={false} + onRow={(record, rowIndex) => ({ + onClick: event => { + history.push(`/instances/${record.id}/view`); + }, + })} + />; +} diff --git a/packages/web_ui/src/components/InstancesPage.jsx b/packages/web_ui/src/components/InstancesPage.jsx index 85996fe2..fb6dbd71 100644 --- a/packages/web_ui/src/components/InstancesPage.jsx +++ b/packages/web_ui/src/components/InstancesPage.jsx @@ -1,6 +1,6 @@ import React, { useContext, useState } from "react"; import { useHistory } from "react-router-dom"; -import { Button, Form, Input, Modal, PageHeader, Table } from "antd"; +import { Button, Form, Input, Modal, PageHeader } from "antd"; import { libConfig, libLink } from "@clusterio/lib"; @@ -8,10 +8,8 @@ import { useAccount } from "../model/account"; import ControlContext from "./ControlContext"; import PageLayout from "./PageLayout"; import { useInstanceList } from "../model/instance"; +import InstanceList from "./InstanceList"; import { notifyErrorHandler } from "../util/notify"; -import { useSlaveList } from "../model/slave"; - -const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare; function CreateInstanceButton(props) { @@ -61,19 +59,9 @@ function CreateInstanceButton(props) { } export default function InstancesPage() { - let history = useHistory(); let account = useAccount(); - let [slaveList] = useSlaveList(); let [instanceList] = useInstanceList(); - function slaveName(slaveId) { - let slave = slaveList.find(s => s.id === slaveId); - if (slave) { - return slave.name; - } - return String(slaveId); - } - return } /> -
strcmp(a["name"], b["name"]), - }, - { - title: "Assigned Slave", - key: "assigned_slave", - render: instance => slaveName(instance["assigned_slave"]), - sorter: (a, b) => strcmp(slaveName(a["assigned_slave"]), slaveName(b["assigned_slave"])), - }, - { - title: "Status", - dataIndex: "status", - sorter: (a, b) => strcmp(a["status"], b["status"]), - }, - ]} - dataSource={instanceList} - rowKey={instance => instance["id"]} - pagination={false} - onRow={(record, rowIndex) => ({ - onClick: event => { - history.push(`/instances/${record.id}/view`); - }, - })} - /> + ; } diff --git a/packages/web_ui/src/components/SlaveViewPage.jsx b/packages/web_ui/src/components/SlaveViewPage.jsx new file mode 100644 index 00000000..f4076073 --- /dev/null +++ b/packages/web_ui/src/components/SlaveViewPage.jsx @@ -0,0 +1,56 @@ +import React, { useContext, useState } from "react"; +import { Descriptions, PageHeader, Spin, Typography } from "antd"; +import { useParams } from "react-router-dom"; + +import InstanceList from "./InstanceList"; +import { useAccount } from "../model/account"; +import { useInstanceList } from "../model/instance"; +import { useSlave } from "../model/slave"; +import PageLayout from "./PageLayout"; + +const { Title } = Typography; + + +export default function SlaveViewPage(props) { + let params = useParams(); + let slaveId = Number(params.id); + let account = useAccount(); + let [instanceList] = useInstanceList(); + let [slave] = useSlave(slaveId); + + instanceList = instanceList.filter(instance => instance["assigned_slave"] === slaveId); + + let nav = [{ name: "Slaves", path: "/slaves" }, { name: slave.name || slaveId }]; + if (slave.loading) { + return ; + } + + if (slave.missing) { + return + +

Slave with id {slaveId} was not found on the master server.

+
; + } + + return + + + + {slave["name"]} + {slave["connected"] ? "yes" : "no"} + {slave["agent"]} + {slave["version"]} + + + {account.hasPermission("core.instance.list") && <> + Instances + + } + ; +} diff --git a/packages/web_ui/src/components/SlavesPage.jsx b/packages/web_ui/src/components/SlavesPage.jsx index f94001a8..9333752a 100644 --- a/packages/web_ui/src/components/SlavesPage.jsx +++ b/packages/web_ui/src/components/SlavesPage.jsx @@ -1,4 +1,5 @@ import React, { useContext, useRef, useState } from "react"; +import { useHistory } from "react-router-dom"; import { Button, Form, Input, Modal, PageHeader, Table } from "antd"; import { libLink } from "@clusterio/lib"; @@ -75,6 +76,7 @@ function GenerateSlaveTokenButton(props) { export default function SlavesPage() { let account = useAccount(); + let history = useHistory(); let [slaveList] = useSlaveList(); return @@ -112,6 +114,11 @@ export default function SlavesPage() { dataSource={slaveList} rowKey={slave => slave["id"]} pagination={false} + onRow={(record, rowIndex) => ({ + onClick: event => { + history.push(`/slaves/${record.id}/view`); + }, + })} /> ; }; diff --git a/packages/web_ui/src/index.jsx b/packages/web_ui/src/index.jsx index a692e723..febfde98 100644 --- a/packages/web_ui/src/index.jsx +++ b/packages/web_ui/src/index.jsx @@ -15,6 +15,7 @@ export { default as MasterConfigTree } from "./components/MasterConfigTree"; export { default as AssignInstanceModal } from "./components/AssignInstanceModal"; export { default as InstanceConsole } from "./components/InstanceConsole"; +export { default as InstanceList } from "./components/InstanceList"; export { default as InstanceRcon } from "./components/InstanceRcon"; export { default as PageLayout } from "./components/PageLayout"; diff --git a/packages/web_ui/src/pages.jsx b/packages/web_ui/src/pages.jsx index b643b0e5..cec0de30 100644 --- a/packages/web_ui/src/pages.jsx +++ b/packages/web_ui/src/pages.jsx @@ -2,6 +2,7 @@ import React from "react"; import MasterPage from "./components/MasterPage"; import SlavesPage from "./components/SlavesPage"; +import SlaveViewPage from "./components/SlaveViewPage"; import InstancesPage from "./components/InstancesPage"; import InstanceViewPage from "./components/InstanceViewPage"; import UsersPage from "./components/UsersPage"; @@ -24,6 +25,11 @@ export const pages = [ permission: "core.slave.list", content: , }, + { + path: "/slaves/:id/view", + sidebarPath: "/slaves", + content: , + }, { path: "/instances", sidebarName: "Instances",