edwink75 / filament-user-activity

Track user activity and show currently active users
MIT License
13 stars 5 forks source link

[Bug]: table only updates on hard refresh #11

Open rimoomey opened 1 month ago

rimoomey commented 1 month ago

What happened?

I cannot currently filter the table dynamically, as the table only correctly updates on page refresh when applying a new filter.

How to reproduce the bug

  1. Log in as a user with permission to view the ActiveUsers page and go to that page.
  2. Verify that you have a user whose latest activity was outside the range of at least one filter.
  3. Switch from a filter that applies to that user to one that filters them out.
  4. Verify that the filtered out user is still in the table, potentially without values in the other displayed columns.

Package Version

1.0.9

PHP Version

8.3

Laravel Version

11.7.0

Which operating systems does with happen with?

Linux

Notes

Issue Demo

https://github.com/edwink75/filament-user-activity/assets/45639947/4d8dab68-1f7e-4cf1-a18e-de1e910c689a

Additional Context

There was a refresh before the page (1) filter value was switched from '30 minutes' to 'Week' and updated to show the new user in the list and (2) before the new user was removed when the filter value was switched from 'Week' to '24 hours'.

rimoomey commented 1 month ago

I don't know if this is helpful, but when I messed with your source files, I was able to fix the problem by converting your form into a Filter field like this. It necessarily involved getting rid of the nice form display you have, but it fixes the issue of live updates not happening. I'm not exactly a Livewire expert, but it seemed like the table wasn't really able to react to changes in the form before a refresh.

<?php

namespace Edwink\FilamentUserActivity\Livewire;

use Carbon\Carbon;
use Filament\Forms\Components\Select;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Livewire\Attributes\Url;
use Livewire\Component;

class ActiveUsersTable extends Component implements HasForms, HasTable
{
    use InteractsWithForms;
    use InteractsWithTable;

    #[Url]
    public int $minutes = 30;

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                Select::make('minutes')
                    ->options(config('filament-user-activity.table.active-users.timeframe-selection'))
                    ->label('Active in last ')
                    ->reactive(),
            ]);
    }

    public function table(Table $table): Table
    {
        return $table
            ->query(
                config('filament-user-activity.model')::whereHas('activities', function ($query) {
                    $query->where('created_at', '>', Carbon::now()->subMinutes($this->minutes)->format('Y-m-d H:i:s'));
                })
                    ->with('activities', function ($query) {
                        $query->where('created_at', '>', Carbon::now()->subMinutes($this->minutes)->format('Y-m-d H:i:s'));
                    })
            )
            ->columns([
                // TextColumn::make('id'),
                TextColumn::make('name'),
                TextColumn::make('activities.created_at')
                    ->formatStateUsing(function ($state) {
                        $timestamp = max(explode(', ', $state));

                        return Carbon::create($timestamp)->diffForHumans();
                    })->label(__('filament-user-activity::user-activity.active-users-table.column.last_action_time')),

                TextColumn::make('activities.url')
                    ->formatStateUsing(function ($state) {
                        return count(explode(', ', $state));
                    })->label(__('filament-user-activity::user-activity.active-users-table.column.last_action_count')),

            ])
            ->filters([
                // ...
            ])
            ->actions([
                // ...
            ])
            ->bulkActions([
                // ...
            ])
            ->paginationPageOptions([50, 100]);
    }

    public function render()
    {
        return view('filament-user-activity::livewire.active-users-table');
    }
}