{
+ return {
+ ...x, // Add a 4th parameter to the stock render function with all of our table data
+ render: x.render ? (...originalParams) => x.render(...originalParams, this.state.tableData) : undefined
+ }
+ })}
+ dataSource={this.state.tableData}
+ pagination={this.state.pagination.total > 10 ? this.state.pagination : false}
+ onChange={this.getData.bind(this)}
+ />
+ {this.props.AddRecord && }
+
+ {this.state.inserting ? "Legg til" : "Rediger"}
+ }
+ >
+ {this.state.showEditModal &&
- {col.renderEdit && col.renderEdit(this.state.record[col.dataIndex], this.state.record, undefined /* Non spec compliant, is supposed to be index of record */, this.state.tableData) || }
-
- })
- }
-
-
-
- }
-
-
- >
- }
- inferColumns(data) {
- // Look at the data and find columns and how to display them. Can be overridden by props.Columns if more customization is needed
- let columns = []
- data.forEach(row => {
- Object.keys(row).filter(x => x !== "key").forEach(key => {
- let existing = columns.find(col => col.key === key)
- if (!existing) {
- columns.push({
- key: key,
- title: key,
- dataIndex: key,
- })
- }
- })
- })
- return columns
- }
+ console.log(this.state.record)
+ return
+ {col.renderEdit && col.renderEdit(this.state.record[col.dataIndex], this.state.record, undefined /* Non spec compliant, is supposed to be index of record */, this.state.tableData) || }
+
+ })
+ }
+
+
+
+ }
+
+
+ >
+ }
+ inferColumns(data) {
+ // Look at the data and find columns and how to display them. Can be overridden by props.Columns if more customization is needed
+ let columns = []
+ data.forEach(row => {
+ Object.keys(row).filter(x => x !== "key").forEach(key => {
+ let existing = columns.find(col => col.key === key)
+ if (!existing) {
+ columns.push({
+ key: key,
+ title: key,
+ dataIndex: key,
+ })
+ }
+ })
+ })
+ return columns
+ }
}
export default DataTable;
diff --git a/packages/master/web/layout/index.jsx b/packages/master/web/layout/index.jsx
index 4893ccd9..5a2900ca 100644
--- a/packages/master/web/layout/index.jsx
+++ b/packages/master/web/layout/index.jsx
@@ -19,148 +19,148 @@ const { SubMenu } = Menu;
class SiteLayout extends Component {
- constructor(props) {
- super(props);
- const { location } = props;
+ constructor(props) {
+ super(props);
+ const { location } = props;
- this.state = {
- collapsed: false,
- setcollapsed: false,
- tags: [],
- setTags: [],
- location,
- siteSettings: {},
- factoryModel: []
- };
- }
+ this.state = {
+ collapsed: false,
+ setcollapsed: false,
+ tags: [],
+ setTags: [],
+ location,
+ siteSettings: {},
+ factoryModel: []
+ };
+ }
- onCollapse() {
- this.setState({ collapsed: !this.state.collapsed })
- }
+ onCollapse() {
+ this.setState({ collapsed: !this.state.collapsed })
+ }
- titleCase(text) {
- return text.substring(0, 1).toUpperCase() + text.substring(1);
- }
+ titleCase(text) {
+ return text.substring(0, 1).toUpperCase() + text.substring(1);
+ }
- replaceParametersInUrl({ endpoint, params }) {
- let path = endpoint;
- console.log("endpoint", params)
- Object.keys(params).forEach(key => {
- path = path.replace(":" + key, params[key])
- })
+ replaceParametersInUrl({ endpoint, params }) {
+ let path = endpoint;
+ console.log("endpoint", params)
+ Object.keys(params).forEach(key => {
+ path = path.replace(":" + key, params[key])
+ })
- return path;
- }
+ return path;
+ }
- render() {
- return (
-
- {document.location.search !== "?hideExtras" ? (
-
-
-
- {" "}
- {this.state.collapsed ? (
-

- ) : (
-

- )}
-
-
-
+ render() {
+ return (
+
+ {document.location.search !== "?hideExtras" ? (
+
+
+
+ {" "}
+ {this.state.collapsed ? (
+

+ ) : (
+

+ )}
+
+
+
-
-
- ) : (
- ""
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ ) : (
+ ""
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- );
- }
+
+
+
+ );
+ }
}
export default withRouter(SiteLayout);
diff --git a/packages/master/web/pages/dashboard.jsx b/packages/master/web/pages/dashboard.jsx
index 059a6d69..7fcf6c94 100644
--- a/packages/master/web/pages/dashboard.jsx
+++ b/packages/master/web/pages/dashboard.jsx
@@ -1,10 +1,10 @@
import React, {Component} from "react"
export class Dashboard extends Component {
- constructor(props){
- super(props)
- }
- render(){
- return Dashboard
- }
+ constructor(props){
+ super(props)
+ }
+ render(){
+ return Dashboard
+ }
}
\ No newline at end of file
diff --git a/packages/master/web/pages/instances/instance.jsx b/packages/master/web/pages/instances/instance.jsx
index d5d51cb6..81024e50 100644
--- a/packages/master/web/pages/instances/instance.jsx
+++ b/packages/master/web/pages/instances/instance.jsx
@@ -1,17 +1,17 @@
import React, { Component } from "react"
import { Card, Button, Popover, Select, Divider, Input, Form, Col, Row, Checkbox, Space } from "antd"
import {
- listSlaves,
- listInstances,
- startInstance,
- stopInstance,
- setInstanceOutputSubscriptions,
- deleteInstance,
- assignInstance,
- createSave,
- getInstanceConfig,
- setInstanceConfigField,
- sendRcon,
+ listSlaves,
+ listInstances,
+ startInstance,
+ stopInstance,
+ setInstanceOutputSubscriptions,
+ deleteInstance,
+ assignInstance,
+ createSave,
+ getInstanceConfig,
+ setInstanceConfigField,
+ sendRcon,
} from "../../util/wslink"
import DataTable from "../../components/data-table"
import notify from "../../util/notify"
@@ -22,208 +22,208 @@ import PlusOutlined from "@ant-design/icons/PlusOutlined"
const { Option } = Select
export class InstanceView extends Component {
- constructor(props) {
- super(props)
- this.state = {
- instance: {},
- slaves: [],
- logLines: [{ message: "Logviewer. Follows the latest logs if you scroll to the bottom. Does not store logs past the lifetime of this tab" }],
- }
- this.messagesEndRef = React.createRef()
- }
- navigate(url) {
- this.props.history.push(url);
- }
- async componentDidMount() {
- let id = this.props.match.params.id
+ constructor(props) {
+ super(props)
+ this.state = {
+ instance: {},
+ slaves: [],
+ logLines: [{ message: "Logviewer. Follows the latest logs if you scroll to the bottom. Does not store logs past the lifetime of this tab" }],
+ }
+ this.messagesEndRef = React.createRef()
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ async componentDidMount() {
+ let id = this.props.match.params.id
- await this.getData()
+ await this.getData()
- await setInstanceOutputSubscriptions({
- instance_id: Number(id),
- })
- window.instanceOutputEventHandler = ({ instance_id, output }) => {
- if (instance_id === Number(id)) {
- this.setState({
- logLines: [...this.state.logLines, output],
- })
- }
- // Automatically scroll to bottom on new line.
- // this.messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
- }
- }
- async getData() {
- let id = this.props.match.params.id
+ await setInstanceOutputSubscriptions({
+ instance_id: Number(id),
+ })
+ window.instanceOutputEventHandler = ({ instance_id, output }) => {
+ if (instance_id === Number(id)) {
+ this.setState({
+ logLines: [...this.state.logLines, output],
+ })
+ }
+ // Automatically scroll to bottom on new line.
+ // this.messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
+ }
+ }
+ async getData() {
+ let id = this.props.match.params.id
- let instances = await listInstances()
- let slaves = await listSlaves()
+ let instances = await listInstances()
+ let slaves = await listSlaves()
- this.setState({
- instance: instances.find(x => x.id === Number(id)),
- slaves,
- })
+ this.setState({
+ instance: instances.find(x => x.id === Number(id)),
+ slaves,
+ })
- let config = await getInstanceConfig({ instance_id: Number(id) })
- console.log(config)
- this.setState({
- config
- })
- }
- async start() {
- this.setState({
- starting: true,
- })
- try {
- await startInstance({
- instance_id: this.state.instance.id,
- save: null,
- })
- } catch (e) {
- notify("Error starting instance", "error", e.message)
- return this.setState({
- starting: false,
- })
- }
- notify("Instance started")
- this.setState({
- starting: false,
- })
- this.getData()
- }
- async stop() {
- this.setState({
- stopping: true,
- })
- try {
- await stopInstance({
- instance_id: this.state.instance.id,
- })
- } catch (e) {
- notify("Error stopping instance", "error", e.message)
- return this.setState({
- stopping: false,
- })
- }
- notify("Instance stopped")
- this.setState({
- stopping: false,
- })
- this.getData()
- }
- async createSave() {
- this.setState({
- creatingSave: true,
- })
- try {
- await createSave({
- instance_id: this.state.instance.id,
- })
- } catch (e) {
- notify("Error creating save", "error", e.message)
- return this.setState({
- creatingSave: false,
- })
- }
- notify("Save created", "success")
- this.setState({
- creatingSave: false,
- })
- }
- async onConfigEditFinish(values) {
- console.log("Completed config edit with", values)
- for (let k in values) {
- if (values[k] !== this.getInstanceConfigAsKvObject(this.state.config)[k]) {
- let value = values[k]
- if (typeof value === "boolean") value = value.toString()
- console.log("Setting", k, value)
- await setInstanceConfigField({
- instance_id: this.state.instance.id,
- field: k,
- value: value,
- })
- }
- }
- notify("Set configuration fields", "success")
- this.setState({
- editingConfig: false
- })
- this.getData()
- }
- render() {
- console.log(this.state)
- let { instance, slaves } = this.state
- let slave = slaves && slaves.find(x => x.id === instance.assigned_slave);
- return
- {instance.name}
- ID: {instance.id}
- Slave: {slave && slave.name}
- {instance.status !== "running" &&
+
+ {
+ await deleteInstance({ instance_id: instance.id });
+ notify("Deleted instance " + instance.id, "success")
+ this.navigate("/instances")
+ }}
+ >
Delete this instance permanently
-
- }
- trigger="click"
- >
-
-
-
-
-
-
- {/* rcon input field */}
-
-
-
-
- {this.state.config && this.renderConfig(this.state.config)}
-
- }
- getInstanceConfigAsKvObject(config) {
- let object = {}
- for (let group of config.serialized_config.groups) {
- for (let fieldName in group.fields) {
- object[group.name + "." + fieldName] = group.fields[fieldName]
- }
- }
- return object
- }
- renderConfig(config) {
- const layout = {
- labelCol: {
- span: 6,
- },
- wrapperCol: {
- span: 14,
- },
- };
- const tailLayout = {
- wrapperCol: {
- offset: 6,
- span: 14,
- },
- };
- return
-
-
+
+
+ {/* rcon input field */}
+
+
+
+
+ {this.state.config && this.renderConfig(this.state.config)}
+
+ }
+ getInstanceConfigAsKvObject(config) {
+ let object = {}
+ for (let group of config.serialized_config.groups) {
+ for (let fieldName in group.fields) {
+ object[group.name + "." + fieldName] = group.fields[fieldName]
+ }
+ }
+ return object
+ }
+ renderConfig(config) {
+ const layout = {
+ labelCol: {
+ span: 6,
+ },
+ wrapperCol: {
+ span: 14,
+ },
+ };
+ const tailLayout = {
+ wrapperCol: {
+ offset: 6,
+ span: 14,
+ },
+ };
+ return
+
+
Save config changes
-
-
- :
- this.setState({ editingConfig: true })}>
- Edit config
-
- }
-
- {config && config.serialized_config.groups.map(group => <>
-
- {group.name}
- {/* {Object.keys(group.fields).map(field => <>
+
+
+ :
+ this.setState({ editingConfig: true })}>
+ Edit config
+
+ }
+
+ {config && config.serialized_config.groups.map(group => <>
+
+ {group.name}
+ {/* {Object.keys(group.fields).map(field => <>
{field}:
{JSON.stringify(group.fields[field])}
>)} */}
- {console.log(group)}
- {Object.keys(group.fields).map(field => )}
-
- >)}
-
-
-
- }
+ {console.log(group)}
+ {Object.keys(group.fields).map(field => )}
+
+ >)}
+
+
+
+ }
}
function renderDisplayField(value) {
- if (typeof value === "object") {
- return JSON.stringify(value)
- }
- if (typeof value === "boolean") {
- return
- }
- return value.toString()
+ if (typeof value === "object") {
+ return JSON.stringify(value)
+ }
+ if (typeof value === "boolean") {
+ return
+ }
+ return value.toString()
}
function renderFormField(value) {
- if (typeof value === "object") {
- return
- }
- if (typeof value === "boolean") {
- return
- }
- return
+ if (typeof value === "object") {
+ return
+ }
+ if (typeof value === "boolean") {
+ return
+ }
+ return
}
class ObjectInput extends Component {
- constructor(props) {
- super(props)
- console.log(this.props)
- /*
+ constructor(props) {
+ super(props)
+ console.log(this.props)
+ /*
value: {
auto_pause: false,
tags: ["clusterio"]
@@ -351,89 +351,89 @@ class ObjectInput extends Component {
id: "factorio.settings",
onChange: f()
*/
- this.state = {}
- }
- onChange(e, key) {
- if (e.target.type === "checkbox") {
- // if (e.target.checked !== undefined) {
- // Its a checkbox, set value to true/false
- let value = { ...this.props.value }
- value[key] = e.target.checked || false
- this.props.onChange(value)
- } else if (e.target.type === "text") {
- // } else if (e.target.value !== undefined) {
- // its probably a text input
- let value = { ...this.props.value }
- value[key] = e.target.value || ""
- this.props.onChange(value)
- }
- }
- render() {
- let { value } = this.props
- let ret = []
- for (let key in value) {
- if (typeof value[key] === "boolean") {
- ret.push( this.onChange(e, key)}
- >
- {key}
-
- )
- } else if (typeof value[key] === "string") {
- ret.push({key} this.onChange(e, key)}
- />
- )
- }
- }
- ret.push(
- this.setState({ newInput: e.target.value })} />
- {
- this.onChange({ target: { value: "", type: "text" } }, this.state.newInput)
- this.setState({
- newInput: undefined,
- addPopoverVisible: false,
- })
- }}
- >Add property
- >}
- trigger="click"
- visible={this.state.addPopoverVisible}
- handleVisibleChange={visible => this.setState({ addPopoverVisible: visible })}
- >
- this.setState({ addPopoverVisible: true })}
- >
- Add property
-
- )
- return {ret}
- }
+ this.state = {}
+ }
+ onChange(e, key) {
+ if (e.target.type === "checkbox") {
+ // if (e.target.checked !== undefined) {
+ // Its a checkbox, set value to true/false
+ let value = { ...this.props.value }
+ value[key] = e.target.checked || false
+ this.props.onChange(value)
+ } else if (e.target.type === "text") {
+ // } else if (e.target.value !== undefined) {
+ // its probably a text input
+ let value = { ...this.props.value }
+ value[key] = e.target.value || ""
+ this.props.onChange(value)
+ }
+ }
+ render() {
+ let { value } = this.props
+ let ret = []
+ for (let key in value) {
+ if (typeof value[key] === "boolean") {
+ ret.push( this.onChange(e, key)}
+ >
+ {key}
+
+ )
+ } else if (typeof value[key] === "string") {
+ ret.push({key} this.onChange(e, key)}
+ />
+ )
+ }
+ }
+ ret.push(
+ this.setState({ newInput: e.target.value })} />
+ {
+ this.onChange({ target: { value: "", type: "text" } }, this.state.newInput)
+ this.setState({
+ newInput: undefined,
+ addPopoverVisible: false,
+ })
+ }}
+ >Add property
+ >}
+ trigger="click"
+ visible={this.state.addPopoverVisible}
+ handleVisibleChange={visible => this.setState({ addPopoverVisible: visible })}
+ >
+ this.setState({ addPopoverVisible: true })}
+ >
+ Add property
+
+ )
+ return {ret}
+ }
}
class ConfigFormItem extends Component {
- constructor(props) {
- super(props)
- }
- render() {
- let { field, group, editingConfig } = this.props
- return
- {editingConfig ?
- renderFormField(group.fields[field])
- :
- renderDisplayField(group.fields[field])
- }
-
- }
+ constructor(props) {
+ super(props)
+ }
+ render() {
+ let { field, group, editingConfig } = this.props
+ return
+ {editingConfig ?
+ renderFormField(group.fields[field])
+ :
+ renderDisplayField(group.fields[field])
+ }
+
+ }
}
diff --git a/packages/master/web/pages/instances/instancesTable.jsx b/packages/master/web/pages/instances/instancesTable.jsx
index 21a86e15..d73e4f88 100644
--- a/packages/master/web/pages/instances/instancesTable.jsx
+++ b/packages/master/web/pages/instances/instancesTable.jsx
@@ -5,42 +5,42 @@ import DataTable from "../../components/data-table"
const config = require("@clusterio/lib/config")
export class InstancesTable extends Component {
- constructor(props) {
- super(props)
- }
- navigate(url) {
- this.props.history.push(url);
- }
- render() {
- return
- Instances
- {
- let instanceConfig = new config.InstanceConfig();
- await instanceConfig.init();
- console.log("Base config", instanceConfig)
- instanceConfig.set("instance.name", args.name);
- let serialized_config = instanceConfig.serialize();
- let response = await createInstance(serialized_config)
- console.log("Created instance", response)
- }
- }}
- DataFunction={listInstances}
- TableProps={{
- onRow: (record, rowIndex) => {
- return {
- onClick: event => {
- this.navigate(`/instances/${record.id}/view`)
- }
- }
- }
- }}
- />
-
- }
+ constructor(props) {
+ super(props)
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ render() {
+ return
+ Instances
+ {
+ let instanceConfig = new config.InstanceConfig();
+ await instanceConfig.init();
+ console.log("Base config", instanceConfig)
+ instanceConfig.set("instance.name", args.name);
+ let serialized_config = instanceConfig.serialize();
+ let response = await createInstance(serialized_config)
+ console.log("Created instance", response)
+ }
+ }}
+ DataFunction={listInstances}
+ TableProps={{
+ onRow: (record, rowIndex) => {
+ return {
+ onClick: event => {
+ this.navigate(`/instances/${record.id}/view`)
+ }
+ }
+ }
+ }}
+ />
+
+ }
}
diff --git a/packages/master/web/pages/permissions/permissionsTable.jsx b/packages/master/web/pages/permissions/permissionsTable.jsx
index eb63f893..8bcf995c 100644
--- a/packages/master/web/pages/permissions/permissionsTable.jsx
+++ b/packages/master/web/pages/permissions/permissionsTable.jsx
@@ -4,27 +4,27 @@ import { listSlaves, listInstances, listPermissions } from "../../util/wslink"
import DataTable from "../../components/data-table"
export class PermissionsTable extends Component {
- constructor(props) {
- super(props)
- }
- navigate(url) {
- this.props.history.push(url);
- }
- render() {
- return
- Permissions
- {
- return {
- onClick: event => {
- this.navigate(`/permissions/${record.id}/view`)
- }
- }
- }
- }}
- />
-
- }
+ constructor(props) {
+ super(props)
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ render() {
+ return
+ Permissions
+ {
+ return {
+ onClick: event => {
+ this.navigate(`/permissions/${record.id}/view`)
+ }
+ }
+ }
+ }}
+ />
+
+ }
}
diff --git a/packages/master/web/pages/roles/role.jsx b/packages/master/web/pages/roles/role.jsx
index 7634e616..625a25e0 100644
--- a/packages/master/web/pages/roles/role.jsx
+++ b/packages/master/web/pages/roles/role.jsx
@@ -4,23 +4,23 @@ import { Card, Button, Popover, Select, Transfer } from "antd"
import DeleteOutlined from "@ant-design/icons/DeleteOutlined"
import {
- listSlaves,
- listInstances,
- startInstance,
- stopInstance,
- setInstanceOutputSubscriptions,
- deleteInstance,
- assignInstance,
- createSave,
- getInstanceConfig,
- setInstanceConfigField,
- sendRcon,
- deleteUser,
- listUsers,
- listRoles,
- setRoles,
- listPermissions,
- updateRole,
+ listSlaves,
+ listInstances,
+ startInstance,
+ stopInstance,
+ setInstanceOutputSubscriptions,
+ deleteInstance,
+ assignInstance,
+ createSave,
+ getInstanceConfig,
+ setInstanceConfigField,
+ sendRcon,
+ deleteUser,
+ listUsers,
+ listRoles,
+ setRoles,
+ listPermissions,
+ updateRole,
} from "../../util/wslink"
import DataTable from "../../components/data-table"
import notify from "../../util/notify"
@@ -28,86 +28,86 @@ import notify from "../../util/notify"
const { Option } = Select
export class RoleView extends Component {
- constructor(props) {
- super(props)
- this.state = {
- role: {}
- }
- this.messagesEndRef = React.createRef()
- }
- navigate(url) {
- this.props.history.push(url);
- }
- async componentDidMount() {
- await this.getData()
- }
- async getData() {
- let id = this.props.match.params.id
+ constructor(props) {
+ super(props)
+ this.state = {
+ role: {}
+ }
+ this.messagesEndRef = React.createRef()
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ async componentDidMount() {
+ await this.getData()
+ }
+ async getData() {
+ let id = this.props.match.params.id
- let roles = await listRoles()
- let permissions = await listPermissions()
+ let roles = await listRoles()
+ let permissions = await listPermissions()
- this.setState({
- role: roles.find(x => x.id === Number(id)),
- permissions,
- })
- }
- async handleChange(targetKeys) {
- this.setState({
- role: {
- ...this.state.role,
- permissions: targetKeys
- }
- });
- let response = await updateRole({
- ...this.state.role,
- permissions: targetKeys,
- })
- console.log("Updated user roles", response)
- }
- render() {
- console.log(this.state)
- let { role, permissions } = this.state
- return
- {
- await deleteUser({ role: role.name })
- notify("Deleted role " + role.name, "success")
- this.navigate("/roles")
- }}
- >
+ this.setState({
+ role: roles.find(x => x.id === Number(id)),
+ permissions,
+ })
+ }
+ async handleChange(targetKeys) {
+ this.setState({
+ role: {
+ ...this.state.role,
+ permissions: targetKeys
+ }
+ });
+ let response = await updateRole({
+ ...this.state.role,
+ permissions: targetKeys,
+ })
+ console.log("Updated user roles", response)
+ }
+ render() {
+ console.log(this.state)
+ let { role, permissions } = this.state
+ return
+ {
+ await deleteUser({ role: role.name })
+ notify("Deleted role " + role.name, "success")
+ this.navigate("/roles")
+ }}
+ >
Delete this role permanently
-
- }
- trigger="click"
- >
-
-
-
-
- {role.name}
- Assign roles
-
- option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1}
- targetKeys={role.permissions}
- onChange={this.handleChange.bind(this)}
- render={item => item.name}
- />
-
- }
+
+ option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1}
+ targetKeys={role.permissions}
+ onChange={this.handleChange.bind(this)}
+ render={item => item.name}
+ />
+
+ }
}
diff --git a/packages/master/web/pages/roles/rolesTable.jsx b/packages/master/web/pages/roles/rolesTable.jsx
index 4e0f0f2a..6dd3af92 100644
--- a/packages/master/web/pages/roles/rolesTable.jsx
+++ b/packages/master/web/pages/roles/rolesTable.jsx
@@ -4,40 +4,40 @@ import { listSlaves, listInstances, listRoles, createRole } from "../../util/wsl
import DataTable from "../../components/data-table"
export class RolesTable extends Component {
- constructor(props) {
- super(props)
- }
- navigate(url) {
- this.props.history.push(url);
- }
- render() {
- return
- Roles
- {
- let response = await createRole({name: args.name, description: args.description})
- console.log("Created role",response)
- }
- }}
- DataFunction={listRoles}
- TableProps={{
- onRow: (record, rowIndex) => {
- return {
- onClick: event => {
- this.navigate(`/roles/${record.id}/view`)
- }
- }
- }
- }}
- />
-
- }
+ constructor(props) {
+ super(props)
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ render() {
+ return
+ Roles
+ {
+ let response = await createRole({name: args.name, description: args.description})
+ console.log("Created role",response)
+ }
+ }}
+ DataFunction={listRoles}
+ TableProps={{
+ onRow: (record, rowIndex) => {
+ return {
+ onClick: event => {
+ this.navigate(`/roles/${record.id}/view`)
+ }
+ }
+ }
+ }}
+ />
+
+ }
}
diff --git a/packages/master/web/pages/settings/settings.jsx b/packages/master/web/pages/settings/settings.jsx
index d4fcf35d..e725d01b 100644
--- a/packages/master/web/pages/settings/settings.jsx
+++ b/packages/master/web/pages/settings/settings.jsx
@@ -2,80 +2,80 @@ import React, { Component } from "react"
import { Card, Button, Input, Form } from "antd"
const layout = {
- labelCol: {
- span: 4,
- },
- wrapperCol: {
- span: 16,
- },
+ labelCol: {
+ span: 4,
+ },
+ wrapperCol: {
+ span: 16,
+ },
};
const tailLayout = {
- wrapperCol: {
- offset: 4,
- span: 16,
- },
+ wrapperCol: {
+ offset: 4,
+ span: 16,
+ },
};
export class Settings extends Component {
- constructor(props) {
- super(props)
- this.state = {
- role: {}
- }
- }
- navigate(url) {
- this.props.history.push(url);
- }
- render() {
- console.log(this.state)
- return
- Web interface settings
-
-
-
-
-
-
-
-
+ constructor(props) {
+ super(props)
+ this.state = {
+ role: {}
+ }
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ render() {
+ console.log(this.state)
+ return
+ Web interface settings
+
+
+
+
+
+
+
+
Save
-
-
-
-
- }
+
+
+
+
+ }
}
diff --git a/packages/master/web/pages/slaves/slavesTable.jsx b/packages/master/web/pages/slaves/slavesTable.jsx
index a2744e55..f0450be1 100644
--- a/packages/master/web/pages/slaves/slavesTable.jsx
+++ b/packages/master/web/pages/slaves/slavesTable.jsx
@@ -4,27 +4,27 @@ import { listSlaves, listInstances } from "../../util/wslink"
import DataTable from "../../components/data-table"
export class SlavesTable extends Component {
- constructor(props) {
- super(props)
- }
- navigate(url) {
- this.props.history.push(url);
- }
- render() {
- return
- Slaves
- {
- return {
- onClick: event => {
- this.navigate(`/slaves/${record.id}/view`)
- }
- }
- }
- }}
- />
-
- }
+ constructor(props) {
+ super(props)
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ render() {
+ return
+ Slaves
+ {
+ return {
+ onClick: event => {
+ this.navigate(`/slaves/${record.id}/view`)
+ }
+ }
+ }
+ }}
+ />
+
+ }
}
diff --git a/packages/master/web/pages/users/user.jsx b/packages/master/web/pages/users/user.jsx
index 819ecec9..9989ab27 100644
--- a/packages/master/web/pages/users/user.jsx
+++ b/packages/master/web/pages/users/user.jsx
@@ -1,10 +1,10 @@
import React, { Component } from "react"
import { Card, Button, Popover, Select, Transfer } from "antd";
import {
- deleteUser,
- listUsers,
- listRoles,
- setRoles,
+ deleteUser,
+ listUsers,
+ listRoles,
+ setRoles,
} from "../../util/wslink"
import DataTable from "../../components/data-table"
import notify from "../../util/notify"
@@ -13,78 +13,78 @@ import DeleteOutlined from "@ant-design/icons/DeleteOutlined"
const { Option } = Select
export class UserView extends Component {
- constructor(props) {
- super(props)
- this.state = {
- user: {}
- }
- this.messagesEndRef = React.createRef();
- }
- navigate(url) {
- this.props.history.push(url);
- }
- async componentDidMount() {
- await this.getData()
- }
- async getData() {
- let name = this.props.match.params.id
+ constructor(props) {
+ super(props)
+ this.state = {
+ user: {}
+ }
+ this.messagesEndRef = React.createRef();
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ async componentDidMount() {
+ await this.getData()
+ }
+ async getData() {
+ let name = this.props.match.params.id
- let users = await listUsers()
- let roles = await listRoles()
+ let users = await listUsers()
+ let roles = await listRoles()
- this.setState({
- user: users.find(x => x.name === name),
- roles,
- })
- }
- async handleChange(targetKeys) {
- this.setState({
- user: {
- ...this.state.user,
- roles: targetKeys
- }
- });
- let response = await setRoles({
- name: this.state.user.name,
- roles: targetKeys,
- })
- console.log("Updated user roles",response)
- };
- render() {
- console.log(this.state)
- let { user, roles } = this.state
- return
- {user.name}
- Assign roles
- option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1}
- targetKeys={user.roles}
- onChange={this.handleChange.bind(this)}
- render={item => item.name}
- />
- {
- await deleteUser({ name: user.name })
- notify("Deleted user " + user.name, "success")
- this.navigate("/users")
- }}
- >
+ this.setState({
+ user: users.find(x => x.name === name),
+ roles,
+ })
+ }
+ async handleChange(targetKeys) {
+ this.setState({
+ user: {
+ ...this.state.user,
+ roles: targetKeys
+ }
+ });
+ let response = await setRoles({
+ name: this.state.user.name,
+ roles: targetKeys,
+ })
+ console.log("Updated user roles",response)
+ };
+ render() {
+ console.log(this.state)
+ let { user, roles } = this.state
+ return
+ {user.name}
+ Assign roles
+ option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1}
+ targetKeys={user.roles}
+ onChange={this.handleChange.bind(this)}
+ render={item => item.name}
+ />
+ {
+ await deleteUser({ name: user.name })
+ notify("Deleted user " + user.name, "success")
+ this.navigate("/users")
+ }}
+ >
Delete this user from the cluster
-
- }
- trigger="click"
- >
-
-
-
-
-
- }
+
+ }
+ trigger="click"
+ >
+
+
+
+
+
+ }
}
diff --git a/packages/master/web/pages/users/usersTable.jsx b/packages/master/web/pages/users/usersTable.jsx
index 7a1a253c..7f22e4a1 100644
--- a/packages/master/web/pages/users/usersTable.jsx
+++ b/packages/master/web/pages/users/usersTable.jsx
@@ -4,37 +4,37 @@ import { listSlaves, listInstances, listUsers, createUser } from "../../util/wsl
import DataTable from "../../components/data-table"
export class UsersTable extends Component {
- constructor(props) {
- super(props)
- }
- navigate(url) {
- this.props.history.push(url);
- }
- render() {
- return
- Slaves
- {
- let response = await createUser({name: args.name})
- console.log("Created user",response)
- }
- }}
- DataFunction={listUsers}
- TableProps={{
- onRow: (record, rowIndex) => {
- return {
- onClick: event => {
- this.navigate(`/users/${record.name}/view`)
- }
- }
- }
- }}
- />
-
- }
+ constructor(props) {
+ super(props)
+ }
+ navigate(url) {
+ this.props.history.push(url);
+ }
+ render() {
+ return
+ Slaves
+ {
+ let response = await createUser({name: args.name})
+ console.log("Created user",response)
+ }
+ }}
+ DataFunction={listUsers}
+ TableProps={{
+ onRow: (record, rowIndex) => {
+ return {
+ onClick: event => {
+ this.navigate(`/users/${record.name}/view`)
+ }
+ }
+ }
+ }}
+ />
+
+ }
}
diff --git a/packages/master/web/util/notify.jsx b/packages/master/web/util/notify.jsx
index 8df6b7c5..40801c98 100644
--- a/packages/master/web/util/notify.jsx
+++ b/packages/master/web/util/notify.jsx
@@ -6,10 +6,10 @@ import { notification } from "antd";
* @param {("info"|"error"|"success"|"warning"|"warn")} type
*/
export default function notify(message, type = "info", description) {
- notification[type]({
- message: typeof message === "string" ? message : "ERROR: See console",
- description,
- placement: "bottomRight",
- });
- if (typeof message !== "string") console.error(message)
+ notification[type]({
+ message: typeof message === "string" ? message : "ERROR: See console",
+ description,
+ placement: "bottomRight",
+ });
+ if (typeof message !== "string") console.error(message)
}
diff --git a/packages/master/web/util/websocket.jsx b/packages/master/web/util/websocket.jsx
index a0a2e8e4..08fb435c 100644
--- a/packages/master/web/util/websocket.jsx
+++ b/packages/master/web/util/websocket.jsx
@@ -36,19 +36,19 @@ function formatOutput(output) {
* @private
*/
export class ControlConnector extends link.WebSocketClientConnector {
- constructor(url, reconnectDelay, token) {
- super(url, reconnectDelay);
- this._token = token;
- }
+ constructor(url, reconnectDelay, token) {
+ super(url, reconnectDelay);
+ this._token = token;
+ }
- register() {
- console.log("SOCKET | registering control");
- this.sendHandshake("register_control", {
- token: this._token,
- agent: "web",
- version: "2.0.0-alpha",
- });
- }
+ register() {
+ console.log("SOCKET | registering control");
+ this.sendHandshake("register_control", {
+ token: this._token,
+ agent: "web",
+ version: "2.0.0-alpha",
+ });
+ }
}
/**
@@ -58,41 +58,41 @@ export class ControlConnector extends link.WebSocketClientConnector {
* @static
*/
export class Control extends link.Link {
- constructor(connector, controlPlugins) {
- super("control", "master", connector);
- link.attachAllMessages(this);
+ constructor(connector, controlPlugins) {
+ super("control", "master", connector);
+ link.attachAllMessages(this);
- /**
+ /**
* Mapping of plugin names to their instance for loaded plugins.
* @type {Map}
*/
- this.plugins = controlPlugins;
- for (let controlPlugin of controlPlugins.values()) {
- plugin.attachPluginMessages(this, controlPlugin.info, controlPlugin);
- }
- }
+ this.plugins = controlPlugins;
+ for (let controlPlugin of controlPlugins.values()) {
+ plugin.attachPluginMessages(this, controlPlugin.info, controlPlugin);
+ }
+ }
- async instanceOutputEventHandler(message) {
- let { instance_id, output } = message.data;
- console.log(formatOutput(output));
- window.instanceOutputEventHandler && window.instanceOutputEventHandler({instance_id, output})
- }
+ async instanceOutputEventHandler(message) {
+ let { instance_id, output } = message.data;
+ console.log(formatOutput(output));
+ window.instanceOutputEventHandler && window.instanceOutputEventHandler({instance_id, output})
+ }
- async debugWsMessageEventHandler(message) {
- console.log("WS", message.data.direction, message.data.content);
- }
+ async debugWsMessageEventHandler(message) {
+ console.log("WS", message.data.direction, message.data.content);
+ }
- async shutdown() {
- this.connector.setTimeout(30);
+ async shutdown() {
+ this.connector.setTimeout(30);
- try {
- await link.messages.prepareDisconnect.send(this);
- } catch (err) {
- if (!(err instanceof errors.SessionLost)) {
- throw err;
- }
- }
+ try {
+ await link.messages.prepareDisconnect.send(this);
+ } catch (err) {
+ if (!(err instanceof errors.SessionLost)) {
+ throw err;
+ }
+ }
- await this.connector.close(1001, "Control Quit");
- }
+ await this.connector.close(1001, "Control Quit");
+ }
}
diff --git a/packages/master/web/util/wslink.jsx b/packages/master/web/util/wslink.jsx
index 3ff8e297..68b6f820 100644
--- a/packages/master/web/util/wslink.jsx
+++ b/packages/master/web/util/wslink.jsx
@@ -7,18 +7,18 @@ let control, controlConnector
// Create WS connection to master. Used by all components through the interface exported here.
(async () => {
- config.finalizeConfigs();
- controlConnector = new ControlConnector(
- localStorage.getItem("master_url"),
- 10, // Reconnect delay
- localStorage.getItem("master_token"),
- );
- control = new Control(controlConnector, []);
- try {
- await controlConnector.connect();
- } catch (err) {
- console.log(err)
- }
+ config.finalizeConfigs();
+ controlConnector = new ControlConnector(
+ localStorage.getItem("master_url"),
+ 10, // Reconnect delay
+ localStorage.getItem("master_token"),
+ );
+ control = new Control(controlConnector, []);
+ try {
+ await controlConnector.connect();
+ } catch (err) {
+ console.log(err)
+ }
})()
let listSlaves = createListFunction("listSlaves")
@@ -28,107 +28,107 @@ let listRoles = createListFunction("listRoles")
let listPermissions = createListFunction("listPermissions", "name")
let startInstance = async function ({ instance_id, save = null }) {
- return await link.messages.startInstance.send(control, { instance_id, save })
+ return await link.messages.startInstance.send(control, { instance_id, save })
}
let stopInstance = async function ({ instance_id }) {
- return await link.messages.stopInstance.send(control, { instance_id })
+ return await link.messages.stopInstance.send(control, { instance_id })
}
let createInstance = async function (serialized_config) {
- return await link.messages.createInstance.send(control, { serialized_config });
+ return await link.messages.createInstance.send(control, { serialized_config });
}
let deleteInstance = async function ({ instance_id }) {
- return await link.messages.deleteInstance.send(control, { instance_id });
+ return await link.messages.deleteInstance.send(control, { instance_id });
}
let assignInstance = async function ({ instance_id, slave_id }) {
- return await link.messages.assignInstanceCommand.send(control, {
- instance_id,
- slave_id,
- });
+ return await link.messages.assignInstanceCommand.send(control, {
+ instance_id,
+ slave_id,
+ });
}
let createSave = async function ({ instance_id }) {
- return await link.messages.createSave.send(control, { instance_id });
+ return await link.messages.createSave.send(control, { instance_id });
}
let getInstanceConfig = async function ({ instance_id }) {
- return await link.messages.getInstanceConfig.send(control, { instance_id });
+ return await link.messages.getInstanceConfig.send(control, { instance_id });
}
let setInstanceConfigField = async function ({ instance_id, field, value }) {
- return await link.messages.setInstanceConfigField.send(control, {
- instance_id,
- field,
- value: typeof value === "object" ? JSON.stringify(value) : value,
- });
+ return await link.messages.setInstanceConfigField.send(control, {
+ instance_id,
+ field,
+ value: typeof value === "object" ? JSON.stringify(value) : value,
+ });
}
let setInstanceConfigProp = async function ({ instance_id, field, prop, value }) {
- return await link.messages.setInstanceConfigProp.send(control, {
- instance_id,
- field,
- prop,
- value, // JSON Object
- });
+ return await link.messages.setInstanceConfigProp.send(control, {
+ instance_id,
+ field,
+ prop,
+ value, // JSON Object
+ });
}
let sendRcon = async function ({ instance_id, command }) {
- return await link.messages.sendRcon.send(control, { instance_id, command })
+ return await link.messages.sendRcon.send(control, { instance_id, command })
}
let setInstanceOutputSubscriptions = async function ({ instance_id }) {
- return await link.messages.setInstanceOutputSubscriptions.send(control, { instance_ids: [instance_id] })
+ return await link.messages.setInstanceOutputSubscriptions.send(control, { instance_ids: [instance_id] })
}
let createUser = async function ({ name }) {
- return await link.messages.createUser.send(control, { name })
+ return await link.messages.createUser.send(control, { name })
}
let deleteUser = async function ({ name }) {
- return await link.messages.deleteUser.send(control, { name })
+ return await link.messages.deleteUser.send(control, { name })
}
let setRoles = async function ({ name, roles }) {
- return await link.messages.updateUserRoles.send(control, {
- name,
- roles,
- })
+ return await link.messages.updateUserRoles.send(control, {
+ name,
+ roles,
+ })
}
let createRole = async function ({ name, description, permissions = [] }) {
- return await link.messages.createRole.send(control, { name, description, permissions })
+ return await link.messages.createRole.send(control, { name, description, permissions })
}
let updateRole = async function ({ id, name, description, permissions }) {
- return await link.messages.updateRole.send(control, {
- id, name, description, permissions
- })
+ return await link.messages.updateRole.send(control, {
+ id, name, description, permissions
+ })
}
export {
- listSlaves,
- listInstances,
- listUsers,
- createUser,
- deleteUser,
- listRoles,
- setRoles,
- createRole,
- updateRole,
- listPermissions,
- startInstance,
- stopInstance,
- createInstance,
- deleteInstance,
- assignInstance,
- createSave,
- getInstanceConfig,
- setInstanceConfigField,
- setInstanceConfigProp,
- sendRcon,
- setInstanceOutputSubscriptions,
+ listSlaves,
+ listInstances,
+ listUsers,
+ createUser,
+ deleteUser,
+ listRoles,
+ setRoles,
+ createRole,
+ updateRole,
+ listPermissions,
+ startInstance,
+ stopInstance,
+ createInstance,
+ deleteInstance,
+ assignInstance,
+ createSave,
+ getInstanceConfig,
+ setInstanceConfigField,
+ setInstanceConfigProp,
+ sendRcon,
+ setInstanceOutputSubscriptions,
}
function createListFunction(name, key) {
- return async () => {
- return (await link.messages[name].send(control)).list.map(addKey(key || "id"));
- }
+ return async () => {
+ return (await link.messages[name].send(control)).list.map(addKey(key || "id"));
+ }
}
function addKey(key) {
- return function (el) {
- return {
- ...el,
- key: el[key]
- }
- }
+ return function (el) {
+ return {
+ ...el,
+ key: el[key]
+ }
+ }
}