feat(filament): added move all action (#762)

This commit is contained in:
Kyrch
2024-12-05 03:11:31 -03:00
committed by GitHub
parent c67af74c5f
commit 7be14cb615
13 changed files with 284 additions and 13 deletions
@@ -42,6 +42,8 @@ trait BackfillAudioActionTrait
$this->label(__('filament.actions.video.backfill.name'));
$this->icon('heroicon-o-speaker-wave');
$this->authorize('create', Audio::class);
$this->action(fn (Video $record, array $data) => $this->handle($record, $data));
@@ -13,6 +13,20 @@ use App\Models\BaseModel;
*/
trait DeleteActionTrait
{
/**
* Initial setup for the action.
*
* @return void
*/
protected function setUp(): void
{
parent::setUp();
$this->color('danger');
$this->icon('heroicon-m-trash');
}
/**
* Get the underlying storage action.
*
@@ -17,6 +17,18 @@ use Illuminate\Support\Facades\Storage;
*/
trait MoveActionTrait
{
/**
* Initial setup for the action.
*
* @return void
*/
protected function setUp(): void
{
parent::setUp();
$this->icon('heroicon-o-arrow-long-right');
}
/**
* Get the fields available on the action.
*
@@ -38,7 +50,7 @@ trait MoveActionTrait
->helperText(__('filament.actions.storage.move.fields.path.help'))
->required()
->rules(['required', 'string', 'doesnt_start_with:/', "ends_with:{$this->allowedFileExtension()}", new StorageFileDirectoryExistsRule($fs)])
->default(fn () => $defaultPath),
->default($defaultPath),
]);
}
@@ -0,0 +1,200 @@
<?php
declare(strict_types=1);
namespace App\Concerns\Filament\Actions\Storage;
use App\Actions\Storage\Base\MoveAction;
use App\Actions\Storage\Wiki\Audio\MoveAudioAction;
use App\Actions\Storage\Wiki\Video\MoveVideoAction;
use App\Actions\Storage\Wiki\Video\Script\MoveScriptAction;
use App\Constants\Config\AudioConstants;
use App\Constants\Config\VideoConstants;
use App\Models\Wiki\Audio;
use App\Models\Wiki\Video;
use App\Models\Wiki\Video\VideoScript;
use App\Rules\Storage\StorageFileDirectoryExistsRule;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;
/**
* Trait MoveAllActionTrait
*/
trait MoveAllActionTrait
{
/**
* Initial setup for the action.
*
* @return void
*/
protected function setUp(): void
{
parent::setUp();
$this->label(__('filament.actions.base.moveAll'));
$this->icon('heroicon-o-arrow-long-right');
$this->authorize('create', [Audio::class, Video::class, VideoScript::class]);
$this->action(fn (array $data) => $this->handle($data));
}
/**
* Get the fields available on the action.
*
* @param Form $form
* @return Form
*/
public function getForm(Form $form): ?Form
{
$videoPath = $this->videoDefaultPath();
$audioPath = $this->audioDefaultPath();
$scriptPath = $this->scriptDefaultPath();
$videoFs = Storage::disk(Config::get(VideoConstants::DEFAULT_DISK_QUALIFIED));
$audioFs = Storage::disk(Config::get(AudioConstants::DEFAULT_DISK_QUALIFIED));
$scriptFs = Storage::disk(Config::get(VideoConstants::SCRIPT_DISK_QUALIFIED));
return $form
->schema([
TextInput::make('video')
->label(__('filament.resources.singularLabel.video'))
->helperText(__('filament.actions.storage.move.fields.path.help'))
->required()
->rules(['required', 'string', 'doesnt_start_with:/', "ends_with:.webm", new StorageFileDirectoryExistsRule($videoFs)])
->default($videoPath),
TextInput::make('audio')
->label(__('filament.resources.singularLabel.audio'))
->helperText(__('filament.actions.storage.move.fields.path.help'))
->hidden($audioPath === null)
->required($audioPath !== null)
->rules(['string', 'doesnt_start_with:/', "ends_with:.ogg", new StorageFileDirectoryExistsRule($audioFs)])
->default($audioPath),
TextInput::make('script')
->label(__('filament.resources.singularLabel.video_script'))
->helperText(__('filament.actions.storage.move.fields.path.help'))
->hidden($scriptPath === null)
->required($scriptPath !== null)
->rules(['string', 'doesnt_start_with:/', "ends_with:.txt", new StorageFileDirectoryExistsRule($scriptFs)])
->default($scriptPath),
]);
}
/**
* Handle the action.
*
* @param array $fields
* @return void
*/
public function handle(array $fields): void
{
$videoPath = Arr::get($fields, 'video');
$audioPath = Arr::get($fields, 'audio');
$scriptPath = Arr::get($fields, 'script');
if (is_string($videoPath)) {
$action = new MoveVideoAction($this->getVideo(), $videoPath);
$this->resolveAction($action);
}
if (is_string($audioPath) && ($audio = $this->getVideo()->audio)) {
$action = new MoveAudioAction($audio, $audioPath);
$this->resolveAction($action);
}
if (is_string($scriptPath) && ($script = $this->getVideo()->videoscript)) {
$action = new MoveScriptAction($script, $scriptPath);
$this->resolveAction($action);
}
}
/**
* Resolve an action.
*
* @param MoveAction $action
* @return void
*/
protected function resolveAction(MoveAction $action): void
{
$storageResults = $action->handle();
$storageResults->toLog();
$action->then($storageResults);
$actionResult = $storageResults->toActionResult();
if ($actionResult->hasFailed()) {
$this->failedLog($actionResult->getMessage());
}
}
/**
* Get the video.
*
* @return Video|null
*/
protected function getVideo(): ?Video
{
$record = $this->getRecord();
return $record instanceof Video
? $record
: null;
}
/**
* Resolve the default value for the path field of the video.
*
* @return string|null
*/
protected function videoDefaultPath(): ?string
{
$video = $this->getVideo();
return $video instanceof Video
? $video->path
: null;
}
/**
* Resolve the default value for the path field of the audio.
*
* @return string|null
*/
protected function audioDefaultPath(): ?string
{
$video = $this->getVideo();
$audio = $video->audio;
return $audio instanceof Audio
? $audio->path
: null;
}
/**
* Resolve the default value for the path field of the script.
*
* @return string|null
*/
protected function scriptDefaultPath(): ?string
{
$video = $this->getVideo();
$script = $video->videoscript;
return $script instanceof VideoScript
? $script->path
: null;
}
}
@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace App\Filament\Actions\Storage;
use App\Concerns\Filament\Actions\Storage\MoveAllActionTrait;
use App\Filament\Actions\BaseAction;
/**
* Class MoveAllAction.
*/
class MoveAllAction extends BaseAction
{
use MoveAllActionTrait;
}
@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace App\Filament\HeaderActions\Storage;
use App\Concerns\Filament\Actions\Storage\MoveAllActionTrait;
use App\Filament\HeaderActions\BaseHeaderAction;
/**
* Class MoveAllHeaderAction.
*/
class MoveAllHeaderAction extends BaseHeaderAction
{
use MoveAllActionTrait;
}
+3
View File
@@ -7,6 +7,7 @@ namespace App\Filament\Resources\Wiki;
use App\Enums\Models\Wiki\VideoOverlap;
use App\Enums\Models\Wiki\VideoSource;
use App\Filament\Actions\Models\Wiki\Video\BackfillAudioAction;
use App\Filament\Actions\Storage\MoveAllAction;
use App\Filament\Actions\Storage\Wiki\Video\DeleteVideoAction;
use App\Filament\Actions\Storage\Wiki\Video\MoveVideoAction;
use App\Filament\BulkActions\Models\Wiki\Video\VideoDiscordNotificationBulkAction;
@@ -407,6 +408,8 @@ class Video extends BaseResource
MoveVideoAction::make('move-video'),
MoveAllAction::make('move-all'),
DeleteVideoAction::make('delete-video'),
]),
],
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Filament\Resources\Wiki\Video\Pages;
use App\Filament\HeaderActions\Models\Wiki\Video\BackfillAudioHeaderAction;
use App\Filament\HeaderActions\Storage\MoveAllHeaderAction;
use App\Filament\HeaderActions\Storage\Wiki\Video\DeleteVideoHeaderAction;
use App\Filament\HeaderActions\Storage\Wiki\Video\MoveVideoHeaderAction;
use App\Filament\Resources\Wiki\Video;
@@ -34,7 +35,9 @@ class EditVideo extends BaseEditResource
BackfillAudioHeaderAction::make('backfill-audio'),
MoveVideoHeaderAction::make('move-video'),
MoveAllHeaderAction::make('move-all'),
DeleteVideoHeaderAction::make('delete-video'),
]),
],
+1 -1
View File
@@ -45,7 +45,7 @@ use Illuminate\Support\Collection;
* @property string $path
* @property Collection<int, PlaylistTrack> $tracks
* @property int|null $resolution
* @property VideoScript|null $script
* @property VideoScript|null $videoscript
* @property int $size
* @property VideoSource|null $source
* @property bool $subbed
+3
View File
@@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
use Laravel\Pennant\Middleware\EnsureFeaturesAreActive;
@@ -25,6 +26,8 @@ class AppServiceProvider extends ServiceProvider
{
Model::preventLazyLoading();
DB::prohibitDestructiveCommands(app()->isProduction());
Model::handleLazyLoadingViolationUsing(function (Model $model, string $relation) {
$class = get_class($model);
+1 -1
View File
@@ -44,7 +44,7 @@
"laravel/sanctum": "^4.0.3",
"laravel/scout": "^10.11.7",
"laravel/tinker": "^2.10",
"league/flysystem-aws-s3-v3": "^3.29",
"league/flysystem-aws-s3-v3": "3.0",
"leandrocfe/filament-apex-charts": "^3.1.4",
"malzariey/filament-daterangepicker-filter": "2.7",
"propaganistas/laravel-disposable-email": "^2.4.7",
Generated
+10 -9
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "993d753f87eac9affe4117d4424730e8",
"content-hash": "dda5db2eb250fdbeb3c2d460ca577946",
"packages": [
{
"name": "anourvalar/eloquent-serialize",
@@ -4728,21 +4728,21 @@
},
{
"name": "league/flysystem-aws-s3-v3",
"version": "3.29.0",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
"reference": "c6ff6d4606e48249b63f269eba7fabdb584e76a9"
"reference": "f8ba6a92a5c1fdcbdd89dede009a1e6e1b93ba8c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/c6ff6d4606e48249b63f269eba7fabdb584e76a9",
"reference": "c6ff6d4606e48249b63f269eba7fabdb584e76a9",
"url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/f8ba6a92a5c1fdcbdd89dede009a1e6e1b93ba8c",
"reference": "f8ba6a92a5c1fdcbdd89dede009a1e6e1b93ba8c",
"shasum": ""
},
"require": {
"aws/aws-sdk-php": "^3.295.10",
"league/flysystem": "^3.10.0",
"aws/aws-sdk-php": "^3.132.4",
"league/flysystem": "^2.0.0 || ^3.0.0",
"league/mime-type-detection": "^1.0.0",
"php": "^8.0.2"
},
@@ -4777,9 +4777,10 @@
"storage"
],
"support": {
"source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.29.0"
"issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues",
"source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.0.0"
},
"time": "2024-08-17T13:10:48+00:00"
"time": "2022-01-13T21:11:49+00:00"
},
{
"name": "league/flysystem-local",
+1
View File
@@ -96,6 +96,7 @@ return [
'detach' => 'Detach',
'edit' => 'Edit',
'forcedelete' => 'Force Delete',
'moveAll' => 'Move All',
'restore' => 'Restore',
'view' => 'View',
],