fix: adds 'view all ...' button to dashboard widgets

This commit is contained in:
2025-05-13 09:07:20 -05:00
parent 217a667df2
commit 8967d407cb
8 changed files with 71 additions and 45 deletions

View File

@@ -24,7 +24,6 @@ export default class extends Controller {
downloadTargetConnected(target) { downloadTargetConnected(target) {
let downloads = this.element.querySelectorAll('tbody tr'); let downloads = this.element.querySelectorAll('tbody tr');
console.log(downloads.length);
if (downloads.length > 5) { if (downloads.length > 5) {
target.classList.add('hidden'); target.classList.add('hidden');
} }

View File

@@ -3,41 +3,34 @@
namespace App\Monitor\Framework\Repository; namespace App\Monitor\Framework\Repository;
use App\Monitor\Framework\Entity\Monitor; use App\Monitor\Framework\Entity\Monitor;
use App\Util\Paginator;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\User\UserInterface;
/** /**
* @extends ServiceEntityRepository<Monitor> * @extends ServiceEntityRepository<Monitor>
*/ */
class MonitorRepository extends ServiceEntityRepository class MonitorRepository extends ServiceEntityRepository
{ {
public function __construct(ManagerRegistry $registry) private Paginator $paginator;
public function __construct(ManagerRegistry $registry, Paginator $paginator)
{ {
parent::__construct($registry, Monitor::class); parent::__construct($registry, Monitor::class);
$this->paginator = $paginator;
} }
// /** public function getUserMonitorsPaginated(UserInterface $user, int $page, int $perPage)
// * @return MovieMonitor[] Returns an array of MovieMonitor objects {
// */ $query = $this->createQueryBuilder('m')
// public function findByExampleField($value): array ->andWhere('m.status IN (:statuses)')
// { ->andWhere('m.user = :user')
// return $this->createQueryBuilder('m') ->orderBy('m.id', 'ASC')
// ->andWhere('m.exampleField = :val') ->setParameter('statuses', ['Active', 'New', 'In Progress', 'Complete'])
// ->setParameter('val', $value) ->setParameter('user', $user)
// ->orderBy('m.id', 'ASC') ->getQuery();
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?MovieMonitor return $this->paginator->paginate($query, $page, $perPage);
// { }
// return $this->createQueryBuilder('m')
// ->andWhere('m.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
} }

View File

@@ -15,6 +15,8 @@ final class DownloadList extends AbstractController
public string $type; public string $type;
public bool $isWidget = true;
public function __construct( public function __construct(
private readonly DownloadRepository $downloadRepository, private readonly DownloadRepository $downloadRepository,
) {} ) {}

View File

@@ -4,17 +4,22 @@ namespace App\Twig\Components;
use App\Monitor\Framework\Repository\MonitorRepository; use App\Monitor\Framework\Repository\MonitorRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveArg;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent] #[AsTwigComponent]
final class MonitorList extends AbstractController final class MonitorList extends AbstractController
{ {
public bool $isWidget = true;
public function __construct( public function __construct(
private MonitorRepository $monitorRepository, private readonly MonitorRepository $monitorRepository,
) {} ) {}
public function getUserMonitors() #[LiveAction]
public function getUserMonitors(#[LiveArg] int $page = 1, #[LiveArg] int $perPage = 5)
{ {
return $this->getUser()->getMonitors(); return $this->monitorRepository->getUserMonitorsPaginated($this->getUser(), $page, $perPage);
} }
} }

View File

@@ -26,7 +26,7 @@ class Paginator
* @param int $limit * @param int $limit
* @return Paginator * @return Paginator
*/ */
public function paginate($query, int $page = 1, int $limit = 10): Paginator public function paginate($query, int $page = 1, int $limit = 5): Paginator
{ {
$paginator = new OrmPaginator($query); $paginator = new OrmPaginator($query);

View File

@@ -14,7 +14,7 @@
</tr> </tr>
</thead> </thead>
<tbody id="{{ table_body_id }}" class="divide-y divide-gray-200 dark:divide-gray-50"> <tbody id="{{ table_body_id }}" class="divide-y divide-gray-200 dark:divide-gray-50">
{% if this.downloads|length > 0 %} {% if this.downloads.items|length > 0 %}
{% for download in this.downloads.items %} {% for download in this.downloads.items %}
<tr id="ad_download_{{ download.id }}"> <tr id="ad_download_{{ download.id }}">
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-stone-800 min-w-[45ch] max-w-[45ch] truncate"> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-stone-800 min-w-[45ch] max-w-[45ch] truncate">
@@ -31,6 +31,13 @@
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
{% if this.downloads.items|length > 5 %}
<tr id="monitor_view_all">
<td colspan="5" class="py-2 whitespace-nowrap bg-orange-500 uppercase text-sm font-medium text-center text-white min-w-[50ch] max-w-[50ch] truncate">
<a href="#">View All Monitors</a>
</td>
</tr>
{% endif %}
{% else %} {% else %}
<tr id="{{ table_body_id }}_no_downloads"> <tr id="{{ table_body_id }}_no_downloads">
<td class="px-6 py-4 whitespace-nowrap text-xs uppercase text-center col-span-2 font-medium text-gray-800 dark:text-stone-800" colspan="2"> <td class="px-6 py-4 whitespace-nowrap text-xs uppercase text-center col-span-2 font-medium text-gray-800 dark:text-stone-800" colspan="2">
@@ -41,9 +48,11 @@
</tbody> </tbody>
</table> </table>
{% if this.downloads.items|length > 0 %} {% if this.isWidget == false %}
{% set paginator = this.downloads %} {% if this.downloads.items|length > 0 %}
{% include 'partial/paginator.html.twig' %} {% set paginator = this.downloads %}
{% include 'partial/paginator.html.twig' %}
{% endif %}
{% endif %} {% endif %}
</div> </div>

View File

@@ -26,8 +26,8 @@
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-gray-50"> <tbody class="divide-y divide-gray-50">
{% if this.userMonitors()|length > 0 %} {% if this.userMonitors.items|length > 0 %}
{% for monitor in this.userMonitors() %} {% for monitor in this.userMonitors.items %}
<tr id="monitor_{{ monitor.id }}"> <tr id="monitor_{{ monitor.id }}">
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-stone-800 min-w-[50ch] max-w-[50ch] truncate"> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-stone-800 min-w-[50ch] max-w-[50ch] truncate">
{{ monitor.title }} {{ monitor.title }}
@@ -52,6 +52,13 @@
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
{% if this.userMonitors.items|length > 5 %}
<tr id="monitor_view_all">
<td colspan="5" class="py-2 whitespace-nowrap bg-orange-500 uppercase text-sm font-medium text-center text-white min-w-[50ch] max-w-[50ch] truncate">
<a href="#">View All Monitors</a>
</td>
</tr>
{% endif %}
{% else %} {% else %}
<tr> <tr>
<td class="px-6 py-4 whitespace-nowrap text-xs uppercase text-center col-span-2 font-medium text-stone-800" colspan="2"> <td class="px-6 py-4 whitespace-nowrap text-xs uppercase text-center col-span-2 font-medium text-stone-800" colspan="2">
@@ -61,5 +68,12 @@
{% endif %} {% endif %}
</tbody> </tbody>
</table> </table>
{% if this.isWidget == false %}
{% if this.userMonitors.items|length > 0 %}
{% set paginator = this.userMonitors %}
{% include 'partial/paginator.html.twig' %}
{% endif %}
{% endif %}
</div> </div>

View File

@@ -5,42 +5,46 @@
{% if paginator.lastPage > 1 %} {% if paginator.lastPage > 1 %}
<nav> <nav>
<ul class="pagination justify-content-center"> <ul class="mt-2 flex flex-row justify-content-center gap-1 py-1 text-white text-sm">
<li class="page-item{{ _currentPage <= 1 ? ' disabled' : '' }}"> <li class="page-item{{ _currentPage <= 1 ? ' disabled' : '' }}">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({page: _currentPage - 1})) }}" aria-label="Previous"> <a data-live-action="click->pagination#paginate"
&laquo; {{ "Previous"|trans }} data-live-action-page-value="_currentPage - 1"
class="page-link px-2.5 py-1 rounded-lg bg-orange-500 align-middle" href="{{ path(_currentRoute, _currentParams|merge({page: _currentPage - 1})) }}" aria-label="Previous">
&laquo;
</a> </a>
</li> </li>
{% set startPage = max(1, _currentPage - 2) %} {% set startPage = max(1, _currentPage - 2) %}
{% set endPage = min(_lastPage, startPage + 4) %} {% set endPage = min(_lastPage, startPage + 4) %}
{% if startPage > 1 %} {% if startPage > 1 %}
<li class="page-item"> <li class="page-item">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({page: 1})) }}">1</a> <a data-live-action="click->pagination#paginate"
data-live-action-page-value="1"
class="page-link px-2.5 py-1 rounded-lg bg-orange-500 align-middle" href="{{ path(_currentRoute, _currentParams|merge({page: 1})) }}">1</a>
</li> </li>
{% if startPage > 2 %} {% if startPage > 2 %}
<li class="page-item disabled"> <li class="page-item disabled">
<span class="page-link">...</span> <span class="page-link px-2.5 py-1 rounded-lg bg-orange-500 align-middle">...</span>
</li> </li>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% for i in startPage..endPage %} {% for i in startPage..endPage %}
<li class="page-item {% if i == _currentPage %}active{% endif %}"> <li class="page-item {% if i == _currentPage %}active{% endif %}">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({page: i})) }}">{{ i }}</a> <a class="page-link px-2.5 py-1 rounded-lg bg-orange-500 align-middle" href="#">{{ i }}</a>
</li> </li>
{% endfor %} {% endfor %}
{% if endPage < _lastPage %} {% if endPage < _lastPage %}
{% if endPage < _lastPage - 1 %} {% if endPage < _lastPage - 1 %}
<li class="page-item disabled"> <li class="page-item disabled">
<span class="page-link">...</span> <span class="page-link px-2.5 py-1 rounded-lg bg-orange-500 align-middle">...</span>
</li> </li>
{% endif %} {% endif %}
<li class="page-item"> <li class="page-item">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({page: _lastPage})) }}">{{ _lastPage }}</a> <a class="page-link px-2.5 py-1 rounded-lg bg-orange-500 align-middle" href="{{ path(_currentRoute, _currentParams|merge({page: _lastPage})) }}">{{ _lastPage }}</a>
</li> </li>
{% endif %} {% endif %}
<li class="page-item {{ _currentPage >= paginator.lastPage ? ' disabled' : '' }}"> <li class="page-item {{ _currentPage >= paginator.lastPage ? ' disabled' : '' }}">
<a class="page-link" href="{{ path(_currentRoute, _currentParams|merge({page: _currentPage + 1})) }}" aria-label="Next"> <a class="page-link px-2.5 py-1 rounded-lg bg-orange-500 align-middle" href="{{ path(_currentRoute, _currentParams|merge({page: _currentPage + 1})) }}" aria-label="Next">
{{ "Next"|trans }} &raquo; &raquo;
</a> </a>
</li> </li>
</ul> </ul>