-
-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(manage): add leaderboard management to game resources (#2576)
- Loading branch information
1 parent
3b79ccd
commit cb8a6b4
Showing
10 changed files
with
354 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 0 additions & 13 deletions
13
app/Filament/Resources/AchievementResource/Pages/Create.php
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
222 changes: 222 additions & 0 deletions
222
app/Filament/Resources/GameResource/RelationManagers/LeaderboardsRelationManager.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Filament\Resources\GameResource\RelationManagers; | ||
|
||
use App\Models\Game; | ||
use App\Models\Leaderboard; | ||
use App\Models\User; | ||
use App\Platform\Enums\ValueFormat; | ||
use Filament\Forms\Form; | ||
use Filament\Resources\RelationManagers\RelationManager; | ||
use Filament\Tables; | ||
use Filament\Tables\Actions\Action; | ||
use Filament\Tables\Table; | ||
use Illuminate\Database\Eloquent\Builder; | ||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Support\Facades\DB; | ||
|
||
class LeaderboardsRelationManager extends RelationManager | ||
{ | ||
protected static string $relationship = 'leaderboards'; | ||
|
||
public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool | ||
{ | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
return $user->can('manage', Leaderboard::class); | ||
} | ||
|
||
public function form(Form $form): Form | ||
{ | ||
return $form | ||
->schema([ | ||
|
||
]); | ||
} | ||
|
||
public function table(Table $table): Table | ||
{ | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
return $table | ||
->recordTitleAttribute('title') | ||
->columns([ | ||
Tables\Columns\TextColumn::make('ID') | ||
->label('ID') | ||
->searchable() | ||
->toggleable(), | ||
|
||
Tables\Columns\TextColumn::make('Title') | ||
->label('Title') | ||
->description(fn (Leaderboard $record): string => $record->description) | ||
->searchable(), | ||
|
||
Tables\Columns\TextColumn::make('Format') | ||
->label('Format') | ||
->formatStateUsing(fn (string $state) => ValueFormat::toString($state)) | ||
->toggleable(), | ||
|
||
Tables\Columns\TextColumn::make('entries_count') | ||
->label('Entries') | ||
->counts('entries') | ||
->numeric() | ||
->toggleable(), | ||
|
||
Tables\Columns\TextColumn::make('LowerIsBetter') | ||
->label('Lower Is Better') | ||
->toggleable(isToggledHiddenByDefault: true), | ||
|
||
Tables\Columns\TextColumn::make('DisplayOrder') | ||
->label('Display Order') | ||
->toggleable(isToggledHiddenByDefault: true), | ||
]) | ||
->searchPlaceholder('Search (ID, Title)') | ||
->filters([ | ||
|
||
]) | ||
->headerActions([ | ||
|
||
]) | ||
->actions([ | ||
Tables\Actions\ActionGroup::make([ | ||
Action::make('view_entries') | ||
->label('View entries') | ||
->url(fn (Leaderboard $leaderboard) => route('filament.admin.resources.leaderboards.view', ['record' => $leaderboard])) | ||
->visible(function (Leaderboard $leaderboard) { | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
return $user->can('manage', $leaderboard) && !$user->can('update', $leaderboard); | ||
}), | ||
|
||
Action::make('edit') | ||
->label('Edit') | ||
->icon('heroicon-s-pencil') | ||
->url(fn (Leaderboard $leaderboard) => route('filament.admin.resources.leaderboards.edit', ['record' => $leaderboard])) | ||
->visible(function (Leaderboard $leaderboard) { | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
return $user->can('update', $leaderboard); | ||
}), | ||
|
||
Action::make('reset_all_entries') | ||
->label('Delete All Entries') | ||
->icon('heroicon-s-trash') | ||
->color('danger') | ||
->requiresConfirmation() | ||
->modalDescription("Are you sure you want to permanently delete all entries of this leaderboard?") | ||
->action(function (Leaderboard $leaderboard) { | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
if (!$user->can('resetAllEntries', $leaderboard)) { | ||
return; | ||
} | ||
|
||
$leaderboard->entries()->delete(); | ||
|
||
activity() | ||
->useLog('default') | ||
->causedBy($user) | ||
->performedOn($leaderboard) | ||
->event('resetAllLeaderboardEntries') | ||
->log('Reset All Leaderboard Entries'); | ||
}) | ||
->visible(function (Leaderboard $leaderboard) { | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
return $user->can('resetAllEntries', $leaderboard); | ||
}), | ||
|
||
Action::make('delete_leaderboard') | ||
->label('Delete Leaderboard') | ||
->icon('heroicon-s-trash') | ||
->color('danger') | ||
->requiresConfirmation() | ||
->modalDescription("Are you sure you want to permanently delete this leaderboard?") | ||
->action(function (Leaderboard $leaderboard) { | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
// TODO use soft deletes | ||
if (!$user->can('forceDelete', $leaderboard)) { | ||
return; | ||
} | ||
|
||
$leaderboard->forceDelete(); | ||
}) | ||
->visible(function (Leaderboard $leaderboard) { | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
return $user->can('forceDelete', $leaderboard); | ||
}), | ||
]), | ||
]) | ||
->bulkActions([ | ||
|
||
]) | ||
->paginated([25, 50, 100]) | ||
->defaultSort(function (Builder $query): Builder { | ||
return $query | ||
->orderBy('DisplayOrder') | ||
->orderBy('Created', 'asc'); | ||
}) | ||
->reorderRecordsTriggerAction( | ||
fn (Action $action, bool $isReordering) => $action | ||
->button() | ||
->label($isReordering ? 'Stop reordering' : 'Start reordering'), | ||
) | ||
->reorderable('DisplayOrder', $this->canReorderLeaderboards()) | ||
->checkIfRecordIsSelectableUsing( | ||
fn (Model $record): bool => $user->can('update', $record->loadMissing('game')), | ||
); | ||
} | ||
|
||
public function reorderTable(array $order): void | ||
{ | ||
parent::reorderTable($order); | ||
|
||
/** @var User $user */ | ||
$user = auth()->user(); | ||
/** @var Game $game */ | ||
$game = $this->getOwnerRecord(); | ||
|
||
// We don't want to flood the logs with reordering activity. | ||
// We'll throttle these events by 10 minutes. | ||
$recentReorderingActivity = DB::table('audit_log') | ||
->where('causer_id', $user->id) | ||
->where('subject_id', $game->id) | ||
->where('subject_type', 'game') | ||
->where('event', 'reorderedLeaderboards') | ||
->where('created_at', '>=', now()->subMinutes(10)) | ||
->first(); | ||
|
||
// If the user didn't recently reorder leaderboards, write a new log. | ||
if (!$recentReorderingActivity) { | ||
activity() | ||
->useLog('default') | ||
->causedBy(auth()->user()) | ||
->performedOn($game) | ||
->event('reorderedLeaderboards') | ||
->log('Reordered Leaderboards'); | ||
} | ||
} | ||
|
||
private function canReorderLeaderboards(): bool | ||
{ | ||
/** @var User $user */ | ||
$user = auth()->user(); | ||
|
||
/** @var Leaderboard $game */ | ||
$game = $this->getOwnerRecord(); | ||
|
||
return $user->can('update', $game); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
app/Filament/Resources/LeaderboardResource/Pages/AuditLog.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
namespace App\Filament\Resources\LeaderboardResource\Pages; | ||
|
||
use App\Filament\Pages\ResourceAuditLog; | ||
use App\Filament\Resources\LeaderboardResource; | ||
|
||
class AuditLog extends ResourceAuditLog | ||
{ | ||
protected static string $resource = LeaderboardResource::class; | ||
} |
Oops, something went wrong.