Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1938.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added a kiosk mode to the main view, providing a minimal version of the incident list suitable for passive Argus usage.
9 changes: 9 additions & 0 deletions docs/user-manual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ Change how often the incidents table gets refreshed

3. Select how often you want the incidents to be updated.

Use kiosk mode
--------------

Kiosk mode is a read-only view of the incidents table intended for display
screens such as NOC monitors, which frees up more vertical space by simplifying the interface.
It can be accessed via the ``Kiosk`` button in the filter toolbar, or directly at **/incidents/kiosk/**.

To exit kiosk mode, you can press the ``Exit kiosk`` button in the filter toolbar.

Decide which incidents are shown in the table
---------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions src/argus/htmx/incident/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
app_name = "htmx"
urlpatterns = [
path("", views.incident_list, name="incident-list"),
path("kiosk/", views.incident_list_kiosk, name="incident-list-kiosk"),
path("<int:pk>/", views.incident_detail, name="incident-detail"),
path("update/<str:action>/", views.incident_update, name="incident-update"),
path("filter/", views.filter_form, name="incident-filter"),
Expand Down
22 changes: 21 additions & 1 deletion src/argus/htmx/incident/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
QueryDict,
)
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.utils.timezone import now as tznow
from django.views.decorators.http import require_POST, require_GET

Expand Down Expand Up @@ -46,6 +47,7 @@

User = get_user_model()
LOG = logging.getLogger(__name__)
KIOSK_URL_NAME = "htmx:incident-list-kiosk"


# Map request trigger to parameters for incidents update
Expand Down Expand Up @@ -266,7 +268,7 @@ def search_tags(request):


@require_GET
def incident_list(request: HtmxHttpRequest) -> HttpResponse:
def incident_list(request: HtmxHttpRequest, kiosk_mode: bool = False) -> HttpResponse:
LOG = logging.getLogger(__name__ + ".incident_list")
LOG.debug("GET at start: %s", request.GET)
request.GET = dedupe_querydict(request.GET)
Expand All @@ -275,6 +277,8 @@ def incident_list(request: HtmxHttpRequest) -> HttpResponse:
preferences = request.user.get_preferences_context()
column_layout_name = preferences["argus_htmx"]["incidents_table_column_name"]
columns = get_incident_table_columns(column_layout_name)
if kiosk_mode:
columns = [c for c in columns if c.name != "row_select"]

# Handle sorting
sort_form = SortForm(request.GET)
Expand Down Expand Up @@ -345,6 +349,14 @@ def incident_list(request: HtmxHttpRequest) -> HttpResponse:
else:
base_template = "htmx/incident/_base.html"

incident_list_url = reverse(KIOSK_URL_NAME if kiosk_mode else "htmx:incident-list")

kiosk_filter_name = None
if kiosk_mode and not request.htmx:
selected_filter_id = request.session.get("selected_filter")
if selected_filter_id:
kiosk_filter_name = Filter.objects.filter(id=selected_filter_id).values_list("name", flat=True).first()

LOG.debug("GET at end: %s", request.GET)
context = {
"columns": columns,
Expand All @@ -358,5 +370,13 @@ def incident_list(request: HtmxHttpRequest) -> HttpResponse:
"page": page,
"last_page_num": last_page_num,
"second_to_last_page": last_page_num - 1,
"kiosk_mode": kiosk_mode,
"kiosk_filter_name": kiosk_filter_name,
"incident_list_url": incident_list_url,
}
return render(request, "htmx/incident/incident_list.html", context=context)


@require_GET
def incident_list_kiosk(request: HtmxHttpRequest) -> HttpResponse:
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
return incident_list(request, kiosk_mode=True)
2 changes: 2 additions & 0 deletions src/argus/htmx/templates/htmx/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
{% endcomment %}
{% endblock navlinks %}
</ul>
{% block navbar_kiosk %}
{% endblock navbar_kiosk %}
</div>
<div class="navbar-end">
{% block userlink %}
Expand Down
6 changes: 6 additions & 0 deletions src/argus/htmx/templates/htmx/incident/_filter_controls.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@
<i class="fa-solid fa-chevron-up fa-xs filter-collapse-icon"
aria-hidden="true"></i>
</button>
<a href="{% url 'htmx:incident-list-kiosk' %}"
onclick="this.href='{% url 'htmx:incident-list-kiosk' %}' + window.location.search"
class="btn btn-sm btn-ghost">
Comment thread
aleksfl marked this conversation as resolved.
Outdated
<i class="fa-solid fa-display fa-xs" aria-hidden="true"></i>
<span class="link">Kiosk</span>
</a>
</div>
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{# djlint:off #}
{% with preferences.argus_htmx.update_interval as update_interval %}
{% if update_interval != 'never' %}
hx-get="{% url 'htmx:incident-list' %}"
hx-vals='{"page": "{{ page.number }}"}'
hx-get="{{ incident_list_url }}"
hx-vals='{"page": "{{ page.number }}"{% if kiosk_mode %}, "sort": "{{ current_sort }}", "sort_order": "{{ current_sort_order }}"{% endif %}'
hx-target="this"
hx-swap="outerHTML"
hx-trigger="every {{ update_interval }}s"
Expand Down
24 changes: 13 additions & 11 deletions src/argus/htmx/templates/htmx/incident/_incident_table_footer.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
<!-- htmx/incident/_incident_table_footer.html -->
<tfoot id="table-footer">
<tr class="sticky bottom-0 bg-base-100">
<td colspan="{{ columns|length }}" class="border-t border-primary">
<div class="flex justify-between items-center">
{% block refresh_info %}
{% include "htmx/incident/_incident_list_refresh_info.html" %}
{% endblock refresh_info %}
{% include "./_incident_table_paginator.html" %}
</div>
</td>
</tr>
{% if not kiosk_mode %}
<tr class="sticky bottom-0 bg-base-100">
<td colspan="{{ columns|length }}" class="border-t border-primary">
<div class="flex justify-between items-center">
{% block refresh_info %}
{% include "htmx/incident/_incident_list_refresh_info.html" %}
{% endblock refresh_info %}
{% include "./_incident_table_paginator.html" %}
</div>
</td>
</tr>
{% endif %}
</tfoot>
<!-- Include in footer of incident table to add scroll shadows to header and footer -->
<script>
(() => {
const table = document.querySelector("#table");
const elements = [table.querySelector("thead tr"), table.querySelector("tfoot tr")]
const elements = [table.querySelector("thead tr"), table.querySelector("tfoot tr")].filter(Boolean);

elements.forEach((el) => {
const intercept = document.createElement("div");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
displayed as clickable.
-->
<li>
<a hx-get="{% url 'htmx:incident-list' %}"
<a hx-get="{{ incident_list_url }}"
hx-vals='{"page": "{{ page_number }}"}'
href="{% querystring page=page_number %}"
hx-indicator="#incident-list .htmx-indicator"
Expand Down
22 changes: 12 additions & 10 deletions src/argus/htmx/templates/htmx/incident/_incident_toolbar.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<section class="flex flex-col gap-2">
<div id="filter-controls-box"
class="border-2 border-primary rounded-box p-2 flex flex-wrap gap-0.5 items-center">
{% include "htmx/incident/_filter_controls.html" %}
<div id="filterbox" class="flex flex-wrap items-center basis-full">
{% include "htmx/incident/_incident_filterbox.html" %}
{% if not kiosk_mode %}
<div id="filter-controls-box"
class="border-2 border-primary rounded-box p-2 flex flex-wrap gap-0.5 items-center">
{% include "htmx/incident/_filter_controls.html" %}
<div id="filterbox" class="flex flex-wrap items-center basis-full">
{% include "htmx/incident/_incident_filterbox.html" %}
</div>
</div>
</div>
<div id="bulk-actions"
class="hidden flex gap-2 w-fit border-2 border-primary/50 bg-primary/10 rounded-box p-1">
{% include "htmx/incident/_incident_list_update_menu.html" %}
</div>
<div id="bulk-actions"
class="hidden flex gap-2 w-fit border-2 border-primary/50 bg-primary/10 rounded-box p-1">
{% include "htmx/incident/_incident_list_update_menu.html" %}
</div>
{% endif %}
</section>
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@
<div class="flex items-center gap-1">
<span id="{{ field.name }}-label">{{ column.label }}</span>
{% include "htmx/incident/cells/_incident_sort_button.html" %}
{# Filter dropdown #}
<div id="{{ column.name }}-dropdown" class="dropdown dropdown-end">
<button type="button"
tabindex="0"
aria-label="Filter by {{ column.label|lower }}"
aria-controls="{{ column.name }}-dropdown-content"
class="filter-btn btn btn-xs {% if field.value %} btn-primary {% else %} btn-ghost text-primary {% endif %} min-h-4 h-4"
{% if dummy_column %}disabled{% endif %}>
<i class="fa-solid fa-magnifying-glass"></i>
</button>
{% include "htmx/incident/cells/_incident_filter_dropdown_body.html" %}
</div>
{% if not kiosk_mode %}
{# Filter dropdown #}
<div id="{{ column.name }}-dropdown" class="dropdown dropdown-end">
<button type="button"
tabindex="0"
aria-label="Filter by {{ column.label|lower }}"
aria-controls="{{ column.name }}-dropdown-content"
class="filter-btn btn btn-xs {% if field.value %} btn-primary {% else %} btn-ghost text-primary {% endif %} min-h-4 h-4"
{% if dummy_column %}disabled{% endif %}>
<i class="fa-solid fa-magnifying-glass"></i>
</button>
{% include "htmx/incident/cells/_incident_filter_dropdown_body.html" %}
</div>
{% endif %}
</div>
{% endwith %}
{% include "htmx/incident/cells/_incident_filter_dropdown_script.html" %}
{% if not kiosk_mode %}
{% include "htmx/incident/cells/_incident_filter_dropdown_script.html" %}
{% endif %}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- htmx/incident/cells/_incident_sort_button.html -->
{# Reusable sort button for column headers. Requires: column, current_sort, current_sort_order #}
{# Cycling order: inactive -> desc -> asc -> inactive (default) #}
{% if column.sort_field %}
{% if column.sort_field and not kiosk_mode %}
{% if current_sort == column.sort_field %}
{% if current_sort_order == "desc" %}
{% with icon="fa-sort-down" next_sort=column.sort_field next_order="asc" label="Sort by "|add:column.label|lower|add:" ascending" active=True %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class="btn btn-xs btn-ghost p-0 aspect-square min-h-4 h-4 {% if active %}text-primary{% else %}text-base-content/50 hover:text-primary{% endif %}"
aria-label="{{ label }}"
{% if dummy_column %}disabled{% endif %}
hx-get="{% url 'htmx:incident-list' %}"
hx-get="{{ incident_list_url }}"
hx-vals='{"sort": "{{ next_sort }}", "sort_order": "{{ next_order }}"}'
hx-include=".incident-list-param"
hx-target="#table"
Expand Down
24 changes: 24 additions & 0 deletions src/argus/htmx/templates/htmx/incident/incident_list.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
{% extends base %}
{% block navbar_kiosk %}
{% if kiosk_mode %}
<div class="border-2 border-primary rounded-box px-3 py-1 bg-base-100 text-base-content flex gap-0.5 items-center">
<span class="text-sm font-medium ml-1">
<span class="opacity-60">Filter:</span>
{{ kiosk_filter_name|default:"None" }}
</span>
<span class="text-sm font-medium ml-1">
<span class="opacity-60">After filtering:</span>
<span id="kiosk-filtered-count">{{ refresh_info.filtered_count }}</span>
</span>
<span class="text-sm font-medium ml-1">
<span class="opacity-60">Last refreshed:</span>
<span id="kiosk-last-refreshed">{{ refresh_info.last_refreshed|date:preferences.argus_htmx.datetime_format|default:"?" }}</span>
</span>
<a href="{% url 'htmx:incident-list' %}"
onclick="this.href='{% url 'htmx:incident-list' %}' + window.location.search"
class="btn btn-sm btn-ghost">
Comment thread
aleksfl marked this conversation as resolved.
Outdated
<i class="fa-solid fa-xmark fa-xs" aria-hidden="true"></i>
<span class="link">Exit kiosk</span>
</a>
</div>
{% endif %}
{% endblock navbar_kiosk %}
{% block main %}
{% if incidents_extra_widget %}
<div class="flex">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
{% block table %}
{% endblock table %}
{% if kiosk_mode %}
<span hx-swap-oob="innerHTML:#kiosk-filtered-count">{{ refresh_info.filtered_count }}</span>
<span hx-swap-oob="innerHTML:#kiosk-last-refreshed">{{ refresh_info.last_refreshed|date:preferences.argus_htmx.datetime_format|default:"?" }}</span>
{% endif %}
Loading
Loading