diff --git a/resources/scripts/api/admin/nodes/getNodes.ts b/resources/scripts/api/admin/nodes/getNodes.ts index 961fba1e8..d70224673 100644 --- a/resources/scripts/api/admin/nodes/getNodes.ts +++ b/resources/scripts/api/admin/nodes/getNodes.ts @@ -11,6 +11,10 @@ export interface Node { description: string | null; locationId: number; fqdn: string; + listenPortHTTP: number; + publicPortHTTP: number; + listenPortSFTP: number; + publicPortSFTP: number; scheme: string; behindProxy: boolean; maintenanceMode: boolean; @@ -19,8 +23,6 @@ export interface Node { disk: number; diskOverallocate: number; uploadSize: number; - daemonListen: number; - daemonSftp: number; daemonBase: string; createdAt: Date; updatedAt: Date; @@ -38,6 +40,10 @@ export const rawDataToNode = ({ attributes }: FractalResponseData): Node => ({ description: attributes.description, locationId: attributes.location_id, fqdn: attributes.fqdn, + listenPortHTTP: attributes.listen_port_http, + publicPortHTTP: attributes.public_port_http, + listenPortSFTP: attributes.listen_port_sftp, + publicPortSFTP: attributes.public_port_sftp, scheme: attributes.scheme, behindProxy: attributes.behind_proxy, maintenanceMode: attributes.maintenance_mode, @@ -46,8 +52,6 @@ export const rawDataToNode = ({ attributes }: FractalResponseData): Node => ({ disk: attributes.disk, diskOverallocate: attributes.disk_overallocate, uploadSize: attributes.upload_size, - daemonListen: attributes.daemon_listen, - daemonSftp: attributes.daemon_sftp, daemonBase: attributes.daemon_base, createdAt: new Date(attributes.created_at), updatedAt: new Date(attributes.updated_at), diff --git a/resources/scripts/api/admin/nodes/updateNode.ts b/resources/scripts/api/admin/nodes/updateNode.ts index f8bf28e6a..b87a8802a 100644 --- a/resources/scripts/api/admin/nodes/updateNode.ts +++ b/resources/scripts/api/admin/nodes/updateNode.ts @@ -1,10 +1,10 @@ import http from '@/api/http'; import { Node, rawDataToNode } from '@/api/admin/nodes/getNodes'; -export default (id: number, name: string, description: string | null, include: string[] = []): Promise => { +export default (id: number, node: Partial, include: string[] = []): Promise => { return new Promise((resolve, reject) => { http.patch(`/api/application/nodes/${id}`, { - name, description, + ...node, }, { params: { include: include.join(',') } }) .then(({ data }) => resolve(rawDataToNode(data))) .catch(reject); diff --git a/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx b/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx index 8cdfaf04b..c20a2a1a8 100644 --- a/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx +++ b/resources/scripts/components/admin/databases/DatabaseEditContainer.tsx @@ -134,6 +134,7 @@ const EditInformationContainer = () => { name={'password'} label={'Password'} type={'password'} + placeholder={'••••••••'} /> diff --git a/resources/scripts/components/admin/nodes/NodeEditContainer.tsx b/resources/scripts/components/admin/nodes/NodeEditContainer.tsx index 8c2c5bd26..581b25820 100644 --- a/resources/scripts/components/admin/nodes/NodeEditContainer.tsx +++ b/resources/scripts/components/admin/nodes/NodeEditContainer.tsx @@ -1,5 +1,3 @@ -import AdminBox from '@/components/admin/AdminBox'; -import NodeSettingsContainer from '@/components/admin/nodes/NodeSettingsContainer'; import React, { useEffect, useState } from 'react'; import { useLocation } from 'react-router'; import tw from 'twin.macro'; @@ -12,6 +10,9 @@ import Spinner from '@/components/elements/Spinner'; import FlashMessageRender from '@/components/FlashMessageRender'; import { ApplicationStore } from '@/state'; import { SubNavigation, SubNavigationLink } from '@/components/admin/SubNavigation'; +import AdminBox from '@/components/admin/AdminBox'; +import NodeLimitContainer from '@/components/admin/nodes/NodeLimitContainer'; +import NodeSettingsContainer from '@/components/admin/nodes/NodeSettingsContainer'; interface ctx { node: Node | undefined; @@ -119,10 +120,14 @@ const NodeEditContainer = () => { -
-
+
+
+ +
+ +
diff --git a/resources/scripts/components/admin/nodes/NodeLimitContainer.tsx b/resources/scripts/components/admin/nodes/NodeLimitContainer.tsx new file mode 100644 index 000000000..06c18cff6 --- /dev/null +++ b/resources/scripts/components/admin/nodes/NodeLimitContainer.tsx @@ -0,0 +1,122 @@ +import React from 'react'; +import AdminBox from '@/components/admin/AdminBox'; +import tw from 'twin.macro'; +import { number, object } from 'yup'; +import Button from '@/components/elements/Button'; +import Field from '@/components/elements/Field'; +import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; +import { Form, Formik, FormikHelpers } from 'formik'; +import { Context } from '@/components/admin/nodes/NodeEditContainer'; +import { ApplicationStore } from '@/state'; +import { Actions, useStoreActions } from 'easy-peasy'; +import updateNode from '@/api/admin/nodes/updateNode'; + +interface Values { + memory: number; + memoryOverallocate: number; + disk: number; + diskOverallocate: number; +} + +export default () => { + const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes); + + const node = Context.useStoreState(state => state.node); + const setNode = Context.useStoreActions(actions => actions.setNode); + + if (node === undefined) { + return ( + <> + ); + } + + const submit = ({ memory, memoryOverallocate, disk, diskOverallocate }: Values, { setSubmitting }: FormikHelpers) => { + clearFlashes('node'); + + updateNode(node.id, { memory, memoryOverallocate, disk, diskOverallocate }) + .then(() => setNode({ ...node, memory, memoryOverallocate, disk, diskOverallocate })) + .catch(error => { + console.error(error); + clearAndAddHttpError({ key: 'node', error }); + }) + .then(() => setSubmitting(false)); + }; + + return ( + + { + ({ isSubmitting, isValid }) => ( + + + + +
+
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+ ) + } +
+ ); +}; diff --git a/resources/scripts/components/admin/nodes/NodeSettingsContainer.tsx b/resources/scripts/components/admin/nodes/NodeSettingsContainer.tsx index 5c4c35d23..062fbdd83 100644 --- a/resources/scripts/components/admin/nodes/NodeSettingsContainer.tsx +++ b/resources/scripts/components/admin/nodes/NodeSettingsContainer.tsx @@ -1,4 +1,3 @@ -import LocationSelect from '@/components/admin/nodes/LocationSelect'; import React from 'react'; import AdminBox from '@/components/admin/AdminBox'; import tw from 'twin.macro'; @@ -11,6 +10,7 @@ import { Form, Formik, FormikHelpers } from 'formik'; import { Context } from '@/components/admin/nodes/NodeEditContainer'; import { ApplicationStore } from '@/state'; import { Actions, useStoreActions } from 'easy-peasy'; +import LocationSelect from '@/components/admin/nodes/LocationSelect'; interface Values { public: boolean; @@ -18,8 +18,8 @@ interface Values { description: string; locationId: number; fqdn: string; - listenPort: number; - publicPort: number; + listenPortHTTP: number; + publicPortHTTP: number; listenPortSFTP: number; publicPortSFTP: number; } @@ -36,11 +36,11 @@ export default () => { ); } - const submit = ({ name, description }: Values, { setSubmitting }: FormikHelpers) => { - clearFlashes('database'); + const submit = ({ name, description, locationId, fqdn, listenPortHTTP, publicPortHTTP, listenPortSFTP, publicPortSFTP }: Values, { setSubmitting }: FormikHelpers) => { + clearFlashes('node'); - updateNode(node.id, name, description) - .then(() => setNode({ ...node, name, description })) + updateNode(node.id, { name, description, locationId, fqdn, listenPortHTTP, publicPortHTTP, listenPortSFTP, publicPortSFTP }) + .then(() => setNode({ ...node, name, description, locationId, fqdn, listenPortHTTP, publicPortHTTP, listenPortSFTP, publicPortSFTP })) .catch(error => { console.error(error); clearAndAddHttpError({ key: 'node', error }); @@ -57,10 +57,10 @@ export default () => { description: node.description || '', locationId: node.locationId, fqdn: node.fqdn, - listenPort: node.daemonListen, - publicPort: node.daemonListen, - listenPortSFTP: node.daemonSftp, - publicPortSFTP: node.daemonSftp, + listenPortHTTP: node.listenPortHTTP, + publicPortHTTP: node.publicPortHTTP, + listenPortSFTP: node.listenPortSFTP, + publicPortSFTP: node.publicPortSFTP, }} validationSchema={object().shape({ name: string().required().max(191), @@ -108,18 +108,18 @@ export default () => {
diff --git a/resources/scripts/components/admin/servers/ServersContainer.tsx b/resources/scripts/components/admin/servers/ServersContainer.tsx index d87a33bf8..3b94d67f8 100644 --- a/resources/scripts/components/admin/servers/ServersContainer.tsx +++ b/resources/scripts/components/admin/servers/ServersContainer.tsx @@ -142,7 +142,7 @@ const UsersContainer = () => {
- {server.relations.node?.fqdn}:{server.relations.node?.daemonListen} + {server.relations.node?.fqdn}