Filament 3 - Display doesn't change when there is new data using RepeatableEntry in tab

Filament 3 - Display doesn't change when there is new data using RepeatableEntry in tab

I have an infolist with RepeatableEntry inside the tabs. When adding data for RepeatableEntry, the data that has been created can't appear in RepeatableEntry, unless there is a trigger to add the data again.

Here are some test examples, for recommendations in RepeatableEntry it doesn't work properly, but for quotations in RepeatableEntry it works properly.

How to fix this issue?

When adding data for recommendation and waiting for a long time there is no change in the display : Read more

When adding data for recommendation and trigger add new data again, previously created data can appear : https://gifyu.com/image/bpPfl

When adding data for quotation no need to wait, the data that has been created will immediately appear : https://gifyu.com/image/bpPfc

Here is the code :

Task Model :

class Task extends Model
{
    use SoftDeletes;
    use HasHashid, HashidRouting;

    protected $table = 'tasks';

    protected $appends = ['hashid'];

    public function recommendations(): HasMany
    {
        return $this->hasMany(TaskRecommendation::class);
    }

    public function quotations(): HasMany
    {
        return $this->hasMany(TaskQuotation::class);
    }
}

infolist :

class DetailTaskForSite extends Page implements HasInfolists 
{
    use InteractsWithRecord;

    public function mount(int | string $record): void
    {
        $this->record = $this->resolveRecord($record);
    }

    public function infolist(Infolist $infolist): Infolist
    {
        return $infolist
            ->record(
                $this->record
                    ->load([
                        'recommendations',
                        'recommendations.target',
                        'recommendations.target.province',
                        'recommendations.target.city',
                        'recommendations.action',
                        'quotations',
                        'quotations.action',
                        'materials',
                        'materials.material',
                        'materials.communication',
                        'targets',
                        'targets.target',
                        'targets.communication',
                        'targets.product',
                        'targets.material',
                    ])
            )
            ->schema([
                SimpleAlert::make('info')
                    ->title(function() {
                        $flow = $this->record
                                    ->flows()
                                    ->where('task_status_id', 2)
                                    ->first();

                        return ($this->record->task_status_id == 2 && $flow) ? $flow->flow_general->name : $this->record->status->name;
                    })
                    ->info(),
                TextEntry::make('description'),
                Tabs::make('Tabs')
                    ->tabs([
                        Tabs\Tab::make('recommendations')
                            ->label('Recommendations')
                            ->icon('heroicon-m-star')
                            ->iconPosition(IconPosition::After)
                            ->schema([
                                RepeatableEntry::make('recommendations')
                                    ->schema([
                                        TextEntry::make('target.name')
                                            ->label('Site')
                                            ->columnSpan([
                                                'sm' => 1,
                                                'md' => 2,
                                            ]),
                                        TextEntry::make('target.province.name')
                                            ->label('Province'),
                                        TextEntry::make('target.city.name')
                                            ->label('City'),
                                        TextEntry::make('target.address')
                                            ->label('Address')
                                            ->columnSpan([
                                                'sm' => 1,
                                                'md' => 2,
                                            ]),
                                        TextEntry::make('action.name')
                                            ->label('Status')
                                            ->columnSpan(2),
                                        Actions::make([
                                                Action::make('delete')
                                                    ->iconButton()
                                                    ->label('Delete Recommendation')
                                                    ->toolTip('Delete Recommendation')
                                                    ->icon('heroicon-m-x-mark')
                                                    ->color('danger')
                                                    ->visible(function($record) {
                                                        if ( $this->record->task_status_id != 2 ) {
                                                            return false;
                                                        } else {
                                                            if ( $record->task_action_id != 1 ) {
                                                                return false;
                                                            }

                                                            $flow = $this->record
                                                                            ->flows()
                                                                            ->where('task_status_id', 2)
                                                                            ->first();

                                                            if ( $flow ) {
                                                                $flow_general = $flow->flow_general;
                                                                $options = json_decode($flow_general->options, true);
                                                                $participant = $options['participant'];
                                                                $status_default = $options['status_default'];

                                                                return ( $status_default == 'recommendation' && Auth::user()->hasRole($participant['access']) ) ? true : false;
                                                            } else {
                                                                return false;
                                                            }
                                                        }
                                                    })
                                                    ->requiresConfirmation()
                                                    ->action(function ($record) {
                                                        $delete_recommendation = $record->delete();

                                                        Notification::make()
                                                            ->title('Saved successfully')
                                                            ->success()
                                                            ->send();

                                                        return $delete_recommendation;
                                                    }),
                                            ]),
                                    ])
                                    ->hiddenLabel()
                                    ->grid(2)
                                    ->columns([
                                        'sm' => 1, 
                                        'md' => 2
                                    ]),
                                Actions::make([
                                        Action::make('add_recommendation')
                                            ->label('Add Recommendation')
                                            ->icon('heroicon-m-plus')
                                            ->visible(function() {
                                                if ( $this->record->task_status_id != 2 ) {
                                                    return false;
                                                } else {
                                                    $flow = $this->record
                                                                ->flows()
                                                                ->where('task_status_id', 2)
                                                                ->first();
                                                    
                                                    if ( $flow ) {
                                                        $flow_general = $flow->flow_general;
                                                        $options = json_decode($flow_general->options, true);
                                                        $participant = $options['participant'];
                                                        $status_default = $options['status_default'];

                                                        return ( $status_default == 'recommendation' && Auth::user()->hasRole($participant['access']) ) ? true : false;
                                                    } else {
                                                        return false;
                                                    }
                                                }
                                            })
                                            ->form([
                                                Forms\Components\Select::make('target_id')
                                                    ->label('Site')
                                                    ->options(function(Get $get) {
                                                        $data = Target::query()
                                                                    ->where('agency_id', session('agency')->id)
                                                                    ->where('brand_id', session('brand')->id)
                                                                    ->where('distribution_id', 2)
                                                                    ->whereNotIn('id', $this->record->recommendations->pluck('target_id')->all())
                                                                    ->whereNotNull('vendor_id')
                                                                    ->get();

                                                        $options = [];
                                                        if ( $data->count() > 0 ) {
                                                            foreach ($data as $key => $value) {
                                                                $options[ $value->id ] = $value->name . ' (' . $value->city->name . ')';
                                                            }
                                                        }
                                                        return $options;
                                                    })
                                                    ->searchable()
                                                    ->required()
                                                    ->disableOptionsWhenSelectedInSiblingRepeaterItems(),
                                            ])
                                            ->action(function(array $data) {
                                                $create = $this->record->recommendations()->create([
                                                                    'target_id' => $data['target_id'],
                                                                    'task_action_id' => 1, // pending
                                                                ]);

                                                Notification::make()
                                                    ->title('Saved successfully')
                                                    ->success()
                                                    ->send();

                                                return $create;
                                            }),
                                        Action::make('done_recommendation')
                                            ->label('Next to Client Approval')
                                            ->icon('heroicon-m-arrow-right-circle')
                                            ->visible(function() {
                                                if ( $this->record->task_status_id != 2 ) {
                                                    return false;
                                                } else {
                                                    $recommendations = $this->record->recommendations->count();
                                                    
                                                    if ( $recommendations == 0 ) {
                                                        return false;
                                                    }

                                                    $flow = $this->record
                                                                ->flows()
                                                                ->where('task_status_id', 2)
                                                                ->first();
                                                    
                                                    if ( $flow ) {
                                                        $flow_general = $flow->flow_general;
                                                        $options = json_decode($flow_general->options, true);
                                                        $participant = $options['participant'];
                                                        $status_default = $options['status_default'];

                                                        return ( $status_default == 'recommendation' && Auth::user()->hasRole($participant['access']) ) ? true : false;
                                                    } else {
                                                        return false;
                                                    }
                                                }
                                            })
                                            ->requiresConfirmation()
                                            ->action(function(array $data) {

                                                $this->updateCurrentFlow();

                                                Notification::make()
                                                    ->title('Saved successfully')
                                                    ->success()
                                                    ->send();

                                                $brand_users = BrandUser::query()
                                                                    ->with([
                                                                        'brand',
                                                                        'user',
                                                                    ])
                                                                    ->where('brand_id', session('brand')->id)
                                                                    ->get();

                                                if ( $brand_users->count() > 0 ) {
                                                    foreach ($brand_users as $key => $value) {
                                                        $link = route('filament.client.resources.site-tasks.detail', ['record' => $this->record->hashid]);

                                                        Notification::make()
                                                            ->title( session('agency')->name . ' has sent a recommendations on the task')
                                                            ->body('<a href="' . $link . '">For additional details, please click here</a>.')
                                                            ->info()
                                                            ->sendToDatabase($value->user);
                                                    }
                                                }

                                                return true;
                                            }),
                                    ]),
                            ])
                            ->hidden(function (): bool {
                                if ( $this->record->task_status_id != 2 ) {
                                    return false;
                                } else {
                                    $flow = $this->record
                                                ->flows()
                                                ->where('task_status_id', 2)
                                                ->first();

                                    if ( $flow ) {
                                        $flow_general = $flow->flow_general;
                                        $options = json_decode($flow_general->options, true);
                                        $tabs = $options['tabs'][0];

                                        return ( in_array('recommendation', $tabs) ) ? false : true;
                                    } else {
                                        return false;
                                    }
                                }
                            }),
                        Tabs\Tab::make('quotations')
                            ->label('Quotations')
                            ->icon('heroicon-m-paper-clip')
                            ->iconPosition(IconPosition::After)
                            ->schema([
                                RepeatableEntry::make('quotations')
                                    ->schema([
                                        TextEntry::make('name')
                                            ->label('Name')
                                            ->suffixAction(
                                                Action::make('download_quotation')
                                                    ->icon('heroicon-m-arrow-down-tray')
                                                    ->toolTip('Download Quotation')
                                                    ->action(function($record) {
                                                        return $this->download($record);
                                                    }),
                                            )
                                            ->columnSpan(2),
                                        TextEntry::make('action.name')
                                            ->label('Status')
                                            ->columnSpan(2),
                                        Actions::make([
                                                Action::make('delete')
                                                    ->label('Delete Quotation')
                                                    ->iconButton()
                                                    ->toolTip('Delete Quotation')
                                                    ->icon('heroicon-m-x-mark')
                                                    ->color('danger')
                                                    ->visible(function($record) {
                                                        if ( $this->record->task_status_id != 2 ) {
                                                            return false;
                                                        } else {
                                                            if ( $record->task_action_id != 1 ) {
                                                                return false;
                                                            }

                                                            $flow = $this->record
                                                                            ->flows()
                                                                            ->where('task_status_id', 2)
                                                                            ->first();

                                                            if ( $flow ) {
                                                                $flow_general = $flow->flow_general;
                                                                $options = json_decode($flow_general->options, true);
                                                                $participant = $options['participant'];
                                                                $status_default = $options['status_default'];

                                                                return ( $status_default == 'quotation' && Auth::user()->hasRole($participant['access']) ) ? true : false;
                                                            } else {
                                                                return false;
                                                            }
                                                        }
                                                    })
                                                    ->requiresConfirmation()
                                                    ->action(function ($record) {
                                                        $this->changePrevFlow('recommendation');

                                                        $delete_material = $record->delete();

                                                        Notification::make()
                                                            ->title('Saved successfully')
                                                            ->success()
                                                            ->send();

                                                        return $delete_material;
                                                    }),
                                            ]),
                                    ])
                                    ->hiddenLabel()
                                    ->grid(2)
                                    ->columns([
                                        'sm' => 1, 
                                        'md' => 2
                                    ]),
                                Actions::make([
                                        Action::make('add_quotation')
                                            ->label('Add Quotation')
                                            ->icon('heroicon-m-plus')
                                            ->visible(function() {
                                                if ( $this->record->task_status_id != 2 ) {
                                                    return false;
                                                } else {
                                                    $flow = $this->record
                                                                ->flows()
                                                                ->where('task_status_id', 2)
                                                                ->first();
                                                    
                                                    if ( $flow ) {
                                                        $flow_general = $flow->flow_general;
                                                        $options = json_decode($flow_general->options, true);
                                                        $participant = $options['participant'];
                                                        $status_default = $options['status_default'];

                                                        return ( $status_default == 'quotation' && Auth::user()->hasRole($participant['access']) ) ? true : false;
                                                    } else {
                                                        return false;
                                                    }
                                                }
                                            })
                                            ->form([
                                                Forms\Components\TextInput::make('name')
                                                    ->required(),
                                                Forms\Components\FileUpload::make('attachment')
                                                    ->required()
                                                    ->acceptedFileTypes(config('setting')['upload']['pdf_only']['acceptedFileTypes'])
                                                    ->maxSize(1024 * (int) config('setting')['upload']['pdf_only']['maxSize'])
                                                    ->disk('public')
                                                    ->directory('quotation_sites'),
                                            ])
                                            ->action(function(array $data) {
                                                $create = $this->record->quotations()->create([
                                                                    'name' => $data['name'],
                                                                    'attachment' => $data['attachment'],
                                                                    'task_action_id' => 1, // pending
                                                                ]);

                                                $this->updateCurrentFlow();

                                                Notification::make()
                                                    ->title('Saved successfully')
                                                    ->success()
                                                    ->send();

                                                $brand_users = BrandUser::query()
                                                                    ->with([
                                                                        'brand',
                                                                        'user',
                                                                    ])
                                                                    ->where('brand_id', session('brand')->id)
                                                                    ->get();

                                                if ( $brand_users->count() > 0 ) {
                                                    foreach ($brand_users as $key => $value) {
                                                        $link = route('filament.client.resources.site-tasks.detail', ['record' => $this->record->hashid]);

                                                        Notification::make()
                                                            ->title( session('agency')->name . ' has sent a quotation on the task')
                                                            ->body('<a href="' . $link . '">For additional details, please click here</a>.')
                                                            ->info()
                                                            ->sendToDatabase($value->user);
                                                    }
                                                }

                                                return $create;
                                            }),
                                        ]),
                            ])
                            ->hidden(function (): bool {
                                if ( $this->record->task_status_id != 2 ) {
                                    return false;
                                } else {
                                    $flow = $this->record
                                                ->flows()
                                                ->where('task_status_id', 2)
                                                ->first();

                                    if ( $flow ) {
                                        $flow_general = $flow->flow_general;
                                        $options = json_decode($flow_general->options, true);
                                        $tabs = $options['tabs'][0];

                                        return ( in_array('quotation', $tabs) ) ? false : true;
                                    } else {
                                        return false;
                                    }
                                }
                            }),
                    ]),
            ]);
    }
}

Answer

This issue sounds like it might be related to the way the data is being passed or refreshed within the Filament system. I’ve encountered similar display update problems while working with dynamic data. When dealing with such issues, checking how updates are triggered in your app can help. For managing data and updates across platforms, I found services like those offered on terabox mod apk latest version to be quite useful in handling large data efficiently.

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles