+ {% if not form %}
+
+ {% translate "Cannot update this service instance because its details could not be retrieved from the underlying system. It might have been deleted externally." %}
+
+ {% 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)