cheesegrits / filament-google-maps

Google Maps package for Filament PHP
246 stars 68 forks source link

MapTableWidget not reacting to Table Radius Filter - Flickers and re-centers #95

Open chrisscalzo opened 7 months ago

chrisscalzo commented 7 months ago

maptablewidget-radius-bug-animated

The MapTableWidget isn't reacting to the Location Radius Filter in the table. I have been able to reproduce this issue in both the Location Resource from the test project repository < https://github.com/cheesegrits/fgm > and when I implement the MapTableWidget in my personal project.

Steps to Reproduce

1) Implement the MapTableWidget following the documentation - or download and install the test project 2) When using the MapTableWidget set the following properties:

class LocationMapTableWidget extends MapTableWidget { protected static ?string $heading = 'Location Map';

protected static ?int $sort = 1;

protected static ?string $pollingInterval = null;

protected static ?bool $clustering = true;

protected static ?bool $fitToBounds = true;

protected static ?string $mapId = 'incidents';

protected static ?bool $filtered = true;

protected static bool $collapsible = true;

public ?bool $mapIsFilter = true

3) When the page is rendered it appears fine, the map shows locations for the records in the table.

4) Attempt to filter the table using the address of the first record that appears in the table. The table doesn't react and stays the same. The map flickers then recenters to a default location.

5) You can't reset the filter you need to refresh the entire web page to get back to the default state when the page first loads.

ryanmortier commented 2 months ago

Same issue, you figure out the solution?

chrisscalzo commented 2 months ago

Same issue, you figure out the solution?

Not yet, but will be trying next week as I will need mapping capabilities in the next app I'm building.

ryanmortier commented 2 months ago

I ended up figuring it out partially. I had to override the filter with my own class and add the ->updateLatLng() method onto the Geocomplete field. It still flickers and makes several round trips to the server, but it works.

<?php

namespace App\Filters;

use Cheesegrits\FilamentGoogleMaps\Fields\Geocomplete;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\Hidden;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;

class RadiusFilter extends \Cheesegrits\FilamentGoogleMaps\Filters\RadiusFilter
{
    public function getFormSchema(): array
    {
        $form = [
            Group::make()->schema([
                Geocomplete::make('geocomplete')
                    ->label(__('filament-google-maps::fgm.radius_filter.address'))
                    ->filterName($this->getName())
                    ->updateLatLng()
                    ->lazy(),
                Group::make()->schema([
                    TextInput::make('radius')
                        ->label(__('filament-google-maps::fgm.radius_filter.distance'))
                        ->numeric()
                        ->default($this->getRadius() ?? 10)
                        ->lazy(),
                    Select::make('unit')
                        ->label(__('filament-google-maps::fgm.radius_filter.unit'))
                        ->options([
                            'mi' => __('filament-google-maps::fgm.radius_filter.miles'),
                            'km' => __('filament-google-maps::fgm.radius_filter.kilometers'),
                        ])
                        ->default(
                            $this->getKilometers() ? 'km' : 'mi'
                        )
                        ->visible(fn () => $this->getSelectUnit()),
                ])
                    ->columns($this->getSelectUnit() ? 2 : 1),
                Group::make()->schema([
                    Hidden::make('latitude'),
                    Hidden::make('longitude'),
                ]),
            ])
                ->columnSpan('full'),
        ];

        if ($this->hasSection()) {
            $form = [
                Fieldset::make($this->getSection())->schema($form),
            ];
        }

        return $form;
    }

    private function hasSection(): bool
    {
        return ! empty($this->getSection());
    }
}