frontend js enums generation, started service/create
This commit is contained in:
90
app/Console/Commands/GenerateJSEnums.php
Normal file
90
app/Console/Commands/GenerateJSEnums.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Symfony\Component\Finder\Finder;
|
||||||
|
|
||||||
|
class GenerateJSEnums extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'enums:generate';
|
||||||
|
|
||||||
|
protected $description = 'Converts enums to js objects for the frontend.';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$enums = base_path('app/enums');
|
||||||
|
|
||||||
|
$this->load($enums);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function load($paths)
|
||||||
|
{
|
||||||
|
$paths = array_unique(Arr::wrap($paths));
|
||||||
|
|
||||||
|
$paths = array_filter($paths, function ($path) {
|
||||||
|
return is_dir($path);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (empty($paths)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ((new Finder)->in($paths)->files() as $enum) {
|
||||||
|
$enum = 'App\\' . str_replace(
|
||||||
|
['/', '.php'],
|
||||||
|
['\\', ''],
|
||||||
|
Str::after($enum->getRealPath(), realpath(app_path()) . DIRECTORY_SEPARATOR)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! class_exists($enum)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$js = "// This is a generated file. \n";
|
||||||
|
$js .= '// Published at ' . now()->format('Y-m-d H:i:s') . "\n";
|
||||||
|
$js .= "\n";
|
||||||
|
$js .= 'export default ';
|
||||||
|
$js .= json_encode($enum::toArray(), JSON_PRETTY_PRINT) . "\n";
|
||||||
|
$js .= "\n";
|
||||||
|
|
||||||
|
if (method_exists($enum, 'getLabels')) {
|
||||||
|
$labels = $enum::getLabels();
|
||||||
|
$js .= 'export const LabelMap = ';
|
||||||
|
$js .= json_encode($labels, JSON_PRETTY_PRINT) . "\n";
|
||||||
|
$js .= "\n";
|
||||||
|
|
||||||
|
$labelSelect = array_map(fn($key) => ['title' => $labels[$key], 'id' => $key], array_keys($labels));
|
||||||
|
$js .= 'export const LabelSelectMap = ';
|
||||||
|
$js .= json_encode($labelSelect, JSON_PRETTY_PRINT) . "\n";
|
||||||
|
$js .= "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method_exists($enum, 'colours')) {
|
||||||
|
$colours = $enum::colours();
|
||||||
|
$js .= 'export const ColourMap = ';
|
||||||
|
$js .= json_encode($colours, JSON_PRETTY_PRINT) . "\n";
|
||||||
|
$js .= "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = explode('\\', $enum)[count(explode('\\', $enum)) - 1];
|
||||||
|
|
||||||
|
// Skip format, JS date formats are different to PHP ones.
|
||||||
|
if ($name !== 'Format') {
|
||||||
|
file_put_contents(base_path('resources/js/Enums/' . $name . '.js'), $js);
|
||||||
|
$this->info('Stored ' . $enum);
|
||||||
|
} else {
|
||||||
|
$this->info('Skipped ' . $name . 's');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
app/Http/Controllers/ServiceController.php
Normal file
16
app/Http/Controllers/ServiceController.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ServiceController extends Controller
|
||||||
|
{
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$server = $request->route('server');
|
||||||
|
return inertia('services/Create', [
|
||||||
|
'server' => $server,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
resources/js/enums/DeploymentStatus.js
Normal file
11
resources/js/enums/DeploymentStatus.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"PENDING": "pending",
|
||||||
|
"IN_PROGRESS": "in-progress",
|
||||||
|
"COMPLETED": "completed",
|
||||||
|
"CANCELLED": "canceled",
|
||||||
|
"FAILED": "failed"
|
||||||
|
}
|
||||||
|
|
||||||
9
resources/js/enums/FirewallRuleStatus.js
Normal file
9
resources/js/enums/FirewallRuleStatus.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"NOT_APPLIED": "not-applied",
|
||||||
|
"APPLIED": "applied",
|
||||||
|
"FAILED": "failed"
|
||||||
|
}
|
||||||
|
|
||||||
8
resources/js/enums/OrganisationRole.js
Normal file
8
resources/js/enums/OrganisationRole.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"ADMIN": "admin",
|
||||||
|
"MEMBER": "member"
|
||||||
|
}
|
||||||
|
|
||||||
7
resources/js/enums/RepositoryType.js
Normal file
7
resources/js/enums/RepositoryType.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"GIT": "git"
|
||||||
|
}
|
||||||
|
|
||||||
8
resources/js/enums/ServerProvider.js
Normal file
8
resources/js/enums/ServerProvider.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"HETZNER": "hetzner",
|
||||||
|
"DIGITAL_OCEAN": "digital-ocean"
|
||||||
|
}
|
||||||
|
|
||||||
15
resources/js/enums/ServerStatus.js
Normal file
15
resources/js/enums/ServerStatus.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"WAITING_FOR_PROVIDER": "waiting-for-provider",
|
||||||
|
"PROVIDER_TIMEOUT": "provider-timeout",
|
||||||
|
"UNPROVISIONED": "unprovisioned",
|
||||||
|
"PROVISIONING": "provisioning",
|
||||||
|
"PROVISIONING_FAILED": "provisioning-failed",
|
||||||
|
"UPDATING": "updating",
|
||||||
|
"ACTIVE": "active",
|
||||||
|
"DELETING": "deleting",
|
||||||
|
"DELETED": "deleted"
|
||||||
|
}
|
||||||
|
|
||||||
11
resources/js/enums/ServiceCategory.js
Normal file
11
resources/js/enums/ServiceCategory.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"DATABASE": "database",
|
||||||
|
"APPLICATION": "application",
|
||||||
|
"GATEWAY": "gateway",
|
||||||
|
"STORAGE": "storage",
|
||||||
|
"CACHE": "cache"
|
||||||
|
}
|
||||||
|
|
||||||
12
resources/js/enums/ServiceStatus.js
Normal file
12
resources/js/enums/ServiceStatus.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"NOT_INSTALLED": "not-installed",
|
||||||
|
"INSTALLING": "installing",
|
||||||
|
"RUNNING": "running",
|
||||||
|
"STOPPED": "stopped",
|
||||||
|
"ERROR": "error",
|
||||||
|
"UNKNOWN": "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
14
resources/js/enums/ServiceType.js
Normal file
14
resources/js/enums/ServiceType.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// This is a generated file.
|
||||||
|
// Published at 2025-04-01 16:18:32
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"FRANKENPHP": "frankenphp",
|
||||||
|
"PHP_FPM": "php-fpm",
|
||||||
|
"POSTGRES": "postgres",
|
||||||
|
"CADDY": "caddy",
|
||||||
|
"VALKEY": "valkey",
|
||||||
|
"MYSQL": "mysql",
|
||||||
|
"NGINX": "nginx",
|
||||||
|
"REDIS": "redis"
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
import AppLayout from '@/layouts/AppLayout.vue';
|
import AppLayout from '@/layouts/AppLayout.vue';
|
||||||
import { Head } from '@inertiajs/vue3';
|
import { Head, Link } from '@inertiajs/vue3';
|
||||||
import { useCycleList, useInterval } from '@vueuse/core';
|
import { useCycleList, useInterval } from '@vueuse/core';
|
||||||
import { DatabaseIcon, Layers2Icon, LoaderCircleIcon } from 'lucide-vue-next';
|
import { DatabaseIcon, Layers2Icon, LoaderCircleIcon, PlusIcon } from 'lucide-vue-next';
|
||||||
import { watch } from 'vue';
|
import { watch } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -60,7 +61,18 @@ watch(counter, () => {
|
|||||||
|
|
||||||
<template v-if="server.status === 'active'">
|
<template v-if="server.status === 'active'">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="mb-3 text-2xl font-semibold tracking-tight">Services</h3>
|
<div class="mb-3 flex items-center justify-between">
|
||||||
|
<h3 class="text-2xl font-semibold tracking-tight">Services</h3>
|
||||||
|
<div>
|
||||||
|
<Button :as="Link" :href="route('services.create', {
|
||||||
|
organisation: $page.props.organisation.id,
|
||||||
|
server: server.id,
|
||||||
|
})" size="xs">
|
||||||
|
<PlusIcon class="size-4" />
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
||||||
<Card v-for="service in server.services" :key="service.id">
|
<Card v-for="service in server.services" :key="service.id">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
|
|||||||
50
resources/js/pages/services/Create.vue
Normal file
50
resources/js/pages/services/Create.vue
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<script setup>
|
||||||
|
import RadioButton from '@/components/RadioButton.vue';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import AppLayout from '@/layouts/AppLayout.vue';
|
||||||
|
import { Head, router, useForm } from '@inertiajs/vue3';
|
||||||
|
import { watch } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = useForm({
|
||||||
|
name: null,
|
||||||
|
category: null,
|
||||||
|
type: null,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Head title="Add Service to Server" />
|
||||||
|
|
||||||
|
<AppLayout
|
||||||
|
:breadcrumbs="[
|
||||||
|
{
|
||||||
|
title: 'Servers',
|
||||||
|
href: route('servers.index', {
|
||||||
|
organisation: $page.props.organisation.id,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Services',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Create',
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-end">
|
||||||
|
<Button @click="form.post(route('servers.store', { organisation: $page.props.organisation.id }))">Submit</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AppLayout>
|
||||||
|
</template>
|
||||||
@@ -5,6 +5,7 @@ use App\Http\Controllers\ApplicationController;
|
|||||||
use App\Http\Controllers\EnvironmentController;
|
use App\Http\Controllers\EnvironmentController;
|
||||||
use App\Http\Controllers\OrganisationController;
|
use App\Http\Controllers\OrganisationController;
|
||||||
use App\Http\Controllers\ServerController;
|
use App\Http\Controllers\ServerController;
|
||||||
|
use App\Http\Controllers\ServiceController;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Support\Ip;
|
use App\Support\Ip;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -27,6 +28,13 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
|||||||
->name('show', 'servers.show')
|
->name('show', 'servers.show')
|
||||||
->name('create', 'servers.create')
|
->name('create', 'servers.create')
|
||||||
->name('store', 'servers.store');
|
->name('store', 'servers.store');
|
||||||
|
|
||||||
|
Route::prefix('servers/{server}')->group(function () {
|
||||||
|
Route::resource('services', ServiceController::class)
|
||||||
|
->only('create', 'store')
|
||||||
|
->name('create', 'services.create')
|
||||||
|
->name('store', 'services.store');
|
||||||
|
});
|
||||||
|
|
||||||
Route::resource('applications', ApplicationController::class)
|
Route::resource('applications', ApplicationController::class)
|
||||||
->only('show')
|
->only('show')
|
||||||
|
|||||||
Reference in New Issue
Block a user