diff --git a/app/Filament/Exports/ResultExporter.php b/app/Filament/Exports/ResultExporter.php index ff4438586..15ff08118 100644 --- a/app/Filament/Exports/ResultExporter.php +++ b/app/Filament/Exports/ResultExporter.php @@ -21,136 +21,59 @@ public function getFormats(): array public static function getColumns(): array { - return [ - ExportColumn::make('id') - ->label('ID'), - ExportColumn::make('ip_address') - ->label('IP address') - ->state(function (Result $record): ?string { - return $record->ip_address; - }) - ->enabledByDefault(false), - ExportColumn::make('isp') - ->label('ISP') - ->state(function (Result $record): ?string { - return $record->isp; - }) - ->enabledByDefault(false), - ExportColumn::make('server_location') - ->label('Server Location') - ->state(function (Result $record): ?string { - return $record->server_location; - }) - ->enabledByDefault(false), - ExportColumn::make('service') - ->state(function (Result $record) { - return $record->service->getLabel(); - }), - ExportColumn::make('server_id') - ->label('Server ID') - ->state(function (Result $record): ?string { - return $record->server_id; - }) - ->enabledByDefault(false), - ExportColumn::make('server_name') - ->state(function (Result $record): ?string { - return $record->server_name; - }) - ->enabledByDefault(false), - - ExportColumn::make('download') - ->state(function (Result $record): ?string { - return $record->download_bits; - }), - ExportColumn::make('upload') - ->state(function (Result $record): ?string { - return $record->upload_bits; - }), - ExportColumn::make('ping'), - ExportColumn::make('packet_loss'), - ExportColumn::make('download_jitter') - ->state(function (Result $record): ?string { - return $record->download_jitter; - }) - ->enabledByDefault(false), - ExportColumn::make('upload_jitter') - ->state(function (Result $record): ?string { - return $record->upload_jitter; - }) - ->enabledByDefault(false), - ExportColumn::make('ping_jitter') - ->state(function (Result $record): ?string { - return $record->ping_jitter; - }) - ->enabledByDefault(false), - ExportColumn::make('ping_low') - ->state(function (Result $record): ?string { - return $record->ping_low; - }) - ->enabledByDefault(false), - ExportColumn::make('ping_high') - ->state(function (Result $record): ?string { - return $record->ping_high; - }) - ->enabledByDefault(false), - ExportColumn::make('upload_latency_high') - ->state(function (Result $record): ?string { - return $record->upload_latency_high; - }) - ->enabledByDefault(false), - ExportColumn::make('upload_latency_low') - ->state(function (Result $record): ?string { - return $record->upload_latency_low; - }) - ->enabledByDefault(false), - ExportColumn::make('upload_latency_avg') - ->state(function (Result $record): ?string { - return $record->upload_latency_iqm; - }) - ->enabledByDefault(false), - ExportColumn::make('download_latency_high') - ->state(function (Result $record): ?string { - return $record->download_latency_high; - }) - ->enabledByDefault(false), - ExportColumn::make('download_latency_low') - ->state(function (Result $record): ?string { - return $record->download_latency_low; - }) - ->enabledByDefault(false), - ExportColumn::make('download_latency_avg') - ->state(function (Result $record): ?string { - return $record->download_latency_iqm; - }) - ->enabledByDefault(false), - ExportColumn::make('result_url') - ->state(function (Result $record) { - return $record->result_url; - }), - ExportColumn::make('error_message') - ->state(function (Result $record) { - return $record->error_message; - }) - ->enabledByDefault(false), - ExportColumn::make('comments') - ->enabledByDefault(false), - ExportColumn::make('status') - ->state(function (Result $record) { - return $record->status->getLabel(); - }), - ExportColumn::make('scheduled') - ->state(function (Result $record): string { - return $record->scheduled ? 'Yes' : 'No'; - }), - ExportColumn::make('healthy') - ->state(function (Result $record): string { - return $record->healthy ? 'Yes' : 'No'; - }) - ->enabledByDefault(false), + $columns = [ + ExportColumn::make('id')->label('ID'), + ExportColumn::make('service')->state(fn (Result $r) => $r->service->getLabel()), + ExportColumn::make('status')->state(fn (Result $r) => $r->status->getLabel()), + ExportColumn::make('scheduled')->state(fn (Result $r) => $r->scheduled ? 'Yes' : 'No'), + ExportColumn::make('healthy')->state(fn (Result $r) => $r->healthy ? 'Yes' : 'No'), ExportColumn::make('created_at'), - ExportColumn::make('updated_at') - ->enabledByDefault(false), + ExportColumn::make('updated_at'), + ExportColumn::make('comments'), ]; + + $columns = array_merge($columns, self::generateDataColumns()); + + return $columns; + } + + protected static function generateDataColumns(): array + { + + $sample = Result::query()->whereNotNull('data')->first()?->data ?? []; + + $flattened = self::flatten($sample); + + $columns = []; + + foreach ($flattened as $key => $default) { + $columns[] = ExportColumn::make($key) + ->label(str_replace('_', ' ', ucfirst($key))) + ->state(function (Result $r) use ($key) { + $flattened = self::flatten($r->data ?? []); + + return $flattened[$key] ?? null; + }); + } + + return $columns; + } + + protected static function flatten(array $array, string $prefix = ''): array + { + $result = []; + + foreach ($array as $key => $value) { + $newKey = $prefix ? "{$prefix}_{$key}" : $key; + + if (is_array($value)) { + $result += self::flatten($value, $newKey); + } else { + $result[$newKey] = $value; + } + } + + return $result; } public static function getCompletedNotificationBody(Export $export): string diff --git a/app/Filament/Resources/ResultResource.php b/app/Filament/Resources/ResultResource.php index 7990202a5..6197d0b67 100644 --- a/app/Filament/Resources/ResultResource.php +++ b/app/Filament/Resources/ResultResource.php @@ -464,6 +464,9 @@ public static function table(Table $table): Table ->headerActions([ ExportAction::make() ->exporter(ResultExporter::class) + ->columnMapping(false) + ->modalHeading('Export all Results') + ->modalDescription('This will export all columns for all results.') ->fileName(fn (): string => 'results-'.now()->timestamp), ActionGroup::make([ Action::make('truncate')