Skip to content

Commit

Permalink
adds ability to download sample excel
Browse files Browse the repository at this point in the history
  • Loading branch information
eighty9nine committed Oct 9, 2024
1 parent da759f0 commit 048155a
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 99 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,33 @@ In some cases you may want to mutate the data before or after validation, in ord

```

### Sample Excel File
You can allow users to download a sample excel file by using the `sampleExcel` method. This method accepts an array of data, a file name, an export class and a sample button label.

```php

use Filament\Forms\Components\Actions\Action;

protected function getHeaderActions(): array
{
return [
\EightyNine\ExcelImport\ExcelImportAction::make()
->sampleExcel(
sampleData: [
['name' => 'John Doe', 'email' => 'john@doe.com', 'phone' => '123456789'],
['name' => 'Jane Doe', 'email' => 'jane@doe.com', 'phone' => '987654321'],
],
fileName: 'sample.xlsx',
exportClass: App\Exports\SampleExport::class,
sampleButtonLabel: 'Download Sample',
customiseActionUsing: fn(Action $action) => $action->color('secondary')
->icon('heroicon-m-clipboard')
->requiresConfirmation(),
),
Actions\CreateAction::make(),
];
}
```

## Testing

Expand Down
1 change: 1 addition & 0 deletions resources/lang/en/excel-import.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
// translations for EightyNine/ExcelImportAction
return [
'validation_failed' => 'Row :row failed validation. The following messages were returned: :messages',
'download_sample_excel_file' => 'Download Sample Excel File',
];
17 changes: 17 additions & 0 deletions src/Concerns/BelongsToTable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace EightyNine\ExcelImport\Concerns;

use Filament\Tables\Table;

trait BelongsToTable
{
protected Table $table;

public function table(Table $table): static
{
$this->table = $table;

return $this;
}
}
105 changes: 105 additions & 0 deletions src/Concerns/HasExcelImportAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace EightyNine\ExcelImport\Concerns;

use Closure;
use EightyNine\ExcelImport\DefaultImport;
use Maatwebsite\Excel\Facades\Excel;

trait HasExcelImportAction
{
use HasUploadForm,
HasFormActionHooks,
HasCustomCollectionMethod,
CanCustomiseActionSetup,
BelongsToTable,
HasSampleExcelFile;

protected string $importClass = DefaultImport::class;

protected array $importClassAttributes = [];

public function use(string $class = null, ...$attributes): static
{
$this->importClass = $class ?: DefaultImport::class;
$this->importClassAttributes = $attributes;

return $this;
}

public static function getDefaultName(): ?string
{
return 'import';
}

public function action(Closure | string | null $action): static
{
if ($action !== 'importData') {
throw new \Exception('You\'re unable to override the action for this plugin');
}

$this->action = $this->importData();

return $this;
}

protected function setUp(): void
{
parent::setUp();

$this->icon('heroicon-o-arrow-down-tray')
->color('warning')
->form(fn () => $this->getDefaultForm())
->modalIcon('heroicon-o-arrow-down-tray')
->color('success')
->modalWidth('md')
->modalAlignment('center')
->modalHeading(fn ($livewire) => __('Import Excel'))
->modalDescription(__('Import data into database from excel file'))
->modalFooterActionsAlignment('right')
->closeModalByClickingAway(false)
->action('importData');
}

private function importData(): Closure
{
return function (array $data, $livewire): bool {
if (is_callable($this->beforeImportClosure)) {
call_user_func($this->beforeImportClosure, $data, $livewire, $this);
}
$importObject = new $this->importClass(
method_exists($livewire, 'getModel') ? $livewire->getModel() : null,
$this->importClassAttributes,
$this->additionalData
);

if(method_exists($importObject, 'setAdditionalData') && isset($this->additionalData)) {
$importObject->setAdditionalData($this->additionalData);
}

if(method_exists($importObject, 'setCustomImportData') && isset($this->customImportData)) {
$importObject->setCustomImportData($this->customImportData);
}

if(method_exists($importObject, 'setCollectionMethod') && isset($this->collectionMethod)) {
$importObject->setCollectionMethod($this->collectionMethod);
}

if(method_exists($importObject, 'setAfterValidationMutator' &&
(isset($this->afterValidationMutator) || $this->shouldRetainBeforeValidationMutation)
)){
$afterValidationMutator = $this->shouldRetainBeforeValidationMutation ?
$this->beforeValidationMutator :
$this->afterValidationMutator;
$importObject->setAfterValidationMutator($afterValidationMutator);
}

Excel::import($importObject, $data['upload']);

if (is_callable($this->afterImportClosure)) {
call_user_func($this->afterImportClosure, $data, $livewire);
}
return true;
};
}
}
80 changes: 80 additions & 0 deletions src/Concerns/HasSampleExcelFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace EightyNine\ExcelImport\Concerns;

use Closure;
use EightyNine\ExcelImport\SampleExcelExport;
use Filament\Forms\Components\Actions\Action;
use Maatwebsite\Excel\Facades\Excel;

trait HasSampleExcelFile
{
protected string $sampleFileName = 'sample.xlsx';
protected $defaultExportClass = SampleExcelExport::class;
protected ?array $sampleData = null;
protected ?string $sampleButtonLabel = null;
protected ?Closure $actionCustomisationClosure = null;

public function downloadSampleExcelFile()
{
return Excel::download(
new $this->defaultExportClass($this->sampleData),
$this->sampleFileName
);
}

public function setSampleFileName(string $name)
{
$this->sampleFileName = $name;
}

public function setDefaultExportClass(string $class)
{
$this->defaultExportClass = $class;
}

public function setSampleData(array $data)
{
if (count($data) > 0 && isset($data[0]) && is_array($data[0])) {
$this->sampleData = $data;
return;
} else {
$this->sampleData = [$data];
return;
}
}

public function setSampleButtonLabel(?string $label)
{
$this->sampleButtonLabel = $label;
}

protected function getSampleExcelButton()
{
$action = Action::make($this->sampleButtonLabel ?: __('excel-import::excel-import.download_sample_excel_file'))
->action(fn() => $this->downloadSampleExcelFile());
if (isset($this->actionCustomisationClosure)) {
return call_user_func($this->actionCustomisationClosure, $action);
}
return $action;
}

public function setActionCustomisationClosure(?Closure $customiseActionUsing){
$this->actionCustomisationClosure = $customiseActionUsing;
}

public function sampleExcel(
array $sampleData,
?string $fileName = null,
?string $exportClass = null,
?string $sampleButtonLabel = null,
?Closure $customiseActionUsing = null
): static {
$this->setSampleData($sampleData);
$this->setSampleFileName($fileName ?: $this->sampleFileName);
$this->setDefaultExportClass($exportClass ?: $this->defaultExportClass);
$this->setSampleButtonLabel($sampleButtonLabel ?: $this->sampleButtonLabel);
$this->setActionCustomisationClosure($customiseActionUsing);
return $this;
}
}
20 changes: 14 additions & 6 deletions src/Concerns/HasUploadForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Closure;
use EightyNine\ExcelImport\ValidationImport;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Field;
use Filament\Forms\Components\FileUpload;
use Maatwebsite\Excel\Facades\Excel;
Expand Down Expand Up @@ -115,7 +116,7 @@ public function visibility(string | Closure | null $visibility): static

protected function getUploadField()
{
return FileUpload::make('upload')
$fileUpload = FileUpload::make('upload')
->acceptedFileTypes($this->acceptedFileTypes)
->label(function ($livewire) {
if (!method_exists($livewire, 'getTable')) {
Expand All @@ -126,25 +127,32 @@ protected function getUploadField()
})
->default(1)
->storeFiles($this->storeFiles)
->disk(fn () => $this->disk ?: (config('excel-import.upload_disk') ?:
->disk(fn() => $this->disk ?: (config('excel-import.upload_disk') ?:
config('filesystems.default')))
->visibility($this->visibility)
->rules($this->validationRules())
->columns()
->required();

if (filled($this->sampleData)) {
$fileUpload->hintAction(
$this->getSampleExcelButton()
);
}
return $fileUpload;
}

public function validationRules(): array
{
$rules = [];
if($this->validate) {
$rules[] = fn (): Closure => function (string $attribute, $value, Closure $fail) {
if ($this->validate) {
$rules[] = fn(): Closure => function (string $attribute, $value, Closure $fail) {
Excel::import(
new ValidationImport(
$fail,
$fail,
$this->validationRules,
$this->beforeValidationMutator
),
),
$value
);
};
Expand Down
Loading

0 comments on commit 048155a

Please sign in to comment.