#591 - sites [wip]

This commit is contained in:
Saeed Vaziry
2025-05-25 22:17:19 +02:00
parent ff11fb44e0
commit f5fdbae4ac
77 changed files with 2156 additions and 414 deletions

View File

@ -68,8 +68,6 @@ public function create(Request $request, Project $project, Server $server): Site
$this->validateRoute($project, $server);
$this->validate($request, CreateSite::rules($server, $request->input()));
$site = app(CreateSite::class)->create($server, $request->all());
return new SiteResource($site);

View File

@ -4,12 +4,14 @@
use App\Actions\Database\RestoreBackup;
use App\Http\Resources\BackupFileResource;
use App\Http\Resources\BackupResource;
use App\Models\Backup;
use App\Models\BackupFile;
use App\Models\Server;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Inertia\Inertia;
use Inertia\Response;
use Spatie\RouteAttributes\Attributes\Delete;
use Spatie\RouteAttributes\Attributes\Get;
use Spatie\RouteAttributes\Attributes\Middleware;
@ -21,11 +23,16 @@
class BackupFileController extends Controller
{
#[Get('/', name: 'backup-files')]
public function index(Server $server, Backup $backup): ResourceCollection
public function index(Server $server, Backup $backup): Response
{
$this->authorize('viewAny', [BackupFile::class, $backup]);
return BackupFileResource::collection($backup->files()->latest()->simplePaginate(config('web.pagination_size')));
return Inertia::render('backups/files', [
'backup' => BackupResource::make($backup),
'files' => BackupFileResource::collection(
$backup->files()->with('backup')->latest()->simplePaginate(config('web.pagination_size'))
),
]);
}
#[Post('/{backupFile}/restore', name: 'backup-files.restore')]

View File

@ -10,6 +10,7 @@
use App\Models\ServerProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Facades\URL;
use Illuminate\Validation\Rule;
use Inertia\Inertia;
@ -40,6 +41,27 @@ public function index(): Response
]);
}
#[Get('/json', name: 'servers.json')]
public function json(Request $request): ResourceCollection
{
$project = user()->currentProject;
$this->authorize('viewAny', [Server::class, $project]);
$this->validate($request, [
'query' => [
'nullable',
'string',
],
]);
$servers = $project->servers()->where('name', 'like', "%{$request->input('query')}%")
->take(10)
->get();
return ServerResource::collection($servers);
}
#[Post('/', name: 'servers.store')]
public function store(Request $request): RedirectResponse
{
@ -58,7 +80,7 @@ public function show(Server $server): Response
$this->authorize('view', $server);
return Inertia::render('servers/show', [
'logs' => ServerLogResource::collection($server->logs()->latest()->simplePaginate(config('web.pagination_size'))),
'logs' => ServerLogResource::collection($server->logs()->latest()->simplePaginate(config('web.pagination_size'), pageName: 'logsPage')),
]);
}

View File

@ -2,8 +2,11 @@
namespace App\Http\Controllers;
use App\Http\Resources\ServerLogResource;
use App\Models\Server;
use App\Models\ServerLog;
use App\Models\Site;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Spatie\RouteAttributes\Attributes\Get;
use Spatie\RouteAttributes\Attributes\Middleware;
use Spatie\RouteAttributes\Attributes\Prefix;
@ -12,6 +15,19 @@
#[Middleware(['auth', 'has-project'])]
class ServerLogController extends Controller
{
#[Get('/json/{site?}', name: 'logs.json')]
public function json(Server $server, ?Site $site = null): ResourceCollection
{
$this->authorize('viewAny', [ServerLog::class, $server]);
$logs = $server->logs()
->when($site, fn ($query) => $query->where('site_id', $site->id))
->latest()
->simplePaginate(config('web.pagination_size'));
return ServerLogResource::collection($logs);
}
#[Get('/{log}', name: 'logs.show')]
public function show(Server $server, ServerLog $log): string
{

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers;
use App\Models\Server;
use App\Models\Service;
use Illuminate\Http\JsonResponse;
use Spatie\RouteAttributes\Attributes\Get;
use Spatie\RouteAttributes\Attributes\Middleware;
use Spatie\RouteAttributes\Attributes\Prefix;
#[Prefix('servers/{server}/services')]
#[Middleware(['auth', 'has-project'])]
class ServiceController extends Controller
{
#[Get('{service}/versions', name: 'services.versions')]
public function versions(Server $server, string $service): JsonResponse
{
$this->authorize('viewAny', [Service::class, $server]);
$versions = [];
$services = $server->services()->where('type', $service)->get(['version']);
/** @var Service $service */
foreach ($services as $service) {
$versions[] = $service->version;
}
return response()->json($versions);
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace App\Http\Controllers;
use App\Actions\Site\CreateSite;
use App\Actions\Site\DeleteSite;
use App\Exceptions\SSHError;
use App\Http\Resources\ServerLogResource;
use App\Http\Resources\SiteResource;
use App\Models\Server;
use App\Models\Site;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Inertia\Inertia;
use Inertia\Response;
use Spatie\RouteAttributes\Attributes\Delete;
use Spatie\RouteAttributes\Attributes\Get;
use Spatie\RouteAttributes\Attributes\Middleware;
use Spatie\RouteAttributes\Attributes\Post;
use Throwable;
#[Middleware(['auth', 'has-project'])]
class SiteController extends Controller
{
#[Get('/sites', name: 'sites.all')]
public function index(): Response
{
$sites = user()->currentProject->sites()->with('server')->latest()->simplePaginate(config('web.pagination_size'));
return Inertia::render('sites/index', [
'sites' => SiteResource::collection($sites),
]);
}
#[Get('/servers/{server}/sites', name: 'sites')]
public function server(Server $server): Response
{
$this->authorize('viewAny', [Site::class, $server]);
return Inertia::render('sites/index', [
'sites' => SiteResource::collection($server->sites()->latest()->simplePaginate(config('web.pagination_size'))),
]);
}
#[Get('/servers/{server}/sites/{site}', name: 'sites.show')]
public function show(Server $server, Site $site): Response
{
$this->authorize('view', [$site, $server]);
return Inertia::render('sites/show', [
'site' => SiteResource::make($site),
'logs' => ServerLogResource::collection($site->logs()->latest()->simplePaginate(config('web.pagination_size'), pageName: 'logsPage')),
]);
}
/**
* @throws Throwable
*/
#[Post('/servers/{server}/sites/', name: 'sites.store')]
public function store(Request $request, Server $server): RedirectResponse
{
$this->authorize('create', [Site::class, $server]);
$site = app(CreateSite::class)->create($server, $request->all());
return redirect()->route('sites.show', ['server' => $server, 'site' => $site])
->with('info', 'Installing site, please wait...');
}
#[Post('/servers/{server}/sites/{site}/switch', name: 'sites.switch')]
public function switch(Server $server, Site $site): RedirectResponse
{
$this->authorize('view', [$site, $server]);
$previousUrl = URL::previous();
$previousRequest = Request::create($previousUrl);
$previousRoute = app('router')->getRoutes()->match($previousRequest);
if ($previousRoute->hasParameter('site')) {
if (count($previousRoute->parameters()) > 2) {
return redirect()->route('sites.show', ['server' => $server->id, 'site' => $site->id]);
}
return redirect()->route($previousRoute->getName(), ['server' => $server, 'site' => $site->id]);
}
return redirect()->route('sites.show', ['server' => $server->id, 'site' => $site->id]);
}
/**
* @throws SSHError
*/
#[Delete('/servers/{server}/sites/{site}', name: 'sites.destroy')]
public function destroy(Server $server, Site $site): RedirectResponse
{
$this->authorize('delete', [$site, $server]);
app(DeleteSite::class)->delete($site);
return redirect()->route('sites', ['server' => $server])
->with('success', 'Site deleted successfully.');
}
}

View File

@ -3,7 +3,9 @@
namespace App\Http\Middleware;
use App\Http\Resources\ServerResource;
use App\Http\Resources\SiteResource;
use App\Models\Server;
use App\Models\Site;
use App\Models\User;
use Illuminate\Foundation\Inspiring;
use Illuminate\Http\Request;
@ -54,6 +56,20 @@ public function share(Request $request): array
$data = [];
if ($request->route('server')) {
$data['server'] = ServerResource::make($request->route('server'));
// sites
$sites = [];
/** @var Server $server */
$server = $request->route('server');
if ($user && $user->can('viewAny', [Site::class, $server])) {
$sites = SiteResource::collection($server->sites);
}
$data['serverSites'] = $sites;
if ($request->route('site')) {
$data['site'] = SiteResource::make($request->route('site'));
}
}
return [

View File

@ -17,6 +17,7 @@ public function toArray(Request $request): array
return [
'id' => $this->id,
'backup_id' => $this->backup_id,
'backup' => new BackupResource($this->whenLoaded('backup')),
'server_id' => $this->backup->server_id,
'name' => $this->name,
'size' => $this->size,

View File

@ -17,6 +17,7 @@ public function toArray(Request $request): array
return [
'id' => $this->id,
'server_id' => $this->server_id,
'server' => new ServerResource($this->whenLoaded('server')),
'source_control_id' => $this->source_control_id,
'type' => $this->type,
'type_data' => $this->type_data,
@ -28,8 +29,10 @@ public function toArray(Request $request): array
'repository' => $this->repository,
'branch' => $this->branch,
'status' => $this->status,
'status_color' => Site::$statusColors[$this->status] ?? 'default',
'port' => $this->port,
'user' => $this->user,
'url' => $this->getUrl(),
'progress' => $this->progress,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,