Basic seeder, navigating to application page
This commit is contained in:
15
app/Http/Controllers/ApplicationController.php
Normal file
15
app/Http/Controllers/ApplicationController.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ApplicationController extends Controller
|
||||||
|
{
|
||||||
|
public function show(Request $request)
|
||||||
|
{
|
||||||
|
return inertia('Applications/Show', [
|
||||||
|
// 'application' => $request->route('application'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
app/Http/Controllers/OrganisationController.php
Normal file
10
app/Http/Controllers/OrganisationController.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class OrganisationController extends Controller
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
@@ -2,27 +2,16 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
use Illuminate\Foundation\Inspiring;
|
use App\Models\Application;
|
||||||
|
use App\Models\Organisation;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Inertia\Middleware;
|
use Inertia\Middleware;
|
||||||
use Tighten\Ziggy\Ziggy;
|
use Tighten\Ziggy\Ziggy;
|
||||||
|
|
||||||
class HandleInertiaRequests extends Middleware
|
class HandleInertiaRequests extends Middleware
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The root template that's loaded on the first page visit.
|
|
||||||
*
|
|
||||||
* @see https://inertiajs.com/server-side-setup#root-template
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $rootView = 'app';
|
protected $rootView = 'app';
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the current asset version.
|
|
||||||
*
|
|
||||||
* @see https://inertiajs.com/asset-versioning
|
|
||||||
*/
|
|
||||||
public function version(Request $request): ?string
|
public function version(Request $request): ?string
|
||||||
{
|
{
|
||||||
return parent::version($request);
|
return parent::version($request);
|
||||||
@@ -37,14 +26,13 @@ class HandleInertiaRequests extends Middleware
|
|||||||
*/
|
*/
|
||||||
public function share(Request $request): array
|
public function share(Request $request): array
|
||||||
{
|
{
|
||||||
[$message, $author] = str(Inspiring::quotes()->random())->explode('-');
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...parent::share($request),
|
...parent::share($request),
|
||||||
'name' => config('app.name'),
|
'name' => config('app.name'),
|
||||||
'quote' => ['message' => trim($message), 'author' => trim($author)],
|
'organisation' => $request->route('organisation') ? Organisation::with('applications')->findOrFail($request->route('organisation')) : null,
|
||||||
|
'application' => $request->route('application') ? Application::findOrFail($request->route('application')) : null,
|
||||||
'auth' => [
|
'auth' => [
|
||||||
'user' => $request->user(),
|
'user' => $request->user()->load('organisations'),
|
||||||
],
|
],
|
||||||
'ziggy' => [
|
'ziggy' => [
|
||||||
...(new Ziggy)->toArray(),
|
...(new Ziggy)->toArray(),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ return new class extends Migration
|
|||||||
{
|
{
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('application', function (Blueprint $table) {
|
Schema::create('applications', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignIdFor(Organisation::class);
|
$table->foreignIdFor(Organisation::class);
|
||||||
$table->string('name');
|
$table->string('name');
|
||||||
@@ -21,6 +21,6 @@ return new class extends Migration
|
|||||||
|
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('application');
|
Schema::dropIfExists('applications');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Enums\OrganisationRole;
|
||||||
|
use App\Enums\RepositoryType;
|
||||||
|
use App\Models\Organisation;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
@@ -15,9 +18,30 @@ class DatabaseSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
// User::factory(10)->create();
|
// User::factory(10)->create();
|
||||||
|
|
||||||
User::factory()->create([
|
$user = User::factory()->create([
|
||||||
'name' => 'Harry',
|
'name' => 'Harry',
|
||||||
'email' => 'harry@hjb.dev',
|
'email' => 'harry@hjb.dev',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$organisation = Organisation::create([
|
||||||
|
'name' => 'Stratbucket',
|
||||||
|
'slug' => 'stratbucket',
|
||||||
|
'owner_id' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$organisation->members()->attach($user, ['role' => OrganisationRole::Admin]);
|
||||||
|
|
||||||
|
$application = $organisation->applications()->create([
|
||||||
|
'name' => 'ClipBin',
|
||||||
|
'repository_url' => 'git@github.com:hjbdev/clipbin.git',
|
||||||
|
'repository_type' => RepositoryType::Git,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$application->environments()->create([
|
||||||
|
'name' => 'Dev',
|
||||||
|
'branch' => 'main',
|
||||||
|
'url' => 'https://dev.clipbin.hjb.dev',
|
||||||
|
'status' => 'active'
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,66 @@
|
|||||||
import Breadcrumbs from '@/components/Breadcrumbs.vue';
|
import Breadcrumbs from '@/components/Breadcrumbs.vue';
|
||||||
import { SidebarTrigger } from '@/components/ui/sidebar';
|
import { SidebarTrigger } from '@/components/ui/sidebar';
|
||||||
import type { BreadcrumbItemType } from '@/types';
|
import type { BreadcrumbItemType } from '@/types';
|
||||||
|
import { Link, usePage } from '@inertiajs/vue3';
|
||||||
|
import { ChevronsUpDown } from 'lucide-vue-next';
|
||||||
|
import { Button } from './ui/button';
|
||||||
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './ui/dropdown-menu';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
breadcrumbs?: BreadcrumbItemType[];
|
breadcrumbs?: BreadcrumbItemType[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const organisation = usePage().props.organisation ?? { name: 'Select Organisation' };
|
||||||
|
const application = usePage().props.application ?? { name: 'Select Application' };
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header
|
<header
|
||||||
class="flex h-16 shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-6 transition-[width,height] ease-in-out group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12 md:px-4"
|
class="flex h-16 shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-6 transition-[width,height] ease-in-out group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12 md:px-4"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-4">
|
||||||
<SidebarTrigger class="-ml-1" />
|
<SidebarTrigger class="-ml-1" />
|
||||||
|
<div class="gap-0.25 flex items-center">
|
||||||
|
<Button :as="Link" :href="route('organisations.show', { organisation: organisation?.id })" variant="ghost" size="xs">
|
||||||
|
{{ organisation?.name }}
|
||||||
|
</Button>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger :as="Button" size="iconxs" variant="ghost">
|
||||||
|
<ChevronsUpDown class="size-3" />
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent>
|
||||||
|
<DropdownMenuItem
|
||||||
|
v-for="org in $page.props.auth.user?.organisations"
|
||||||
|
:as="Link"
|
||||||
|
:href="route('organisations.show', { organisation: org.id })"
|
||||||
|
>{{ org.name }}</DropdownMenuItem
|
||||||
|
>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
<div class="gap-0.25 flex items-center">
|
||||||
|
<Button
|
||||||
|
:as="Link"
|
||||||
|
:href="route('applications.show', { organisation: application.organisation_id, application: application.id })"
|
||||||
|
variant="ghost"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
{{ application?.name }}
|
||||||
|
</Button>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger :as="Button" size="iconxs" variant="ghost">
|
||||||
|
<ChevronsUpDown class="size-3" />
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent>
|
||||||
|
<DropdownMenuItem
|
||||||
|
v-for="app in organisation?.applications"
|
||||||
|
:as="Link"
|
||||||
|
:href="route('applications.show', { organisation: app.organisation_id, application: app.id })"
|
||||||
|
>{{ app.name }}</DropdownMenuItem
|
||||||
|
>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
<template v-if="breadcrumbs.length > 0">
|
<template v-if="breadcrumbs.length > 0">
|
||||||
<Breadcrumbs :breadcrumbs="breadcrumbs" />
|
<Breadcrumbs :breadcrumbs="breadcrumbs" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ export const buttonVariants = cva(
|
|||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: 'h-9 px-4 py-2',
|
default: 'h-9 px-4 py-2',
|
||||||
|
xs: 'h-7 px-2 text-xs',
|
||||||
sm: 'h-8 rounded-md px-3 text-xs',
|
sm: 'h-8 rounded-md px-3 text-xs',
|
||||||
lg: 'h-10 rounded-md px-8',
|
lg: 'h-10 rounded-md px-8',
|
||||||
icon: 'h-9 w-9',
|
icon: 'h-9 w-9',
|
||||||
|
'iconxs': 'h-7 px-0.5',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
|
|||||||
23
resources/js/pages/Applications/Show.vue
Normal file
23
resources/js/pages/Applications/Show.vue
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import AppLayout from '@/layouts/AppLayout.vue';
|
||||||
|
import { type BreadcrumbItem } from '@/types';
|
||||||
|
import { Head } from '@inertiajs/vue3';
|
||||||
|
import PlaceholderPattern from '../components/PlaceholderPattern.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
application: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Head title="Dashboard" />
|
||||||
|
|
||||||
|
<AppLayout>
|
||||||
|
<div class="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
|
||||||
|
{{ application }}
|
||||||
|
</div>
|
||||||
|
</AppLayout>
|
||||||
|
</template>
|
||||||
@@ -22,7 +22,7 @@ const breadcrumbs: BreadcrumbItem[] = [
|
|||||||
<div>Applications have environments</div>
|
<div>Applications have environments</div>
|
||||||
<div>Servers have services</div>
|
<div>Servers have services</div>
|
||||||
<div>Services have slices, this could be a database table or a client in a websocket server</div>
|
<div>Services have slices, this could be a database table or a client in a websocket server</div>
|
||||||
<div>Environments have SLICES</div>
|
<div>Environments have SLICES</div>
|
||||||
<div>Also servers need to be provisioned</div>
|
<div>Also servers need to be provisioned</div>
|
||||||
<div>Users have SSH keys</div>
|
<div>Users have SSH keys</div>
|
||||||
<div>Keystone has its own SSH keys</div>
|
<div>Keystone has its own SSH keys</div>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\ApplicationController;
|
||||||
|
use App\Http\Controllers\OrganisationController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
|
|
||||||
@@ -7,9 +9,16 @@ Route::get('/', function () {
|
|||||||
return Inertia::render('Welcome');
|
return Inertia::render('Welcome');
|
||||||
})->name('home');
|
})->name('home');
|
||||||
|
|
||||||
Route::get('dashboard', function () {
|
Route::middleware(['auth', 'verified'])->group(function () {
|
||||||
return Inertia::render('Dashboard');
|
Route::inertia('dashboard', 'Dashboard')->name('dashboard');
|
||||||
})->middleware(['auth', 'verified'])->name('dashboard');
|
|
||||||
|
|
||||||
require __DIR__.'/settings.php';
|
Route::prefix('organisations/{organisation}')->group(function () {
|
||||||
require __DIR__.'/auth.php';
|
Route::get('/', [OrganisationController::class, 'show'])->name('organisations.show');
|
||||||
|
Route::resource('applications', ApplicationController::class)
|
||||||
|
->only('show')
|
||||||
|
->name('show', 'applications.show');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
require __DIR__ . '/settings.php';
|
||||||
|
require __DIR__ . '/auth.php';
|
||||||
|
|||||||
Reference in New Issue
Block a user