mirror of
https://github.com/brufdev/many-notes.git
synced 2026-05-13 21:59:37 -05:00
Allow multiple file imports into vaults
This commit is contained in:
@@ -26,8 +26,11 @@ final class ImportFile extends Component
|
||||
|
||||
public VaultNode $parent;
|
||||
|
||||
#[Validate('required|file')]
|
||||
public ?TemporaryUploadedFile $file = null;
|
||||
/**
|
||||
* @var array<int, TemporaryUploadedFile> $files
|
||||
*/
|
||||
#[Validate(['files.*' => 'required|file'])]
|
||||
public array $files = [];
|
||||
|
||||
public string $fileMimes;
|
||||
|
||||
@@ -55,29 +58,35 @@ final class ImportFile extends Component
|
||||
$this->openModal();
|
||||
}
|
||||
|
||||
public function updatedFile(): void
|
||||
public function updatedFiles(): void
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
/** @var TemporaryUploadedFile $file */
|
||||
$file = $this->file;
|
||||
$fileExtension = $file->getClientOriginalExtension();
|
||||
$fileMimeType = $file->getMimeType();
|
||||
$fileName = $file->getClientOriginalName();
|
||||
$filePath = $file->getRealPath();
|
||||
$filesImported = 0;
|
||||
|
||||
if (!VaultFile::validate($fileExtension, $fileMimeType)) {
|
||||
$this->closeModal();
|
||||
foreach ($this->files as $file) {
|
||||
$fileExtension = $file->getClientOriginalExtension();
|
||||
$fileMimeType = $file->getMimeType();
|
||||
$fileName = $file->getClientOriginalName();
|
||||
$filePath = $file->getRealPath();
|
||||
|
||||
$this->dispatch('toast', message: __('File not supported'), type: 'error');
|
||||
if (!VaultFile::validate($fileExtension, $fileMimeType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new ProcessImportedFile()->handle($this->vault, $this->parent, $fileName, $filePath);
|
||||
$filesImported++;
|
||||
}
|
||||
|
||||
$this->closeModal();
|
||||
|
||||
if ($filesImported === 0) {
|
||||
$this->dispatch('toast', message: __('No files imported'), type: 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
new ProcessImportedFile()->handle($this->vault, $this->parent, $fileName, $filePath);
|
||||
$this->closeModal();
|
||||
|
||||
$this->dispatch('toast', message: __('File imported'), type: 'success');
|
||||
$this->dispatch('toast', message: __('Files imported'), type: 'success');
|
||||
|
||||
broadcast(new VaultFileSystemUpdatedEvent($this->vault));
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
x-on:livewire-upload-progress="progress = $event.detail.progress"
|
||||
>
|
||||
<label
|
||||
for="file-upload"
|
||||
for="files-upload"
|
||||
class="flex flex-col items-center justify-center w-full h-full gap-2 text-base font-medium cursor-pointer"
|
||||
>
|
||||
<h6 class="font-semibold">{{ __('Browse file to import') }}</h6>
|
||||
<h6 class="font-semibold">{{ __('Browse files to import') }}</h6>
|
||||
<span class="text-sm">{{ __('Image, video, audio, note or pdf file') }}</span>
|
||||
<span class="text-sm">{{ __('Max size ') . ini_get('upload_max_filesize') }}</span>
|
||||
|
||||
@error('file')
|
||||
@error('files.*')
|
||||
<p class="text-sm text-center text-error-500" aria-live="assertive">{{ $message }}</p>
|
||||
@enderror
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<input type="file" id="file-upload" class="hidden" wire:model="file" accept="{{ $fileMimes }}" />
|
||||
<input type="file" id="files-upload" class="hidden" wire:model="files" accept="{{ $fileMimes }}" multiple />
|
||||
</div>
|
||||
</x-form>
|
||||
</x-modal.panel>
|
||||
|
||||
@@ -42,7 +42,7 @@ it('does not accept passing a file as parent node', function (): void {
|
||||
->assertStatus(400);
|
||||
});
|
||||
|
||||
it('saves an imported file to both the database and the disk', function (): void {
|
||||
it('saves imported files to both the database and the disk', function (): void {
|
||||
$user = User::factory()->create()->first();
|
||||
$vault = new CreateVault()->handle($user, [
|
||||
'name' => fake()->words(3, true),
|
||||
@@ -52,16 +52,20 @@ it('saves an imported file to both the database and the disk', function (): void
|
||||
'name' => fake()->words(3, true),
|
||||
]);
|
||||
$content = fake()->paragraph();
|
||||
$file = UploadedFile::fake()->createWithContent('note.md', $content);
|
||||
$file1 = UploadedFile::fake()->createWithContent('note1.md', $content);
|
||||
$file2 = UploadedFile::fake()->createWithContent('note2.md', $content);
|
||||
|
||||
Livewire::actingAs($user)
|
||||
->test(ImportFile::class, ['vault' => $vault])
|
||||
->assertSet('show', false)
|
||||
->call('open', $node)
|
||||
->set('file', $file)
|
||||
->set('files', [$file1, $file2])
|
||||
->assertSet('show', false);
|
||||
|
||||
$path = new GetPathFromVaultNode()->handle($node) . '/' . $file->name;
|
||||
$path = new GetPathFromVaultNode()->handle($node) . '/' . $file1->name;
|
||||
expect(Storage::disk('local')->exists($path))->toBeTrue();
|
||||
expect(Storage::disk('local')->get($path))->toBe($content);
|
||||
$path = new GetPathFromVaultNode()->handle($node) . '/' . $file2->name;
|
||||
expect(Storage::disk('local')->exists($path))->toBeTrue();
|
||||
expect(Storage::disk('local')->get($path))->toBe($content);
|
||||
});
|
||||
@@ -87,7 +91,7 @@ it('handles name collisions when importing a file with an existing name', functi
|
||||
Livewire::actingAs($user)
|
||||
->test(ImportFile::class, ['vault' => $vault])
|
||||
->call('open', $folderNode)
|
||||
->set('file', $file);
|
||||
->set('files', $file);
|
||||
|
||||
$nodes = $vault->nodes()->get();
|
||||
expect($nodes->count())->toBe(3);
|
||||
@@ -122,7 +126,7 @@ it('handles name collisions when importing a file with a name existing in multip
|
||||
Livewire::actingAs($user)
|
||||
->test(ImportFile::class, ['vault' => $vault])
|
||||
->call('open')
|
||||
->set('file', $file);
|
||||
->set('files', $file);
|
||||
|
||||
$nodes = $vault->nodes()->get();
|
||||
expect($nodes->count())->toBe(3);
|
||||
@@ -148,7 +152,7 @@ it('does not import a file with a non-allowed extension', function (): void {
|
||||
->test(ImportFile::class, ['vault' => $vault])
|
||||
->assertSet('show', false)
|
||||
->call('open')
|
||||
->set('file', $file)
|
||||
->set('files', $file)
|
||||
->assertDispatched('toast', type: 'error');
|
||||
});
|
||||
|
||||
@@ -169,7 +173,7 @@ it('creates links when importing a file', function (): void {
|
||||
Livewire::actingAs($user)
|
||||
->test(ImportFile::class, ['vault' => $vault])
|
||||
->call('open')
|
||||
->set('file', $file);
|
||||
->set('files', $file);
|
||||
|
||||
expect($vault->nodes()->get()->get(1)->links()->count())->toBe(1);
|
||||
});
|
||||
@@ -185,7 +189,7 @@ it('creates tags when importing a file', function (): void {
|
||||
Livewire::actingAs($user)
|
||||
->test(ImportFile::class, ['vault' => $vault])
|
||||
->call('open')
|
||||
->set('file', $file);
|
||||
->set('files', $file);
|
||||
|
||||
expect($vault->nodes()->first()->tags()->count())->toBe(2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user