Compare commits

...

5 Commits

Author SHA1 Message Date
Brock H Caldwell
a9031df3c3 feat: only shows top level monitors on dashboard and children on dedicated page 2025-11-05 22:35:12 -06:00
Brock H Caldwell
55ab9d840e feat: adds page to list child monitors 2025-11-05 22:19:11 -06:00
Brock H Caldwell
3001e85715 fix: missing placeholders for n/a monitor attributes 2025-11-05 20:48:55 -06:00
Brock H Caldwell
f4125cc37c fix: sentry release 2025-11-05 20:41:11 -06:00
Brock H Caldwell
a3408d9852 fix: include release with sentry 2025-11-05 20:31:43 -06:00
8 changed files with 64 additions and 6 deletions

View File

@@ -23,7 +23,12 @@ export default class extends Controller {
} }
if (null !== content && undefined !== content && "" !== content) { if (null !== content && undefined !== content && "" !== content) {
document.dispatchEvent(new CustomEvent('showPreviewContentModal', {detail: {heading: heading, content: content}})) if (['', null, undefined].includes(monitor.getAttribute('parent-id'))) {
window.location.href = `/monitors/${monitor.getAttribute('monitor-id')}`;
} else {
document.dispatchEvent(new CustomEvent('showPreviewContentModal', {detail: {heading: heading, content: content}}))
}
} }
}) })
}) })

View File

@@ -4,6 +4,7 @@ when@prod:
register_error_handler: true # Disables the ErrorListener, ExceptionListener and FatalErrorListener integrations of the base PHP SDK register_error_handler: true # Disables the ErrorListener, ExceptionListener and FatalErrorListener integrations of the base PHP SDK
options: options:
release: '%app.version%'
traces_sample_rate: 1 traces_sample_rate: 1
profiles_sample_rate: 1 profiles_sample_rate: 1
attach_stacktrace: true attach_stacktrace: true

View File

@@ -33,7 +33,6 @@ class Paginator
public function paginate($query, int $page = 1, int $limit = 5): Paginator public function paginate($query, int $page = 1, int $limit = 5): Paginator
{ {
$paginator = new OrmPaginator($query); $paginator = new OrmPaginator($query);
$paginator $paginator
->getQuery() ->getQuery()
->setFirstResult($limit * ($page - 1)) ->setFirstResult($limit * ($page - 1))

View File

@@ -7,6 +7,7 @@ use App\Monitor\Action\Handler\AddMonitorHandler;
use App\Monitor\Action\Handler\DeleteMonitorHandler; use App\Monitor\Action\Handler\DeleteMonitorHandler;
use App\Monitor\Action\Input\AddMonitorInput; use App\Monitor\Action\Input\AddMonitorInput;
use App\Monitor\Action\Input\DeleteMonitorInput; use App\Monitor\Action\Input\DeleteMonitorInput;
use App\Monitor\Framework\Entity\Monitor;
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\Bundle\SecurityBundle\Security; use Symfony\Bundle\SecurityBundle\Security;
@@ -34,4 +35,12 @@ class WebController extends AbstractController
{ {
return $this->render('monitor/upcoming-episodes.html.twig'); return $this->render('monitor/upcoming-episodes.html.twig');
} }
#[Route('/monitors/{id}', name: 'app.monitor.view', methods: ['GET'])]
public function viewMonitor(Monitor $monitor)
{
return $this->render('monitor/view.html.twig', [
'monitor' => $monitor,
]);
}
} }

View File

@@ -17,11 +17,14 @@ final class MonitorList extends AbstractController
use PaginateTrait; use PaginateTrait;
#[LiveProp(writable: true)]
public ?int $parentMonitorId = null;
#[LiveProp(writable: true)] #[LiveProp(writable: true)]
public string $term = ""; public string $term = "";
#[LiveProp(writable: true)] #[LiveProp(writable: true)]
public string $type; public string $type = "";
#[LiveProp(writable: true)] #[LiveProp(writable: true)]
public bool $isWidget = true; public bool $isWidget = true;
@@ -33,7 +36,9 @@ final class MonitorList extends AbstractController
#[LiveAction] #[LiveAction]
public function getMonitors() public function getMonitors()
{ {
if ($this->type === "active") { if (null !== $this->parentMonitorId) {
return $this->getChildMonitorsByParentId($this->parentMonitorId);
} elseif ($this->type === "active") {
return $this->getActiveUserMonitors(); return $this->getActiveUserMonitors();
} elseif ($this->type === "complete") { } elseif ($this->type === "complete") {
return $this->getCompleteUserMonitors(); return $this->getCompleteUserMonitors();
@@ -48,6 +53,7 @@ final class MonitorList extends AbstractController
return $this->asPaginator($this->monitorRepository->createQueryBuilder('m') return $this->asPaginator($this->monitorRepository->createQueryBuilder('m')
->andWhere('m.status IN (:statuses)') ->andWhere('m.status IN (:statuses)')
->andWhere('(m.title LIKE :term OR m.imdbId LIKE :term OR m.monitorType LIKE :term OR m.status LIKE :term)') ->andWhere('(m.title LIKE :term OR m.imdbId LIKE :term OR m.monitorType LIKE :term OR m.status LIKE :term)')
->andWhere('m.parent IS NULL')
->setParameter('statuses', ['New', 'In Progress', 'Active']) ->setParameter('statuses', ['New', 'In Progress', 'Active'])
->setParameter('term', '%'.$this->term.'%') ->setParameter('term', '%'.$this->term.'%')
->orderBy('m.id', 'DESC') ->orderBy('m.id', 'DESC')
@@ -67,4 +73,16 @@ final class MonitorList extends AbstractController
->getQuery() ->getQuery()
); );
} }
#[LiveAction]
public function getChildMonitorsByParentId(int $parentId)
{
return $this->asPaginator(
$this->monitorRepository->createQueryBuilder('m')
->andWhere("m.parent = :parentId")
->setParameter('parentId', $parentId)
->orderBy('m.id', 'DESC')
->getQuery()
);
}
} }

View File

@@ -17,10 +17,17 @@
class="px-6 py-3 text-start"> class="px-6 py-3 text-start">
ID ID
</th> </th>
{% if null != parentMonitorId %}
<th scope="col" <th scope="col"
class="hidden md:table-cell px-6 py-3 text-start"> class="hidden md:table-cell px-6 py-3 text-start">
Search Count Search Count
</th> </th>
{% else %}
<th scope="col"
class="hidden md:table-cell px-6 py-3 text-start">
Episodes
</th>
{% endif %}
<th scope="col" <th scope="col"
class="hidden md:table-cell px-6 py-3 text-start"> class="hidden md:table-cell px-6 py-3 text-start">
Created at Created at

View File

@@ -1,16 +1,17 @@
<tr{{ attributes }} is="monitor-list-row" id="monitor_{{ monitor.id }}" class="dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-900" <tr{{ attributes }} is="monitor-list-row" id="monitor_{{ monitor.id }}" class="dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-900"
monitor-id="{{ monitor.id }}" monitor-id="{{ monitor.id }}"
parent-id="{{ monitor.parent.id ?? null }}"
imdb-id="{{ monitor.imdbId }}" imdb-id="{{ monitor.imdbId }}"
media-title="{{ monitor.title }}" media-title="{{ monitor.title }}"
season="{{ monitor.season }}" season="{{ monitor.season }}"
episode="{{ monitor.episode }}" episode="{{ monitor.episode ?? '-' }}"
status="{{ monitor.status }}" status="{{ monitor.status }}"
search-count="{{ monitor.searchCount }}" search-count="{{ monitor.searchCount }}"
media-type="{{ monitor.monitorType|monitor_type }}" media-type="{{ monitor.monitorType|monitor_type }}"
episode-id="{{ monitor|monitor_media_id }}" episode-id="{{ monitor|monitor_media_id }}"
created-at="{{ monitor.createdAt|date('m/d/Y g:i a') }}" created-at="{{ monitor.createdAt|date('m/d/Y g:i a') }}"
last-search="{{ monitor.lastSearch|date('m/d/Y g:i a') }}" last-search="{{ monitor.lastSearch|date('m/d/Y g:i a') }}"
downloaded-at="{{ monitor.downloadedAt|date('m/d/Y g:i a') }}" downloaded-at="{{null != monitor.downloadedAt ? monitor.downloadedAt|date('m/d/Y g:i a') : '-' }}"
> >
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-stone-800 truncate"> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-stone-800 truncate">
<a href="{{ path('app_search_result', {imdbId: monitor.imdbId, mediaType: monitor.monitorType|as_download_type}) }}" <a href="{{ path('app_search_result', {imdbId: monitor.imdbId, mediaType: monitor.monitorType|as_download_type}) }}"
@@ -26,9 +27,15 @@
<td class="px-6 py-4 whitespace-nowrap text-sm"> <td class="px-6 py-4 whitespace-nowrap text-sm">
{{ monitor|monitor_media_id }} {{ monitor|monitor_media_id }}
</td> </td>
{% if null != monitor.parent %}
<td class="hidden md:table-cell px-6 py-4 whitespace-nowrap text-sm"> <td class="hidden md:table-cell px-6 py-4 whitespace-nowrap text-sm">
{{ monitor.searchCount }} {{ monitor.searchCount }}
</td> </td>
{% else %}
<td class="hidden md:table-cell px-6 py-4 whitespace-nowrap text-sm">
{{ monitor.children|length }}
</td>
{% endif %}
<td class="hidden md:table-cell px-6 py-4 whitespace-nowrap text-sm"> <td class="hidden md:table-cell px-6 py-4 whitespace-nowrap text-sm">
{{ monitor.createdAt|date('m/d/Y h:i a') }} {{ monitor.createdAt|date('m/d/Y h:i a') }}
</td> </td>

View File

@@ -0,0 +1,12 @@
{% extends 'base.html.twig' %}
{% block title %}{{ monitor.title }} &mdash; Monitors &mdash; Torsearch{% endblock %}
{% block h2 %}Monitors{% endblock %}
{% block body %}
<div class="px-4 py-2">
<twig:Card title="Viewing your monitors for {{ monitor.title }}">
<twig:MonitorList :parentMonitorId="monitor.id" :isWidget="false" :perPage="10"></twig:MonitorList>
</twig:Card>
</div>
{% endblock %}