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 : https://gifyu.com/image/bpPf7
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('For additional details, please click here.')
->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('For additional details, please click here.')
->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;
}
}
}),
]),
]);
}
}