Skip to content

Commit

Permalink
wip bucket file browser
Browse files Browse the repository at this point in the history
  • Loading branch information
flowan committed Feb 16, 2024
1 parent 609480e commit 26e9f67
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 1 deletion.
7 changes: 7 additions & 0 deletions app/Filament/Resources/BucketResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,19 @@ public static function table(Table $table): Table
default => 'danger',
}),
Tables\Columns\TextColumn::make('created_at')
->dateTime()
->searchable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\TextColumn::make('updated_at')
->dateTime()
->searchable()
->toggleable(isToggledHiddenByDefault: true),
])
->actions([
Tables\Actions\Action::make('files')
->label('Files')
->icon('heroicon-o-folder-open')
->url(fn (Bucket $record): string => route('filament.admin.resources.buckets.files', $record)),
Tables\Actions\EditAction::make(),
])
->defaultSort('id', 'desc');
Expand All @@ -77,6 +83,7 @@ public static function getPages(): array
'index' => Pages\ListBuckets::route('/'),
'create' => Pages\CreateBucket::route('/create'),
'edit' => Pages\EditBucket::route('/{record}/edit'),
'files' => Pages\Files::route('/{record}/files'),
];
}
}
93 changes: 93 additions & 0 deletions app/Filament/Resources/BucketResource/Pages/Files.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Filament\Resources\BucketResource\Pages;

use App\Filament\Resources\BucketResource;
use Filament\Resources\Pages\Page;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class Files extends Page
{
protected static string $resource = BucketResource::class;

protected static string $view = 'filament.resources.bucket-resource.pages.files';

protected ?Model $record = null;

public array $directories = [];

public array $files = [];

public array $breadcrumbs = [];

public string $path = '';

public function mount(int | string $record): void
{
$this->record = $this->resolveRecord($record);
$this->path = (string) request()->input('path', '');

if (Str::of($this->path)->contains('..')) {
abort(403);
}

$parentPath = dirname($this->path);
if ($parentPath === '.') {
$parentPath = '';
}

if (! empty($this->path)) {
$this->breadcrumbs = collect(explode('/', $this->path))->map(function ($part, $index) {
return (object)[
'name' => $part,
'path' => implode('/', array_slice(explode('/', $this->path), 0, $index + 1)),
];
})->toArray();
}

$directories = Storage::directories(bucket_relative_path($this->record->name.'/'.$this->path));

foreach ($directories as $key => $directory) {
$directories[$key] = (object) [
'name' => basename($directory),
'path' => Str::of($directory)->after(bucket_relative_path($this->record->name))->trim('/')->__toString(),
];
}

$this->directories = array_merge([(object) ['name' => '..', 'path' => $parentPath]], $directories);

$files = Storage::files(bucket_relative_path($this->record->name.'/'.$this->path));

foreach ($files as $key => $file) {
$files[$key] = (object) [
'name' => basename($file),
'path' => Str::of($file)->after(bucket_relative_path($this->record->name))->trim('/')->__toString(),
'size' => format_filesize(Storage::size($file), 2),
'last_modified' => Carbon::createFromTimestamp(Storage::lastModified($file))->format(Table::$defaultDateTimeDisplayFormat),
];
}

$this->files = $files;
}

protected function resolveRecord(int | string $key): Model
{
$record = static::getResource()::resolveRecordRouteBinding($key);

if ($record === null) {
throw (new ModelNotFoundException())->setModel($this->getModel(), [$key]);
}

return $record;
}

public function getRecord(): Model
{
return $this->record;
}
}
12 changes: 12 additions & 0 deletions app/Helpers/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,15 @@ function bucket_path(string $bucket = 'public', ?string $filePath = null): strin

return $rootPath.'/'.bucket_relative_path($bucket, $filePath);
}

function format_filesize($bytes, int $decimals = 0): ?string
{
if (! $bytes) {
return null;
}

$size = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
$factor = floor((\strlen($bytes) - 1) / 3);

return round((float) sprintf("%.{$decimals}f", $bytes / (1024 ** $factor)), $decimals).' '.$size[$factor];
}
2 changes: 1 addition & 1 deletion config/warehouse.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

return [
'version' => '0.1.0',
'version' => '0.3.0',

'storage' => [
'path' => env('WAREHOUSE_STORAGE_PATH', storage_path('app')),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<x-filament-panels::page>

<div class="fi-ta-ctn divide-y divide-gray-200 overflow-hidden rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:divide-white/10 dark:bg-gray-900 dark:ring-white/10">
<div class="fi-ta-content divide-y divide-gray-200 overflow-x-auto dark:divide-white/10 dark:border-t-white/10">

<div class="fi-ta-header flex gap-1.5 p-4 text-sm">
<x-filament::link color="gray" href="?path=">
{{ $this->getRecord()->name }}
</x-filament::link>

@foreach($breadcrumbs as $breadcrumb)
<span class="text-gray-400">></span>
<x-filament::link color="gray" href="?path={{ $breadcrumb->path }}">
{{ $breadcrumb->name }}
</x-filament::link>
@endforeach
</div>

<x-filament-tables::table>
<x-slot name="header">
<x-filament-tables::header-cell>Name</x-filament-tables::header-cell>
<x-filament-tables::header-cell>Size</x-filament-tables::header-cell>
<x-filament-tables::header-cell>Last Modified</x-filament-tables::header-cell>
</x-slot>

@foreach($directories as $directory)
<tr class="fi-ta-row [@media(hover:hover)]:transition [@media(hover:hover)]:duration-75 hover:bg-gray-50 dark:hover:bg-white/5">
<td class="fi-ta-cell p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3 fi-table-cell-name">
<div class="fi-ta-col-wrp flex items-center">
<x-filament::icon
icon="heroicon-o-folder"
class="h-6 w-6 text-gray-400 dark:text-gray-500"
/>
<a href="?path={{ $directory->path }}" class="fi-ta-text inline-block w-full px-3 py-3 text-sm">{{ $directory->name }}</a>
</div>
</td>
<td class="fi-ta-cell p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3 fi-table-cell-user.name">
<div class="fi-ta-col-wrp">

</div>
</td>
<td class="fi-ta-cell p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3 fi-table-cell-visibility">
<div class="fi-ta-col-wrp">

</div>
</td>
</tr>
@endforeach

@foreach($files as $file)
<tr class="fi-ta-row [@media(hover:hover)]:transition [@media(hover:hover)]:duration-75 hover:bg-gray-50 dark:hover:bg-white/5">
<td class="fi-ta-cell p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3 fi-table-cell-name">
<div class="fi-ta-col-wrp flex items-center">
<x-filament::icon
icon="heroicon-o-document"
class="h-6 w-6 text-gray-400 dark:text-gray-500"
/>
<span class="fi-ta-text text-sm inline-block px-3 py-3">{{ $file->name }}</span>
</div>
</td>
<td class="fi-ta-cell p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3 fi-table-cell-user.name">
<div class="fi-ta-col-wrp">
<span class="fi-ta-text text-sm inline-block px-3 py-3">{{ $file->size }}</span>
</div>
</td>
<td class="fi-ta-cell p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3 fi-table-cell-visibility">
<div class="fi-ta-col-wrp">
<span class="fi-ta-text text-sm inline-block px-3 py-3">{{ $file->last_modified }}</span>
</div>
</td>
</tr>
@endforeach
</x-filament-tables::table>

</div>
</div>

</x-filament-panels::page>

0 comments on commit 26e9f67

Please sign in to comment.