Skip to content
This repository has been archived by the owner on Feb 11, 2025. It is now read-only.

Commit

Permalink
Merge bulk and singular incident update logic
Browse files Browse the repository at this point in the history
* Make update endpoint work for singular incident as well and change detail view to use it
* Remove now obsolete ack incident view
* Include single incident pk using hx-vals
  • Loading branch information
podliashanyk authored Oct 30, 2024
1 parent 0fdde37 commit 092d9e6
Show file tree
Hide file tree
Showing 9 changed files with 19 additions and 231 deletions.
6 changes: 0 additions & 6 deletions src/argus_htmx/incidents/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,5 @@
urlpatterns = [
path("", views.incident_list, name="incident-list"),
path("<int:pk>/", views.incident_detail, name="incident-detail"),
path("<int:pk>/ack/", views.incident_add_ack, name="incident-add-ack"),
path("<int:pk>/ack-detail/", views.incident_detail_add_ack, name="incident-detail-add-ack"),
path("<int:pk>/close-detail/", views.incident_detail_close, name="incident-detail-close"),
path("<int:pk>/reopen-detail/", views.incident_detail_reopen, name="incident-detail-reopen"),
path("<int:pk>/ticket-edit-detail/", views.incident_detail_edit_ticket, name="incident-detail-edit-ticket"),
path("<int:pk>/ticket-add-detail/", views.incident_detail_add_ticket, name="incident-detail-add-ticket"),
path("update/<str:action>/", views.incidents_update, name="incidents-update"),
]
118 changes: 3 additions & 115 deletions src/argus_htmx/incidents/views.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
from __future__ import annotations

import logging
from typing import Optional
from datetime import datetime

from django import forms
from django.conf import settings
from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect, render, get_object_or_404
from django.urls import reverse
from django.shortcuts import render, get_object_or_404

from django.views.decorators.http import require_POST
from django.core.paginator import Paginator
Expand Down Expand Up @@ -44,6 +39,7 @@
"close": (DescriptionOptionalForm, bulk_close_queryset),
"reopen": (DescriptionOptionalForm, bulk_reopen_queryset),
"update-ticket": (EditTicketUrlForm, bulk_change_ticket_url_queryset),
"add-ticket": (AddTicketUrlForm, bulk_change_ticket_url_queryset),
}


Expand All @@ -63,67 +59,19 @@ class HtmxHttpRequest(HttpRequest):
# fetch with htmx
def incident_detail(request, pk: int):
incident = get_object_or_404(Incident, id=pk)
action_endpoints = {
"ack": reverse("htmx:incident-detail-add-ack", kwargs={"pk": pk}),
"close": reverse("htmx:incident-detail-close", kwargs={"pk": pk}),
"reopen": reverse("htmx:incident-detail-reopen", kwargs={"pk": pk}),
"edit_ticket": reverse("htmx:incident-detail-edit-ticket", kwargs={"pk": pk}),
"add_ticket": reverse("htmx:incident-detail-add-ticket", kwargs={"pk": pk}),
}
context = {
"incident": incident,
"endpoints": action_endpoints,
"page_title": str(incident),
}
return render(request, "htmx/incidents/incident_detail.html", context=context)


def _incident_add_ack(pk: int, formdata, user: User, group: Optional[str] = None):
incident = get_object_or_404(Incident, id=pk)
is_group_member = None
if group:
group = get_object_or_404(Group, name=group)
is_group_member = user.groups.filter(pk=group.pk).exists()
form = AckForm()
if formdata:
if group and not is_group_member:
raise PermissionDenied("User {request.user} is not a member of the correct group")
form = AckForm(formdata)
if form.is_valid():
incident.create_ack(
user,
description=form.cleaned_data["description"],
expiration=form.cleaned_data["expiration"],
)
context = {
"form": form,
"incident": incident,
"page_title": str(incident),
"group": group,
"is_group_member": is_group_member,
}
return incident, context


def incident_add_ack(request, pk: int, group: Optional[str] = None):
formdata = request.POST or None
_, context = _incident_add_ack(pk, formdata, request.user, group)
return render(request, "htmx/incidents/incident_add_ack.html", context=context)


@require_POST
def incident_detail_add_ack(request, pk: int, group: Optional[str] = None):
formdata = request.POST or None
_incident_add_ack(pk, formdata, request.user, group)
return redirect("htmx:incident-detail", pk=pk)


def get_form_data(request, formclass: forms.Form):
formdata = request.POST or None
incident_ids = []
cleaned_form = None
if formdata:
incident_ids = request.POST.getlist("selected_incidents", [])
incident_ids = request.POST.getlist("incident_ids", [])
form = formclass(formdata)
if form.is_valid():
cleaned_form = form.cleaned_data
Expand All @@ -143,66 +91,6 @@ def incidents_update(request: HtmxHttpRequest, action: str):
return HttpResponseClientRefresh()


@require_POST
def incident_detail_close(request, pk: int):
incident = get_object_or_404(Incident, id=pk)
if not incident.stateful:
LOG.warning("Attempt at closing the uncloseable %s", incident)
messages.warning(request, f"Did not close {incident}, stateless incidents cannot be closed.")
return redirect("htmx:incident-detail", pk=pk)
form = DescriptionOptionalForm(request.POST or None)
if form.is_valid():
incident.set_closed(
request.user,
description=form.cleaned_data.get("description", ""),
)
LOG.info("%s manually closed by %s", incident, request.user)
return redirect("htmx:incident-detail", pk=pk)


@require_POST
def incident_detail_reopen(request, pk: int):
incident = get_object_or_404(Incident, id=pk)
if not incident.stateful:
LOG.warning("Attempt at reopening the unopenable %s", incident)
messages.warning(request, f"Did not reopen {incident}, stateless incidents cannot be reopened.")
return redirect("htmx:incident-detail", pk=pk)
form = DescriptionOptionalForm(request.POST or None)
if form.is_valid():
incident.set_open(
request.user,
description=form.cleaned_data.get("description", ""),
)
LOG.info("%s manually reopened by %s", incident, request.user)
return redirect("htmx:incident-detail", pk=pk)


@require_POST
def incident_detail_add_ticket(request, pk: int):
incident = get_object_or_404(Incident, id=pk)
form = AddTicketUrlForm()
if request.POST:
form = AddTicketUrlForm(request.POST)
if form.is_valid():
incident.ticket_url = form.cleaned_data["ticket_url"]
incident.save()

return redirect("htmx:incident-detail", pk=pk)


@require_POST
def incident_detail_edit_ticket(request, pk: int):
incident = get_object_or_404(Incident, id=pk)
form = EditTicketUrlForm()
if request.POST:
form = EditTicketUrlForm(request.POST)
if form.is_valid():
incident.ticket_url = form.cleaned_data["ticket_url"]
incident.save()

return redirect("htmx:incident-detail", pk=pk)


def _get_page_size(params):
try:
if (page_size := int(params.pop("page_size", DEFAULT_PAGE_SIZE))) in ALLOWED_PAGE_SIZES:
Expand Down
36 changes: 0 additions & 36 deletions src/argus_htmx/static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1259,18 +1259,6 @@ html {
}
}

.btn-outline.btn-secondary:hover {
--tw-text-opacity: 1;
color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity)));
}

@supports (color: color-mix(in oklab, black, black)) {
.btn-outline.btn-secondary:hover {
background-color: color-mix(in oklab, var(--fallback-s,oklch(var(--s)/1)) 90%, black);
border-color: color-mix(in oklab, var(--fallback-s,oklch(var(--s)/1)) 90%, black);
}
}

.btn-outline.btn-accent:hover {
--tw-text-opacity: 1;
color: var(--fallback-ac,oklch(var(--ac)/var(--tw-text-opacity)));
Expand Down Expand Up @@ -1982,10 +1970,6 @@ input.tab:checked + .tab-content,
--btn-color: var(--fallback-p);
}

.btn-secondary {
--btn-color: var(--fallback-s);
}

.btn-accent {
--btn-color: var(--fallback-a);
}
Expand Down Expand Up @@ -2062,10 +2046,6 @@ input.tab:checked + .tab-content,
--btn-color: var(--p);
}

.btn-secondary {
--btn-color: var(--s);
}

.btn-accent {
--btn-color: var(--a);
}
Expand All @@ -2075,12 +2055,6 @@ input.tab:checked + .tab-content,
}
}

.btn-secondary {
--tw-text-opacity: 1;
color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity)));
outline-color: var(--fallback-s,oklch(var(--s)/1));
}

.btn-accent {
--tw-text-opacity: 1;
color: var(--fallback-ac,oklch(var(--ac)/var(--tw-text-opacity)));
Expand Down Expand Up @@ -2146,11 +2120,6 @@ input.tab:checked + .tab-content,
color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
}

.btn-outline.btn-secondary {
--tw-text-opacity: 1;
color: var(--fallback-s,oklch(var(--s)/var(--tw-text-opacity)));
}

.btn-outline.btn-secondary.btn-active {
--tw-text-opacity: 1;
color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity)));
Expand Down Expand Up @@ -3850,11 +3819,6 @@ input.tab:checked + .tab-content,
border-color: var(--fallback-p,oklch(var(--p)/var(--tw-border-opacity)));
}

.border-secondary {
--tw-border-opacity: 1;
border-color: var(--fallback-s,oklch(var(--s)/var(--tw-border-opacity)));
}

.bg-base-100 {
--tw-bg-opacity: 1;
background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{% extends "htmx/_base_form_modal.html" %}
{% block form_control %}
hx-post="{% url endpoint|default:'htmx:incidents-update' action=action %}"
{% if action_type == "bulk-update" %}
hx-post="{% url endpoint|default:'htmx:incident-list' action=action %}"
hx-include="[name='selected_incidents']"
hx-include="[name='incident_ids']"
{% else %}
{{ block.super }}
hx-vals='{"incident_ids": [{{ incident.pk }}] }'
{% endif %}
{% endblock form_control %}
12 changes: 5 additions & 7 deletions src/argus_htmx/templates/htmx/incidents/_incident_ack.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<a class="link" href="{% url 'htmx:incident-add-ack' pk=incident.pk %}">
{% if incident.acked %}
<span class="badge badge-primary">Acked</span>
{% else %}
<span class="badge badge-accent">Unacked</span>
{% endif %}
</a>
{% if incident.acked %}
<span class="badge badge-primary">Acked</span>
{% else %}
<span class="badge badge-accent">Unacked</span>
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
type="checkbox"
class="row-select checkbox checkbox-sm checkbox-accent border"
hx-on:change="event.target.checked ? htmx.find('.tab-select').checked = event.target.checked : null;"
name="selected_incidents"
name="incident_ids"
value="{{ incident.pk }}">
Original file line number Diff line number Diff line change
@@ -1,12 +1,2 @@
{% if incident.open %}
<span class="badge badge-primary">Open</span>
{% else %}
<span class="badge badge-accent">Closed</span>
{% endif %}
<a class="link" href="{% url 'htmx:incident-add-ack' pk=incident.pk %}">
{% if incident.acked %}
<span class="badge badge-primary">Acked</span>
{% else %}
<span class="badge badge-accent">Unacked</span>
{% endif %}
</a>
{% include "htmx/incidents/_incident_status.html" %}
{% include "htmx/incidents/_incident_ack.html" %}
46 changes: 0 additions & 46 deletions src/argus_htmx/templates/htmx/incidents/incident_add_ack.html

This file was deleted.

10 changes: 5 additions & 5 deletions src/argus_htmx/templates/htmx/incidents/incident_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@ <h3 class="font-bold">Ticket</h3>
<div class="card-actions">
{% if incident.stateful %}
{% if incident.open %}
{% include "htmx/incidents/_incident_close_modal.html" with dialog_id="close-incident-dialog" button_title="Close" header="Manually close incident" explanation="Write a message describing why the incident was manually closed" endpoint=endpoints.close cancel_text="Cancel" submit_text="Close now" %}
{% include "htmx/incidents/_incident_close_modal.html" with action="close" dialog_id="close-incident-dialog" button_title="Close" header="Manually close incident" explanation="Write a message describing why the incident was manually closed" cancel_text="Cancel" submit_text="Close now" %}
{% else %}
{% include "htmx/incidents/_incident_reopen_modal.html" with dialog_id="reopen-incident-dialog" button_title="Reopen" header="Manually reopen incident" explanation="Write a message describing why the incident was manually reopend" endpoint=endpoints.reopen cancel_text="Cancel" submit_text="Reopen now" %}
{% include "htmx/incidents/_incident_reopen_modal.html" with action="reopen" dialog_id="reopen-incident-dialog" button_title="Reopen" header="Manually reopen incident" explanation="Write a message describing why the incident was manually reopend" cancel_text="Cancel" submit_text="Reopen now" %}
{% endif %}
{% endif %}
{% if incident.ticket_url %}
{% include "htmx/incidents/_incident_ticket_edit_modal.html" with dialog_id="edit-ticket-dialog" button_title="Edit ticket url" header="Edit ticket" explanation="" endpoint=endpoints.edit_ticket cancel_text="Cancel" submit_text="Update" %}
{% include "htmx/incidents/_incident_ticket_edit_modal.html" with action="update-ticket" dialog_id="edit-ticket-dialog" button_title="Edit ticket url" header="Edit ticket" explanation="" cancel_text="Cancel" submit_text="Update" %}
{% else %}
<!-- Manually create ticket dialog -->
{% include "htmx/incidents/_incident_ticket_edit_modal.html" with dialog_id="manual-create-ticket-dialog" button_title="Add ticket url" header="Add url to existing ticket" explanation="Are you sure you want to store this url to an existing ticket on this incident?" endpoint=endpoints.add_ticket cancel_text="Cancel" submit_text="Add ticket" %}
{% include "htmx/incidents/_incident_ticket_edit_modal.html" with action="add-ticket" dialog_id="manual-create-ticket-dialog" button_title="Add ticket url" header="Add url to existing ticket" explanation="Are you sure you want to store this url to an existing ticket on this incident?" cancel_text="Cancel" submit_text="Add ticket" %}
{% endif %}
</div>
</div>
Expand All @@ -96,7 +96,7 @@ <h2 class="card-title">Acknowledgements</h2>
</div>
{% endfor %}
<div class="card-actions divide-none">
{% include "htmx/incidents/_incident_acknowledge_modal.html" with dialog_id="create-acknowledgment-dialog" button_title="Create acknowledgment" header="Submit acknowledgment" explanation="Write a message describing why this incident was acknowledged" endpoint=endpoints.ack cancel_text="Cancel" submit_text="Submit" %}
{% include "htmx/incidents/_incident_acknowledge_modal.html" with action="ack" dialog_id="create-acknowledgment-dialog" button_title="Create acknowledgment" header="Submit acknowledgment" explanation="Write a message describing why this incident was acknowledged" cancel_text="Cancel" submit_text="Submit" %}
</div>
</div>
</section>
Expand Down

0 comments on commit 092d9e6

Please sign in to comment.