mirror of
https://github.com/coollabsio/coolify.git
synced 2026-08-27 18:14:24 -05:00
feat(files): add Files tab and routes for applications, services and databases
This commit is contained in:
@@ -40,8 +40,14 @@ class FileBrowser extends Component
|
||||
|
||||
public $upload;
|
||||
|
||||
public function mount($resource): void
|
||||
/** @var array<string, mixed> */
|
||||
public array $parameters = [];
|
||||
|
||||
public function mount($resource = null): void
|
||||
{
|
||||
$this->parameters = get_route_parameters();
|
||||
$resource = $resource ?? $this->resolveResourceFromRoute();
|
||||
|
||||
// Security gate first, before any server or container resolution.
|
||||
$this->authorize('canAccessTerminal');
|
||||
$this->authorize('view', $resource);
|
||||
@@ -255,6 +261,29 @@ class FileBrowser extends Component
|
||||
};
|
||||
}
|
||||
|
||||
protected function resolveResourceFromRoute()
|
||||
{
|
||||
$parameters = get_route_parameters();
|
||||
$teamId = data_get(auth()->user()->currentTeam(), 'id');
|
||||
|
||||
if ($uuid = data_get($parameters, 'application_uuid')) {
|
||||
return Application::ownedByCurrentTeam()->where('uuid', $uuid)->firstOrFail();
|
||||
}
|
||||
if ($uuid = data_get($parameters, 'service_uuid')) {
|
||||
return Service::ownedByCurrentTeam()->where('uuid', $uuid)->firstOrFail();
|
||||
}
|
||||
if ($uuid = data_get($parameters, 'database_uuid')) {
|
||||
$resource = getResourceByUuid($uuid, $teamId);
|
||||
if (is_null($resource)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return $resource;
|
||||
}
|
||||
|
||||
abort(404);
|
||||
}
|
||||
|
||||
protected function resolveType($resource): string
|
||||
{
|
||||
return match (true) {
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
'navigate' => false,
|
||||
'visible' => ! $application->destination->server->isSwarm() && auth()->user()?->can('canAccessTerminal'),
|
||||
],
|
||||
[
|
||||
'label' => 'Files',
|
||||
'route' => 'project.application.files',
|
||||
'active' => $currentRoute === 'project.application.files',
|
||||
'visible' => ! $application->destination->server->isSwarm() && auth()->user()?->can('canAccessTerminal'),
|
||||
],
|
||||
[
|
||||
'label' => 'Deployment Logs',
|
||||
'route' => 'project.application.deployment.index',
|
||||
@@ -142,6 +148,7 @@
|
||||
'Persistent Storage' => 'storages',
|
||||
'Backups' => 'database',
|
||||
'Terminal' => 'browser-terminal',
|
||||
'Files' => 'folder',
|
||||
'Deployment Logs' => 'time-back',
|
||||
'Runtime Logs' => 'unordered-list',
|
||||
'Git Source' => 'sources',
|
||||
@@ -161,7 +168,7 @@
|
||||
// Discord-style groups for the settings sidebar
|
||||
$menuGroups = [
|
||||
'Settings' => ['General', 'Domains', 'Environment Variables', 'Persistent Storage', 'Advanced', 'Swarm', 'Healthcheck'],
|
||||
'Observe & troubleshoot' => ['Runtime Logs', 'Deployment Logs', 'Terminal', 'Metrics'],
|
||||
'Observe & troubleshoot' => ['Runtime Logs', 'Deployment Logs', 'Terminal', 'Files', 'Metrics'],
|
||||
'Deploy' => ['Git Source', 'Servers', 'Preview Deployments'],
|
||||
'Automation' => ['Scheduled Tasks', 'Webhooks', 'Backups'],
|
||||
'Operations' => ['Resource Operations', 'Resource Limits', 'Rollback', 'Tags', 'Danger Zone'],
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
['label' => 'Servers', 'route' => 'project.database.servers', 'icon' => 'servers'],
|
||||
['label' => 'Runtime Logs', 'route' => 'project.database.logs', 'icon' => 'unordered-list', 'navigate' => false],
|
||||
['label' => 'Terminal', 'route' => 'project.database.command', 'icon' => 'browser-terminal', 'navigate' => false, 'visible' => auth()->user()?->can('canAccessTerminal')],
|
||||
['label' => 'Files', 'route' => 'project.database.files', 'icon' => 'folder', 'visible' => auth()->user()?->can('canAccessTerminal')],
|
||||
['label' => 'Webhooks', 'route' => 'project.database.webhooks', 'icon' => 'notifications'],
|
||||
['label' => 'Healthcheck', 'route' => 'project.database.healthcheck', 'icon' => 'feedback'],
|
||||
['label' => 'Resource Limits', 'route' => 'project.database.resource-limits', 'icon' => 'cpu'],
|
||||
@@ -33,7 +34,7 @@
|
||||
|
||||
$menuGroups = [
|
||||
'Settings' => ['General', 'Environment Variables', 'Persistent Storage', 'Healthcheck'],
|
||||
'Observe & troubleshoot' => ['Runtime Logs', 'Terminal', 'Metrics'],
|
||||
'Observe & troubleshoot' => ['Runtime Logs', 'Terminal', 'Files', 'Metrics'],
|
||||
'Deploy' => ['Servers'],
|
||||
'Automation' => ['Webhooks', 'Backups', 'Import Backup'],
|
||||
'Operations' => ['Resource Operations', 'Resource Limits', 'Tags', 'Danger Zone'],
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
['label' => 'Backups', 'route' => 'project.service.volume-backups.index', 'icon' => 'database'],
|
||||
['label' => 'Runtime Logs', 'route' => 'project.service.logs', 'icon' => 'unordered-list', 'navigate' => false],
|
||||
['label' => 'Terminal', 'route' => 'project.service.command', 'icon' => 'browser-terminal', 'navigate' => false, 'visible' => auth()->user()?->can('canAccessTerminal')],
|
||||
['label' => 'Files', 'route' => 'project.service.files', 'icon' => 'folder', 'visible' => auth()->user()?->can('canAccessTerminal')],
|
||||
['label' => 'Scheduled Tasks', 'route' => 'project.service.scheduled-tasks.show', 'icon' => 'calendar'],
|
||||
['label' => 'Webhooks', 'route' => 'project.service.webhooks', 'icon' => 'notifications'],
|
||||
['label' => 'Resource Operations', 'route' => 'project.service.resource-operations', 'icon' => 'server-update'],
|
||||
@@ -32,7 +33,7 @@
|
||||
|
||||
$menuGroups = [
|
||||
'Settings' => ['General', 'Domains', 'Environment Variables', 'Persistent Storage'],
|
||||
'Observe & troubleshoot' => ['Runtime Logs', 'Terminal'],
|
||||
'Observe & troubleshoot' => ['Runtime Logs', 'Terminal', 'Files'],
|
||||
'Automation' => ['Scheduled Tasks', 'Webhooks', 'Backups'],
|
||||
'Operations' => ['Resource Operations', 'Tags', 'Danger Zone'],
|
||||
];
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
<div>
|
||||
<x-slot:title>
|
||||
{{ data_get_str($resource, 'name')->limit(10) }} > Files | Coolify
|
||||
</x-slot>
|
||||
|
||||
@if ($type === 'application')
|
||||
<livewire:project.application.heading :application="$resource" wire:key="application-heading-files" />
|
||||
@elseif ($type === 'service')
|
||||
<livewire:project.service.heading :service="$resource" :parameters="$parameters" title="Files" />
|
||||
@else
|
||||
<livewire:project.database.heading :database="$resource" />
|
||||
@endif
|
||||
|
||||
<x-application.settings-section title="Files"
|
||||
helper="Browse and manage files inside the running container." :flush="true">
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ use App\Livewire\Project\Service\Index as ServiceIndex;
|
||||
use App\Livewire\Project\Service\VolumeBackup\Index;
|
||||
use App\Livewire\Project\Service\VolumeBackup\Show;
|
||||
use App\Livewire\Project\Shared\ExecuteContainerCommand;
|
||||
use App\Livewire\Project\Shared\FileBrowser;
|
||||
use App\Livewire\Project\Shared\Logs;
|
||||
use App\Livewire\Project\Show as ProjectShow;
|
||||
use App\Livewire\Security\ApiTokens;
|
||||
@@ -297,6 +298,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||
Route::get('/deployment/{deployment_uuid}', DeploymentShow::class)->name('project.application.deployment.show');
|
||||
Route::get('/logs', Logs::class)->name('project.application.logs');
|
||||
Route::get('/terminal', ExecuteContainerCommand::class)->name('project.application.command')->middleware('can.access.terminal');
|
||||
Route::get('/files', FileBrowser::class)->name('project.application.files')->middleware('can.access.terminal');
|
||||
Route::get('/tasks/{task_uuid}', ApplicationConfiguration::class)->name('project.application.scheduled-tasks');
|
||||
});
|
||||
Route::prefix('project/{project_uuid}/environment/{environment_uuid}/database/{database_uuid}')->group(function () {
|
||||
@@ -315,6 +317,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||
|
||||
Route::get('/logs', Logs::class)->name('project.database.logs');
|
||||
Route::get('/terminal', ExecuteContainerCommand::class)->name('project.database.command')->middleware('can.access.terminal');
|
||||
Route::get('/files', FileBrowser::class)->name('project.database.files')->middleware('can.access.terminal');
|
||||
Route::get('/backups', DatabaseBackupIndex::class)->name('project.database.backup.index');
|
||||
Route::get('/backups/{backup_uuid}', DatabaseBackupExecution::class)->name('project.database.backup.execution');
|
||||
Route::get('/backups/{backup_uuid}/s3', DatabaseBackupExecution::class)->name('project.database.backup.s3');
|
||||
@@ -340,6 +343,7 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
||||
Route::get('/tags', ServiceConfiguration::class)->name('project.service.tags');
|
||||
Route::get('/danger', ServiceConfiguration::class)->name('project.service.danger');
|
||||
Route::get('/terminal', ExecuteContainerCommand::class)->name('project.service.command')->middleware('can.access.terminal');
|
||||
Route::get('/files', FileBrowser::class)->name('project.service.files')->middleware('can.access.terminal');
|
||||
Route::get('/{stack_service_uuid}/backups', ServiceDatabaseBackups::class)->name('project.service.database.backups');
|
||||
Route::get('/{stack_service_uuid}/backups/{backup_uuid}', ServiceDatabaseBackups::class)->name('project.service.database.backup.show');
|
||||
Route::get('/{stack_service_uuid}/backups/{backup_uuid}/s3', ServiceDatabaseBackups::class)->name('project.service.database.backup.s3');
|
||||
|
||||
Reference in New Issue
Block a user