clusev/app/Livewire/Files/Index.php

94 lines
3.8 KiB
PHP

<?php
namespace App\Livewire\Files;
use Livewire\Attributes\Layout;
use Livewire\Attributes\On;
use Livewire\Attributes\Title;
use Livewire\Component;
#[Layout('layouts.app')]
#[Title('Dateien — Clusev')]
class Index extends Component
{
/** Current working directory in the SFTP browser. */
public string $path = '/var/www';
/**
* Mock directory listing. Replaced by the SSH/SFTP layer (phpseclib) later.
* Shape mirrors what Sftp::list() will return per entry.
*/
public array $entries = [];
public function mount(): void
{
$this->entries = [
['name' => 'html', 'type' => 'dir', 'size' => null, 'perms' => 'drwxr-xr-x', 'owner' => 'www-data', 'modified' => '2026-06-09 14:22'],
['name' => 'releases', 'type' => 'dir', 'size' => null, 'perms' => 'drwxr-xr-x', 'owner' => 'deploy', 'modified' => '2026-06-10 09:01'],
['name' => 'shared', 'type' => 'dir', 'size' => null, 'perms' => 'drwxr-xr-x', 'owner' => 'deploy', 'modified' => '2026-06-08 18:47'],
['name' => '.env', 'type' => 'file', 'size' => 1284, 'perms' => '-rw-------', 'owner' => 'www-data', 'modified' => '2026-06-10 09:02'],
['name' => 'composer.json', 'type' => 'file', 'size' => 2913, 'perms' => '-rw-r--r--', 'owner' => 'deploy', 'modified' => '2026-06-07 11:30'],
['name' => 'composer.lock', 'type' => 'file', 'size' => 412_337, 'perms' => '-rw-r--r--', 'owner' => 'deploy', 'modified' => '2026-06-07 11:31'],
['name' => 'artisan', 'type' => 'file', 'size' => 1686, 'perms' => '-rwxr-xr-x', 'owner' => 'deploy', 'modified' => '2026-05-21 08:15'],
['name' => 'index.php', 'type' => 'file', 'size' => 543, 'perms' => '-rw-r--r--', 'owner' => 'www-data', 'modified' => '2026-05-21 08:15'],
['name' => 'access.log', 'type' => 'file', 'size' => 8_472_119, 'perms' => '-rw-r-----', 'owner' => 'www-data', 'modified' => '2026-06-11 23:58'],
];
}
/**
* Breadcrumb segments derived from $path (root first, then each folder).
*
* @return array<int, array{label: string, path: string}>
*/
public function getCrumbsProperty(): array
{
$crumbs = [['label' => '/', 'path' => '/']];
$acc = '';
foreach (array_filter(explode('/', $this->path)) as $segment) {
$acc .= '/'.$segment;
$crumbs[] = ['label' => $segment, 'path' => $acc];
}
return $crumbs;
}
/**
* Delete a file (R5): opens the confirm modal, which writes the AuditEvent
* and re-dispatches `fileConfirmed`. SFTP unlink is wired in behind this later.
*/
public function confirmDelete(string $name): void
{
$this->dispatch('openModal',
component: 'modals.confirm-action',
arguments: [
'heading' => 'Datei löschen',
'body' => "{$name}“ wird unwiderruflich aus {$this->path} entfernt.",
'confirmLabel' => 'Löschen',
'danger' => true,
'icon' => 'trash',
'auditAction' => 'file.delete',
'auditTarget' => rtrim($this->path, '/')."/{$name}",
'event' => 'fileConfirmed',
'params' => ['name' => $name],
'notify' => "{$name}“ gelöscht.",
],
);
}
/** Applies the confirmed deletion (mock until SFTP unlink lands). */
#[On('fileConfirmed')]
public function deleteEntry(string $name): void
{
$this->entries = array_values(array_filter(
$this->entries,
fn (array $e): bool => $e['name'] !== $name,
));
}
public function render()
{
return view('livewire.files.index');
}
}