22
33namespace App \Filament \Resources ;
44
5+ use App \Actions \MigrateBadJsonResults ;
6+ use App \Enums \ResultStatus ;
57use App \Exports \ResultsSelectedBulkExport ;
68use App \Filament \Resources \ResultResource \Pages ;
9+ use App \Helpers \Number ;
710use App \Helpers \TimeZoneHelper ;
811use App \Models \Result ;
12+ use App \Settings \DataMigrationSettings ;
913use App \Settings \GeneralSettings ;
1014use Carbon \Carbon ;
1115use Filament \Forms ;
1216use Filament \Forms \Components \TextInput ;
1317use Filament \Forms \Form ;
18+ use Filament \Notifications \Notification ;
1419use Filament \Resources \Resource ;
20+ use Filament \Support \Enums \Alignment ;
1521use Filament \Tables ;
1622use Filament \Tables \Actions \Action ;
17- use Filament \Tables \Columns \IconColumn ;
18- use Filament \Tables \Columns \TextColumn ;
1923use Filament \Tables \Table ;
2024use Illuminate \Database \Eloquent \Builder ;
2125use Illuminate \Database \Eloquent \Collection ;
26+ use Illuminate \Support \Facades \Auth ;
27+ use Illuminate \Support \HtmlString ;
2228use Maatwebsite \Excel \Facades \Excel ;
2329
2430class ResultResource extends Resource
@@ -52,17 +58,6 @@ public static function form(Form $form): Form
5258 $ component ->state (Carbon::parse ($ state )->format ($ settings ->time_format ?? 'M j, Y G:i:s ' ));
5359 })
5460 ->columnSpan (2 ),
55- Forms \Components \TextInput::make ('server_id ' )
56- ->label ('Server ID ' ),
57- Forms \Components \TextInput::make ('server_name ' )
58- ->label ('Server name ' )
59- ->columnSpan (2 ),
60- Forms \Components \TextInput::make ('server_host ' )
61- ->label ('Server host ' )
62- ->columnSpan ([
63- 'default ' => 2 ,
64- 'md ' => 3 ,
65- ]),
6661 Forms \Components \TextInput::make ('download ' )
6762 ->label ('Download (Mbps) ' )
6863 ->afterStateHydrated (function (TextInput $ component , $ state ) {
@@ -75,11 +70,26 @@ public static function form(Form $form): Form
7570 }),
7671 Forms \Components \TextInput::make ('ping ' )
7772 ->label ('Ping (Ms) ' ),
73+ Forms \Components \TextInput::make ('data.download.latency.jitter ' )
74+ ->label ('Download Jitter (Ms) ' ),
75+ Forms \Components \TextInput::make ('data.upload.latency.jitter ' )
76+ ->label ('Upload Jitter (Ms) ' ),
77+ Forms \Components \TextInput::make ('data.ping.jitter ' )
78+ ->label ('Ping Jitter (Ms) ' ),
7879 ])
7980 ->columnSpan (2 ),
8081 Forms \Components \Section::make ()
8182 ->schema ([
82- Forms \Components \Checkbox::make ('successful ' ),
83+ Forms \Components \Placeholder::make ('service ' )
84+ ->content (fn (Result $ result ): string => $ result ->service ),
85+ Forms \Components \Placeholder::make ('server_name ' )
86+ ->content (fn (Result $ result ): string => $ result ->server_name ),
87+ Forms \Components \Placeholder::make ('server_id ' )
88+ ->label ('Server ID ' )
89+ ->content (fn (Result $ result ): string => $ result ->server_id ),
90+ Forms \Components \Placeholder::make ('server_host ' )
91+ ->label ('Server ID ' )
92+ ->content (fn (Result $ result ): string => $ result ->server_id ),
8393 Forms \Components \Checkbox::make ('scheduled ' ),
8494 ])
8595 ->columns (1 )
@@ -88,65 +98,93 @@ public static function form(Form $form): Form
8898 'md ' => 1 ,
8999 ]),
90100 ]),
91- Forms \Components \Textarea::make ('data ' )
92- ->rows (10 )
93- ->columnSpan (2 ),
94101 ]);
95102 }
96103
97104 public static function table (Table $ table ): Table
98105 {
106+ $ dataSettings = new DataMigrationSettings ();
107+
99108 $ settings = new GeneralSettings ();
100109
101110 return $ table
102111 ->columns ([
103- TextColumn::make ('id ' )
112+ Tables \ Columns \ TextColumn::make ('id ' )
104113 ->label ('ID ' )
105114 ->sortable (),
106- TextColumn::make ('server ' )
107- ->getStateUsing ( fn ( Result $ record ): ? string => ! blank ( $ record -> server_id ) ? $ record -> server_id . ' ( ' . $ record -> server_name . ' ) ' : null )
115+ Tables \ Columns \ TextColumn::make ('ip_address ' )
116+ ->label ( ' IP address ' )
108117 ->toggleable ()
118+ ->toggledHiddenByDefault ()
109119 ->sortable (),
110- IconColumn::make ('successful ' )
111- ->boolean ()
112- ->toggleable (),
113- IconColumn::make ('scheduled ' )
114- ->boolean ()
115- ->toggleable (),
116- TextColumn::make ('download ' )
117- ->label ('Download (Mbps) ' )
118- ->getStateUsing (fn (Result $ record ): ?string => ! blank ($ record ->download ) ? toBits (convertSize ($ record ->download ), 2 ) : null )
120+ Tables \Columns \TextColumn::make ('service ' )
121+ ->toggleable ()
122+ ->toggledHiddenByDefault ()
123+ ->sortable (),
124+ Tables \Columns \TextColumn::make ('server_id ' )
125+ ->label ('Server ID ' )
126+ ->toggleable ()
127+ ->sortable (),
128+ Tables \Columns \TextColumn::make ('server_name ' )
129+ ->toggleable ()
130+ ->sortable (),
131+ Tables \Columns \TextColumn::make ('download ' )
132+ ->getStateUsing (fn (Result $ record ): ?string => ! blank ($ record ->download ) ? Number::fileSizeBits (bits: $ record ->download , precision: 2 , perSecond: true ) : null )
119133 ->sortable (),
120- TextColumn::make ('upload ' )
121- ->label ('Upload (Mbps) ' )
122- ->getStateUsing (fn (Result $ record ): ?string => ! blank ($ record ->upload ) ? toBits (convertSize ($ record ->upload ), 2 ) : null )
134+ Tables \Columns \TextColumn::make ('upload ' )
135+ ->getStateUsing (fn (Result $ record ): ?string => ! blank ($ record ->upload ) ? Number::fileSizeBits (bits: $ record ->upload , precision: 2 , perSecond: true ) : null )
123136 ->sortable (),
124- TextColumn::make ('ping ' )
125- ->label ('Ping (Ms) ' )
137+ Tables \Columns \TextColumn::make ('ping ' )
126138 ->toggleable ()
127139 ->sortable (),
128- TextColumn::make ('download_jitter ' )
129- ->getStateUsing (fn (Result $ record ): ?string => json_decode ($ record ->data , true )['download ' ]['latency ' ]['jitter ' ] ?? null )
140+ Tables \Columns \TextColumn::make ('download_jitter ' )
130141 ->toggleable ()
131142 ->toggledHiddenByDefault ()
132143 ->sortable (),
133- TextColumn::make ('upload_jitter ' )
134- ->getStateUsing (fn (Result $ record ): ?string => json_decode ($ record ->data , true )['upload ' ]['latency ' ]['jitter ' ] ?? null )
144+ Tables \Columns \TextColumn::make ('upload_jitter ' )
135145 ->toggleable ()
136146 ->toggledHiddenByDefault ()
137147 ->sortable (),
138- TextColumn::make ('ping_jitter ' )
139- ->getStateUsing (fn (Result $ record ): ?string => json_decode ($ record ->data , true )['ping ' ]['jitter ' ] ?? null )
148+ Tables \Columns \TextColumn::make ('ping_jitter ' )
140149 ->toggleable ()
141150 ->toggledHiddenByDefault ()
142151 ->sortable (),
143- TextColumn::make ('created_at ' )
144- ->label ('Created ' )
152+ Tables \Columns \TextColumn::make ('status ' )
153+ ->toggleable ()
154+ ->sortable (),
155+ Tables \Columns \IconColumn::make ('scheduled ' )
156+ ->boolean ()
157+ ->toggleable ()
158+ ->toggledHiddenByDefault ()
159+ ->alignment (Alignment::Center),
160+ Tables \Columns \TextColumn::make ('created_at ' )
145161 ->dateTime ($ settings ->time_format ?? 'M j, Y G:i:s ' )
146162 ->timezone (TimeZoneHelper::displayTimeZone ($ settings ))
147- ->sortable (),
163+ ->sortable ()
164+ ->alignment (Alignment::End),
165+ Tables \Columns \TextColumn::make ('updated_at ' )
166+ ->dateTime ($ settings ->time_format ?? 'M j, Y G:i:s ' )
167+ ->timezone (TimeZoneHelper::displayTimeZone ($ settings ))
168+ ->toggleable ()
169+ ->toggledHiddenByDefault ()
170+ ->sortable ()
171+ ->alignment (Alignment::End),
148172 ])
149173 ->filters ([
174+ Tables \Filters \SelectFilter::make ('ip_address ' )
175+ ->label ('IP address ' )
176+ ->multiple ()
177+ ->options (function (): array {
178+ return Result::query ()
179+ ->select ('data->interface->externalIp AS public_ip_address ' )
180+ ->distinct ()
181+ ->get ()
182+ ->mapWithKeys (function (Result $ item , int $ key ) {
183+ return [$ item ['public_ip_address ' ] => $ item ['public_ip_address ' ]];
184+ })
185+ ->toArray ();
186+ })
187+ ->attribute ('data->interface->externalIp ' ),
150188 Tables \Filters \TernaryFilter::make ('scheduled ' )
151189 ->placeholder ('- ' )
152190 ->trueLabel ('Only scheduled speedtests ' )
@@ -156,23 +194,17 @@ public static function table(Table $table): Table
156194 false: fn (Builder $ query ) => $ query ->where ('scheduled ' , false ),
157195 blank: fn (Builder $ query ) => $ query ,
158196 ),
159- Tables \Filters \TernaryFilter::make ('successful ' )
160- ->placeholder ('- ' )
161- ->trueLabel ('Only successful speedtests ' )
162- ->falseLabel ('Only failed speedtests ' )
163- ->queries (
164- true: fn (Builder $ query ) => $ query ->where ('successful ' , true ),
165- false: fn (Builder $ query ) => $ query ->where ('successful ' , false ),
166- blank: fn (Builder $ query ) => $ query ,
167- ),
197+ Tables \Filters \SelectFilter::make ('status ' )
198+ ->multiple ()
199+ ->options (ResultStatus::class),
168200 ])
169201 ->actions ([
170202 Tables \Actions \ActionGroup::make ([
171203 Action::make ('view result ' )
172204 ->label ('View on Speedtest.net ' )
173205 ->icon ('heroicon-o-link ' )
174- ->url (fn (Result $ record ): ?string => $ record?->url )
175- ->hidden (fn (Result $ record ): bool => ! $ record ->is_successful )
206+ ->url (fn (Result $ record ): ?string => $ record-> result_url )
207+ ->hidden (fn (Result $ record ): bool => $ record ->status !== ResultStatus::Completed )
176208 ->openUrlInNewTab (),
177209 Tables \Actions \ViewAction::make (),
178210 Tables \Actions \Action::make ('updateComments ' )
@@ -206,14 +238,26 @@ public static function table(Table $table): Table
206238 }),
207239 Tables \Actions \DeleteBulkAction::make (),
208240 ])
209- ->defaultSort ('created_at ' , 'desc ' );
210- }
241+ ->headerActions ([
242+ Tables \Actions \Action::make ('migrate ' )
243+ ->action (function (): void {
244+ Notification::make ()
245+ ->title ('Starting data migration... ' )
246+ ->body ('This can take a little bit depending how much data you have. ' )
247+ ->warning ()
248+ ->sendToDatabase (Auth::user ());
211249
212- public static function getRelations (): array
213- {
214- return [
215- //
216- ];
250+ MigrateBadJsonResults::dispatch (Auth::user ());
251+ })
252+ ->hidden ($ dataSettings ->bad_json_migrated )
253+ ->requiresConfirmation ()
254+ ->modalHeading ('Migrate History ' )
255+ ->modalDescription (new HtmlString ('<p>v0.16.0 archived the old <code>"results"</code> table, to migrate your history click the button below.</p><p>For more information read the <a href="#" target="_blank" rel="nofollow" class="underline">docs</a>.</p> ' ))
256+ ->modalSubmitActionLabel ('Yes, migrate it ' ),
257+ ])
258+ ->defaultSort ('created_at ' , 'desc ' )
259+ ->paginated ([5 , 15 , 25 , 50 , 100 ])
260+ ->defaultPaginationPageOption (15 );
217261 }
218262
219263 public static function getPages (): array
0 commit comments