From 8ea45cad586a8f010f2e511c79591161db3bd7e1 Mon Sep 17 00:00:00 2001 From: salam Date: Fri, 13 Feb 2026 09:49:35 +0100 Subject: [PATCH] UserActivitiesTable --- .../Tables/UserActivitiesTable.php | 67 +++++++++++++++++- .../UserActivities/UserActivityResource.php | 14 ++-- app/Policies/UserActivityPolicy.php | 70 +++++++++++++++++++ composer.lock | 22 +++--- 4 files changed, 157 insertions(+), 16 deletions(-) create mode 100644 app/Policies/UserActivityPolicy.php diff --git a/app/Filament/Resources/UserActivities/Tables/UserActivitiesTable.php b/app/Filament/Resources/UserActivities/Tables/UserActivitiesTable.php index dc9f52f7..f9bd4bff 100644 --- a/app/Filament/Resources/UserActivities/Tables/UserActivitiesTable.php +++ b/app/Filament/Resources/UserActivities/Tables/UserActivitiesTable.php @@ -2,8 +2,17 @@ namespace App\Filament\Resources\UserActivities\Tables; +use App\Models\User; +use App\Models\UserActivity; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Toggle; use Filament\Tables\Columns\TextColumn; +use Filament\Tables\Enums\FiltersLayout; +use Filament\Tables\Filters\Filter; +use Filament\Tables\Filters\Indicator; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\DB; class UserActivitiesTable { @@ -18,8 +27,62 @@ class UserActivitiesTable TextColumn::make('created_at')->dateTime('M j, Y H:i'), ]) ->defaultSort('created_at', 'desc') + ->deferFilters(false) + ->hiddenFilterIndicators(false) + ->persistFiltersInSession() ->filters([ - // - ]); + Filter::make('created_at') + ->columns(2)->columnSpan(3) + ->schema([ + Toggle::make('user_latest') + ->onIcon('phosphor-user-fill') + ->offIcon('phosphor-user') + ->label('Logged User'), + Select::make(name: 'user_id') + ->hidden(fn () => auth()->user()->sport_id == 5) + ->placeholder('User') + ->prefixIcon('phosphor-user') + ->hiddenLabel() + ->label('') + ->multiple() + ->searchable() + ->preload() + ->options(function () { + $res = UserActivity::groupBy('user_id')->pluck('user_id')->toArray(); + + return User::query()->whereIn('id', $res)->orderBy('name')->pluck('name', 'id'); + }) + ->live(), + ]) + ->query(function (Builder $query, array $data): Builder { + return $query + ->when( + $data['user_latest'], + function (Builder $query) { + $res = UserActivity::query() + ->whereIn('id', function ($q) { + $q->select(DB::raw('MAX(id) FROM user_activities GROUP BY user_id')); + }) + ->pluck('id'); + $query->whereIn('id', $res); + } + ) + ->when( + $data['user_id'], + fn (Builder $query, $user_id): Builder => $query->where('user_id', $user_id)->orderBy('created_at', 'DESC'), + ); + })->indicateUsing(function (array $data): array { + $indicators = []; + if ($data['user_latest'] ?? null) { + $indicators[] = Indicator::make('User latest')->color('info'); + } + if ($data['user_id'] ?? null) { + $user = User::query()->whereIn('id', $data['user_id'])->value('name'); + $indicators[] = Indicator::make($user)->color('info'); + } + + return $indicators; + }), + ], layout: FiltersLayout::AboveContent); } } diff --git a/app/Filament/Resources/UserActivities/UserActivityResource.php b/app/Filament/Resources/UserActivities/UserActivityResource.php index cc827325..971d2740 100644 --- a/app/Filament/Resources/UserActivities/UserActivityResource.php +++ b/app/Filament/Resources/UserActivities/UserActivityResource.php @@ -7,10 +7,8 @@ use App\Filament\Resources\UserActivities\Pages\ListUserActivities; use App\Filament\Resources\UserActivities\Schemas\UserActivityForm; use App\Filament\Resources\UserActivities\Tables\UserActivitiesTable; use App\Models\UserActivity; -use BackedEnum; use Filament\Resources\Resource; use Filament\Schemas\Schema; -use Filament\Support\Icons\Heroicon; use Filament\Tables\Table; class UserActivityResource extends Resource @@ -23,7 +21,11 @@ class UserActivityResource extends Resource protected static string|\UnitEnum|null $navigationGroup = 'User'; - protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack; + protected static ?string $navigationLabel = 'Connected'; + + protected static ?string $modelLabel = ''; + + protected static string|\BackedEnum|null $navigationIcon = 'phosphor-users'; public static function form(Schema $schema): Schema { @@ -44,6 +46,10 @@ class UserActivityResource extends Resource public static function getNavigationBadge(): ?string { - return parent::getEloquentQuery()->count(); + return (string) UserActivity::query() + ->select('user_id', \DB::raw('count(*) as total')) + ->groupBy('user_id') + ->pluck('user_id') + ->first() ?? '0'; } } diff --git a/app/Policies/UserActivityPolicy.php b/app/Policies/UserActivityPolicy.php new file mode 100644 index 00000000..129716b5 --- /dev/null +++ b/app/Policies/UserActivityPolicy.php @@ -0,0 +1,70 @@ +can('ViewAny:UserActivity'); + } + + public function view(AuthUser $authUser, UserActivity $userActivity): bool + { + return $authUser->can('View:UserActivity'); + } + + public function create(AuthUser $authUser): bool + { + return $authUser->can('Create:UserActivity'); + } + + public function update(AuthUser $authUser, UserActivity $userActivity): bool + { + return $authUser->can('Update:UserActivity'); + } + + public function delete(AuthUser $authUser, UserActivity $userActivity): bool + { + return $authUser->can('Delete:UserActivity'); + } + + public function restore(AuthUser $authUser, UserActivity $userActivity): bool + { + return $authUser->can('Restore:UserActivity'); + } + + public function forceDelete(AuthUser $authUser, UserActivity $userActivity): bool + { + return $authUser->can('ForceDelete:UserActivity'); + } + + public function forceDeleteAny(AuthUser $authUser): bool + { + return $authUser->can('ForceDeleteAny:UserActivity'); + } + + public function restoreAny(AuthUser $authUser): bool + { + return $authUser->can('RestoreAny:UserActivity'); + } + + public function replicate(AuthUser $authUser, UserActivity $userActivity): bool + { + return $authUser->can('Replicate:UserActivity'); + } + + public function reorder(AuthUser $authUser): bool + { + return $authUser->can('Reorder:UserActivity'); + } + +} \ No newline at end of file diff --git a/composer.lock b/composer.lock index 42f42e98..1200f0d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4824,16 +4824,16 @@ }, { "name": "nette/utils", - "version": "v4.1.2", + "version": "v4.1.3", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "f76b5dc3d6c6d3043c8d937df2698515b99cbaf5" + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/f76b5dc3d6c6d3043c8d937df2698515b99cbaf5", - "reference": "f76b5dc3d6c6d3043c8d937df2698515b99cbaf5", + "url": "https://api.github.com/repos/nette/utils/zipball/bb3ea637e3d131d72acc033cfc2746ee893349fe", + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe", "shasum": "" }, "require": { @@ -4845,8 +4845,10 @@ }, "require-dev": { "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", "nette/tester": "^2.5", - "phpstan/phpstan": "^2.0@stable", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -4907,9 +4909,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.1.2" + "source": "https://github.com/nette/utils/tree/v4.1.3" }, - "time": "2026-02-03T17:21:09+00:00" + "time": "2026-02-13T03:05:33+00:00" }, { "name": "nikic/php-parser", @@ -13297,12 +13299,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.3" }, - "platform-dev": {}, - "plugin-api-version": "2.9.0" + "platform-dev": [], + "plugin-api-version": "2.6.0" }