namespace App\Support;
use Illuminate\Database\Eloquent\Model;
use Visualbuilder\ExportScheduler\Contracts\BypassesReportVisibility;
class ReportAdmins implements BypassesReportVisibility
{
public function can(?Model $user): bool
{
return $user?->hasRole('Report Admin') ?? false;
}
}
use Illuminate\Database\Eloquent\Model;
use Visualbuilder\ExportScheduler\Contracts\HasLinkedColumns;
class OrderExporter extends Exporter implements HasLinkedColumns
{
public static function getColumns(): array
{
return [
ExportColumn::make('id')->label('Order ID'),
ExportColumn::make('user.name')->label('End User'),
];
}
public static function getColumnLinks(): array
{
return [
'id' => fn (Order $order) => OrderResource::getUrl('view', ['record' => $order]),
'user.name' => fn (Order $order) => $order->user
? UserResource::getUrl('view', ['record' => $order->user])
: null,
];
}
}
'dynamic_recipients' => true, // brings the fields back into the schedule form
use Illuminate\Support\Facades\Schedule;
Schedule::command('export:run')->everyMinute();
use Filament\Pages\Enums\SubNavigationPosition;
use Filament\Support\Enums\Width;
use Visualbuilder\ExportScheduler\Filament\Resources\CustomReportResource;
use Visualbuilder\ExportScheduler\Mail\ExportReady;
use Visualbuilder\ExportScheduler\Notifications\ScheduledExportCompleteNotification;
use Visualbuilder\ExportScheduler\Support\ReportUserResolver;
use Visualbuilder\ExportScheduler\Support\VisibilityBypass;
return [
/**
* Filament resources to register. Subclass the resource and swap it in here
* to customise its forms, tables or pages.
*/
'resources' => [
CustomReportResource::class,
],
/**
* The success Notification and Mailable to use
*/
'notification' => ScheduledExportCompleteNotification::class,
'mailable' => ExportReady::class,
/**
* Allow users to choose from Exporters in these directories
*/
'exporter_directories' => [
'App\Filament\Exporters',
],
/**
* Where the exports should be stored, local or s3
*/
'file_disk' => 'local',
/**
* The report viewer loads the whole result set so it can search and sort
* across every page, including columns that are not database columns. Set a
* number here to cap how many rows are loaded on very large reports. Null
* loads all of them. The export itself is never capped.
*/
'viewer_max_rows' => null,
/**
* Roles allowed to create SQL query reports. Uses Spatie Permission's
* hasRole(). Set to an empty array to allow all users.
*/
'sql_query_roles' => ['Developer'],
/**
* Admin Panel Navigation
*/
'navigation' => [
'enabled' => true,
'sort' => 100,
'label' => 'Custom Report',
'plural_label' => 'Custom Reports',
'icon' => 'heroicon-o-document-chart-bar',
'group' => 'Reports',
'cluster' => false,
'position' => SubNavigationPosition::Top,
/**
* Width of the create, edit and delete modals in the schedules
* relation manager. The schedule form is wide - frequency,
* recipient, cc and overrides - so it needs more room than a
* Filament default.
*/
'modal_width' => Width::FiveExtraLarge,
],
],
/**
* How the package reads a user's id, display label and email address.
*
* Bind your own implementation of ResolvesReportUsers here if the per-model
* attributes below are not enough.
*/
'user_resolver' => ReportUserResolver::class,
/**
* Which users may see, edit, delete and run every report and schedule,
* regardless of who owns them.
*
* The default grants this to nobody. Bind your own implementation of
* BypassesReportVisibility to open it up to admins.
*/
'visibility_bypass' => VisibilityBypass::class,
/**
* Automatic Recipients - reruns a report once per user found in the data and
* sends each of them only their own rows.
*
* Hidden from the schedule form by default. Schedules that already have it
* enabled keep fanning out regardless of this flag; it only governs whether
* the fields can be reached in the UI.
*/
'dynamic_recipients' => false,
/**
* Which authenticatable models may receive exports, and be given visibility
* of a report.
*
* Only `model` is
use Visualbuilder\ExportScheduler\ExportSchedulerPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->default()
->plugins([
ExportSchedulerPlugin::make(),
]);
}
use Visualbuilder\ExportScheduler\Contracts\HasExportReportIdentity;
class Contact extends Model implements HasExportReportIdentity
{
public function getExportReportLabel(): string
{
return "{$this->last_name}, {$this->first_name}";
}
public function getExportReportEmail(): ?string
{
return $this->work_email ?? $this->personal_email;
}
}
// In a service provider
$this->app->bind(
\Visualbuilder\ExportScheduler\Contracts\ResolvesReportUsers::class,
\App\Services\CustomReportUserResolver::class,
);
use Visualbuilder\ExportScheduler\Traits\InteractsWithExportSchedulerFilter;
class Organisation extends Model
{
use InteractsWithExportSchedulerFilter;
protected $filterOptionLabel = 'name';
}
use Visualbuilder\ExportScheduler\Services\ScheduledExporter;
// Scheduled delivery
(new ScheduledExporter($report, $schedule))->run();
// Ad hoc: no schedule, no recipient list, the result goes to the requester
(new ScheduledExporter($report))->run();