Improve instance delete

This commit is contained in:
Tobias Kunze 2025-05-25 22:53:22 +02:00
parent 09ce5406ee
commit 3a8b9987b2
6 changed files with 46 additions and 27 deletions

View file

@ -6,7 +6,7 @@ import urlman
from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.db import IntegrityError, models
from django.db import IntegrityError, models, transaction
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
@ -636,6 +636,7 @@ class ServiceInstance(ServalaModelMixin, models.Model):
_("Error updating instance: {error}").format(error=str(e))
)
@transaction.atomic
def delete_instance(self, user):
"""
Soft deletes the instance in Django and initiates deletion of the

View file

@ -88,33 +88,28 @@ class ServiceInstanceFilterForm(forms.Form):
return queryset
class ServiceInstanceDeleteForm(forms.Form):
name_confirm = forms.CharField(
class ServiceInstanceDeleteForm(forms.ModelForm):
name = forms.CharField(
label=_("Instance Name"),
max_length=63,
widget=forms.TextInput(attrs={"class": "form-control"}),
)
def __init__(self, *args, **kwargs):
self.instance_name = kwargs.pop("instance_name", None)
kwargs["initial"] = {"name": ""}
super().__init__(*args, **kwargs)
if self.instance_name:
self.fields["name_confirm"].help_text = _(
"To confirm deletion, please type the instance name: <strong>{instance_name}</strong>"
).format(instance_name=self.instance_name)
else:
self.fields["name_confirm"].help_text = _(
"Please type the instance name to confirm deletion."
)
self.fields["name"].help_text = _(
"To confirm deletion, please type the instance name: <strong>{instance_name}</strong>"
).format(instance_name=self.instance.name)
def clean_name_confirm(self):
entered_name = self.cleaned_data.get("name_confirm")
if not self.instance_name:
raise ValidationError(
_("Cannot confirm deletion: instance name not provided to form.")
)
if entered_name != self.instance_name:
def clean_name(self):
entered_name = self.cleaned_data.get("name")
if entered_name != self.instance.name:
raise ValidationError(
_("The entered name does not match the instance name. Deletion not confirmed.")
)
return entered_name
class Meta:
model = ServiceInstance
fields = ("name", )

View file

@ -1,6 +1,6 @@
{% load i18n %}
{% if form.non_field_errors or form.errors %}
<div class="alert alert-danger" role="alert">
<div class="alert alert-danger form-errors" role="alert">
<div>
{% if form.non_field_errors %}
{% if form.non_field_errors|length > 1 %}

View file

@ -6,9 +6,20 @@
{% endblock page_title %}
{% endblock html_title %}
{% block page_title_extra %}
{% if has_change_permission %}
<a href="{{ instance.urls.update }}" class="btn btn-primary me-1 mb-1">{% translate "Edit" %}</a>
{% endif %}
<div>
{% if has_change_permission and not instance.is_deleted %}
<a href="{{ instance.urls.update }}" class="btn btn-primary me-1 mb-1">{% translate "Edit" %}</a>
{% endif %}
{% if has_delete_permission and not instance.is_deleted %}
<button type="button" class="btn btn-danger me-1 mb-1"
hx-get="{{ instance.urls.delete }}"
hx-target="#deleteInstanceModalContent"
data-bs-toggle="modal"
data-bs-target="#deleteInstanceModal">
{% translate "Delete" %}
</button>
{% endif %}
</div>
{% endblock page_title_extra %}
{% block content %}
<section class="section">
@ -47,7 +58,14 @@
<dt class="col-sm-4">{% translate "Status" %}</dt>
<dd class="col-sm-8">
{% if instance.is_deleted %}
<span class="badge text-bg-secondary">{% translate "Deleted" %}</span>
<span class="badge text-bg-danger">{% translate "Deleted" %}</span>
{% if instance.deleted_at %}
<small class="text-muted d-block mt-1">
{% blocktranslate with date=instance.deleted_at|date:"SHORT_DATETIME_FORMAT" user=instance.deleted_by|default:_("system") %}
On {{ date }} by {{ user }}
{% endblocktranslate %}
</small>
{% endif %}
{% else %}
<span class="badge text-bg-success">{% translate "Active" %}</span>
{% endif %}
@ -56,7 +74,7 @@
</div>
</div>
</div>
{% if instance.status_conditions %}
{% if not instance.is_deleted and instance.status_conditions %}
<div class="col-12 col-md-7">
<div class="card">
<div class="card-header">
@ -101,7 +119,7 @@
</div>
</div>
{% endif %}
{% if instance.spec %}
{% if not instance.is_deleted and instance.spec and spec_fieldsets %}
<div class="col-12">
<div class="card">
<div class="card-header">

View file

@ -423,7 +423,9 @@ class ServiceInstanceDeleteView(
name=self.object.name, error=str(e)
),
)
return self.form_invalid(form)
response = HttpResponse()
response["HX-Redirect"] = str(self.object.urls.base)
return response
def get_success_url(self):
return self.request.organization.urls.instances

View file

@ -90,3 +90,6 @@ a.btn-keycloak {
flex-wrap: wrap;
justify-content: space-between;
}
.hide-form-errors .alert.form-errors {
display: none;
}