From eb4d3f95563ab1d26db154693ee51d66ce54c32b Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Wed, 21 May 2025 09:19:31 +0200 Subject: [PATCH] Implement service instance update --- .../service_instance_update.html | 39 +++++++++++++ src/servala/frontend/views/service.py | 56 ++++++++++++++++--- 2 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 src/servala/frontend/templates/frontend/organizations/service_instance_update.html diff --git a/src/servala/frontend/templates/frontend/organizations/service_instance_update.html b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html new file mode 100644 index 0000000..cbfbd6f --- /dev/null +++ b/src/servala/frontend/templates/frontend/organizations/service_instance_update.html @@ -0,0 +1,39 @@ +{% extends "frontend/base.html" %} +{% load i18n %} +{% load static %} +{% load partials %} +{% block html_title %} + {% block page_title %} + {% block title %} + {% blocktranslate with instance_name=instance.name organization_name=request.organization.name %}Update {{ instance_name }} in {{ organization_name }}{% endblocktranslate %} + {% endblock %} + {% endblock page_title %} +{% endblock html_title %} +{% partialdef service-form %} +{% if form %} +
+
+
+ {% if form_error %} +
+ {% translate "Oops! Something went wrong with the service form generation. Please try again later." %} +
+ {% else %} + {% include "includes/tabbed_fieldset_form.html" with form=form %} + {% endif %} +
+
+{% endif %} +{% endpartialdef %} +{% block content %} +
+
+ {% if not form %} + + {% else %} +
{% partial service-form %}
+ {% endif %} +
+ {% endblock %} diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index 1ee46b4..0a0fe10 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -17,7 +17,11 @@ from servala.frontend.forms.service import ( ServiceFilterForm, ServiceInstanceFilterForm, ) -from servala.frontend.views.mixins import HtmxViewMixin, OrganizationViewMixin +from servala.frontend.views.mixins import ( + HtmxUpdateView, + HtmxViewMixin, + OrganizationViewMixin, +) class ServiceListView(OrganizationViewMixin, ListView): @@ -310,12 +314,43 @@ class ServiceInstanceDetailView( return fieldsets - def get_context_data(self, **kwargs): - """Return service instance for the current organization.""" - context = super().get_context_data(**kwargs) - if self.object.spec: - context["spec_fieldsets"] = self.get_nested_spec() - return context + +class ServiceInstanceUpdateView( + ServiceInstanceMixin, OrganizationViewMixin, HtmxUpdateView +): + template_name = "frontend/organizations/service_instance_update.html" + permission_type = "change" + + def get_form_class(self): + return self.object.context.model_form_class + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs["instance"] = self.object.spec_object + return kwargs + + def form_valid(self, form): + try: + spec_data = form.get_nested_data().get("spec") + self.object.update_spec(spec_data=spec_data, updated_by=self.request.user) + messages.success( + self.request, + _("Service instance '{name}' updated successfully.").format( + name=self.object.name + ), + ) + return redirect(self.object.urls.base) + except ValidationError as e: + messages.error(self.request, e.message or str(e)) + return self.form_invalid(form) + except Exception as e: + messages.error( + self.request, _("Error updating instance: {error}").format(error=str(e)) + ) + return self.form_invalid(form) + + def get_success_url(self): + return self.object.urls.base class ServiceInstanceListView(OrganizationViewMixin, ListView): @@ -331,7 +366,12 @@ class ServiceInstanceListView(OrganizationViewMixin, ListView): def get_queryset(self): """Return all service instances for the current organization with filtering.""" queryset = ServiceInstance.objects.filter( - organization=self.request.organization + organization=self.request.organization, + is_deleted=False, # Exclude soft-deleted + ).select_related( + "context__service_offering__provider", + "context__control_plane", + "context__service_definition__service", ) if self.filter_form.is_valid(): queryset = self.filter_form.filter_queryset(queryset)