diff --git a/src/Board.php b/src/Board.php index 0aec3e432..a3ea2c762 100644 --- a/src/Board.php +++ b/src/Board.php @@ -58,16 +58,15 @@ protected function setUp(): void */ public function getViewData(): array { - // Batch all column counts in a single query $allCounts = $this->getBatchedBoardRecordCounts(); + $batchedRecords = $this->getBatchedBoardRecords(); - // Build columns data using new concerns $columns = []; + foreach ($this->getColumns() as $column) { $columnId = $column->getName(); - // Get formatted records - $records = $this->getBoardRecords($columnId); + $records = $batchedRecords[$columnId] ?? new \Illuminate\Database\Eloquent\Collection; $formattedRecords = $records->map(fn ($record) => $this->formatBoardRecord($record))->toArray(); $columns[$columnId] = [ diff --git a/src/Concerns/HasBoardRecords.php b/src/Concerns/HasBoardRecords.php index c8f7a8f9f..b221102fe 100644 --- a/src/Concerns/HasBoardRecords.php +++ b/src/Concerns/HasBoardRecords.php @@ -148,6 +148,55 @@ public function getBatchedBoardRecordCounts(): array ->toArray(); } + /** + * Get records for ALL columns in a single query, partitioned in PHP. + * + * @return array + */ + public function getBatchedBoardRecords(): array + { + $query = $this->getQuery(); + + if (! $query) { + return []; + } + + $statusField = $this->getColumnIdentifierAttribute(); + $positionField = $this->getPositionIdentifierAttribute(); + $limit = $this->getCardsPerColumn(); + $livewire = $this->getLivewire(); + + $baseQuery = clone $query; + + if ($livewire->getTable()->isFilterable() || $livewire->hasTableSearch()) { + $baseQuery = clone $livewire->getFilteredTableQuery(); + } + + $keyName = $baseQuery->getModel()->getKeyName(); + $columnIds = collect($this->getColumns())->map(fn ($col) => $col->getName())->all(); + + $allRecords = (clone $baseQuery) + ->whereIn($statusField, $columnIds) + ->orderBy($positionField, 'asc') + ->orderBy($keyName, 'asc') + ->get(); + + $partitioned = []; + + foreach ($columnIds as $columnId) { + $columnLimit = property_exists($livewire, 'columnCardLimits') + ? ($livewire->columnCardLimits[$columnId] ?? $limit) + : $limit; + + $partitioned[$columnId] = $allRecords + ->filter(fn ($record) => (string) data_get($record, $statusField) === (string) $columnId) + ->take($columnLimit) + ->values(); + } + + return $partitioned; + } + /** * Format a record for display with Infolist entries. */