diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 735f182f..8ee87203 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -17,7 +17,7 @@ jobs:
fail-fast: true
matrix:
php: [ 8.4 ]
- node-version: [ "20.x" ]
+ node-version: [ "22.x" ]
steps:
- uses: actions/checkout@v4
@@ -46,10 +46,13 @@ jobs:
- name: Set up the .env file
run: touch .env
+ - name: Generate Application Key
+ run: php artisan key:generate
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
- node-version: "20.x"
+ node-version: "22.x"
- name: Install NPM Dependencies
run: npm install --force
diff --git a/app/Actions/Site/UpdateLoadBalancer.php b/app/Actions/Site/UpdateLoadBalancer.php
index a628e9d8..f3b58197 100644
--- a/app/Actions/Site/UpdateLoadBalancer.php
+++ b/app/Actions/Site/UpdateLoadBalancer.php
@@ -22,7 +22,7 @@ public function update(Site $site, array $input): void
foreach ($input['servers'] as $server) {
$loadBalancerServer = new LoadBalancerServer([
'load_balancer_id' => $site->id,
- 'ip' => $server['server'],
+ 'ip' => $server['ip'],
'port' => $server['port'],
'weight' => $server['weight'],
'backup' => (bool) $server['backup'],
@@ -43,7 +43,7 @@ public static function rules(Site $site): array
'required',
'array',
],
- 'servers.*.server' => [
+ 'servers.*.ip' => [
'required',
Rule::exists('servers', 'local_ip')
->where('project_id', $site->project->id),
diff --git a/resources/js/pages/application/components/load-balancer.tsx b/resources/js/pages/application/components/load-balancer.tsx
index d0d5a375..83e80aee 100644
--- a/resources/js/pages/application/components/load-balancer.tsx
+++ b/resources/js/pages/application/components/load-balancer.tsx
@@ -6,8 +6,8 @@ import Container from '@/components/container';
import HeaderContainer from '@/components/header-container';
import Heading from '@/components/heading';
import { Button } from '@/components/ui/button';
-import { BookOpenIcon, LoaderCircleIcon } from 'lucide-react';
-import { FormEvent } from 'react';
+import { BookOpenIcon, LoaderCircleIcon, XIcon } from 'lucide-react';
+import React, { FormEvent } from 'react';
import { LoadBalancerServer } from '@/types/load-balancer-server';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { Form, FormField, FormFields } from '@/components/ui/form';
@@ -15,6 +15,9 @@ import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import InputError from '@/components/ui/input-error';
import FormSuccessful from '@/components/form-successful';
+import ServerSelect from '@/pages/servers/components/server-select';
+import { Input } from '@/components/ui/input';
+import { Switch } from '@/components/ui/switch';
export default function LoadBalancer() {
const page = usePage<{
@@ -26,26 +29,42 @@ export default function LoadBalancer() {
const form = useForm<{
method: 'round-robin' | 'least-connections' | 'ip-hash';
servers: {
- server: string;
- port: string;
+ load_balancer_id: number;
+ ip: string;
+ port: number;
weight: string;
backup: boolean;
}[];
}>({
method: 'round-robin',
- servers: [],
+ servers: page.props.loadBalancerServers,
});
+ const addServer = () => {
+ const newServer: LoadBalancerServer = {
+ load_balancer_id: 0,
+ ip: '',
+ port: 80,
+ weight: '100',
+ backup: false,
+ created_at: '',
+ updated_at: '',
+ };
+
+ form.setData('servers', [...form.data.servers, newServer]);
+ };
+
const submit = (e: FormEvent) => {
e.preventDefault();
form.post(route('application.update-load-balancer', { server: page.props.server.id, site: page.props.site.id }), {
- onSuccess: () => {
- form.reset();
- },
preserveScroll: true,
});
};
+ const getFieldError = (field: string): string | undefined => {
+ return form.errors[field as keyof typeof form.errors];
+ };
+
return (