I have a header action in a ListRecords type page where I show a simple modal with a FileUpload and a TextInput. The idea is the user will upload a file that will be saved with a random filename when submit form. Meanwhile, the file basename will be displayed to user in a TextInput, where de user could set a display name for the file.
Actual code works but the file it shows in the TextInput is the tmp one (/tmp/php2j831s). I need the clientOriginalFileName which is available for instance in getUploadedFileNameForStorageUsing
but, this method is triggered after submit de form.
I appreciate any help, thanks!
public static function getUploadFileAction($sender, CreateProjectFolderTreeService $folderService, ?Project $project = null, $actionClass = \Filament\Forms\Components\Actions\Action::class)
{
// \Filament\Forms\Components\Actions\Action::class
// \Filament\Tables\Actions\Action::class
/** @var \Filament\Forms\Components\Actions\Action $actionClass */
return $actionClass::make('create_folder')
->label(__('message.project.upload_file_button'))
->extraAttributes(['class' => 'create_folder_button'])
->icon('file-plus-01')
->requiresConfirmation(false)
->closeModalByClickingAway(false)
->closeModalByEscaping(false)
->modalHeading('')
->modalSubmitActionLabel(__('message.project.upload_file_modal.upload_file_button'))
->modalContent(fn(Get $get, ?Project $record) => self::createdNewFolderModal($record ?? $project, AppUtils::getSafeValueFromGet($get, 'current_folder_name')))
->modalCloseButton()
->form([
\Filament\Forms\Components\FileUpload::make('uploaded_file')
->label(__('message.project.upload_file_modal.select_file'))
->disk('private')
->directory(fn() => "projects/{$project->id}") // Directorio dinámico por proyecto
->required()
->acceptedFileTypes(['application/pdf', 'image/*', 'video/*', 'text/plain'])
->maxSize(10240)
->getUploadedFileNameForStorageUsing(function (BaseFileUpload $component, \Livewire\Features\SupportFileUploads\TemporaryUploadedFile $file) {
return $component->shouldPreserveFilenames()
? $file->getClientOriginalName()
: (Str::ulid() . '.' . $file->getClientOriginalExtension());
})
->afterStateUpdated(function (Set $set, $component, ?string $state) {
$set('new_file_name', $state);
}),
TextInput::make('new_file_name')
->label(__('message.project.upload_file_modal.file_name'))
->live()
->required(),
])
->action(function (array $data, $record, Get $get, Set $set) use ($sender, $project, $folderService): void {
dd($sender, $get(), $data, $record, $project);
$parentId = $sender->parentId;
$projectId = $project->id;
$fileName = $data['new_file_name'];
$filePath = $data['uploaded_file'];
// Verificar si ya existe una carpeta con el mismo nombre y parent_id
$existingFolder = \App\Models\ProjectFile::where('parent_id', $parentId)
->where('project_id', $projectId)
->where('name', $fileName)
->first();
if ($existingFolder) {
\Filament\Notifications\Notification::make()
->title(__('message.project.file_name_error_title'))
->body(__('message.project.file_name_error_body'))
->danger()
->send();
return;
}
$folderService->createProjectFile($project, $fileName, $folderService->getAbsoluteFullPhysicalFolderPath($project, $parentId), $parentId);
$sender->resetTable();
});
}
I think you need to make the FileUpload component reactive ->reactive()
to changes, triggering Livewire updates.
Modified afterStateUpdated
Retrieves the uploaded file instance, extracts its original name with proper type checking, and falls back to the basename if a path string is encountered.
Lastly Add dehydrated(true)
.
\Filament\Forms\Components\FileUpload::make('uploaded_file')
->label(__('message.project.upload_file_modal.select_file'))
->disk('private')
->directory(fn() => "projects/{$project->id}")
->required()
->acceptedFileTypes(['application/pdf', 'image/*', 'video/*', 'text/plain'])
->maxSize(10240)
->getUploadedFileNameForStorageUsing(function (BaseFileUpload $component, TemporaryUploadedFile $file) {
return $component->shouldPreserveFilenames()
? $file->getClientOriginalName()
: (Str::ulid() . '.' . $file->getClientOriginalExtension());
})
->afterStateUpdated(function (Set $set, $component) {
// Get the uploaded file instance and extract original name
$file = $component->getState();
$originalName = $file instanceof TemporaryUploadedFile
? $file->getClientOriginalName()
: basename($file);
$set('new_file_name', $originalName);
})
->reactive(), // Make the component reactive
\Filament\Forms\Components\TextInput::make('new_file_name')
->label(__('message.project.upload_file_modal.file_name'))
->required()
->dehydrated(true),