diff --git a/src/servala/frontend/forms/service.py b/src/servala/frontend/forms/service.py
index 3b7a547..428f1bc 100644
--- a/src/servala/frontend/forms/service.py
+++ b/src/servala/frontend/forms/service.py
@@ -1,7 +1,13 @@
from django import forms
from django.utils.translation import gettext_lazy as _
-from servala.core.models import CloudProvider, ControlPlane, ServiceCategory
+from servala.core.models import (
+ CloudProvider,
+ ControlPlane,
+ Service,
+ ServiceCategory,
+ ServiceOffering,
+)
class ServiceFilterForm(forms.Form):
@@ -33,3 +39,52 @@ class ControlPlaneSelectForm(forms.Form):
def __init__(self, *args, planes=None, **kwargs):
super().__init__(*args, **kwargs)
self.fields["control_plane"].queryset = planes
+
+
+class ServiceInstanceFilterForm(forms.Form):
+ name = forms.CharField(required=False, label=_("Name"))
+ service = forms.ModelChoiceField(
+ queryset=Service.objects.all(), required=False, label=_("Service")
+ )
+ provider = forms.ModelChoiceField(
+ queryset=ServiceOffering.objects.all()
+ .values_list("provider", flat=True)
+ .distinct(),
+ required=False,
+ label=_("Provider"),
+ )
+ control_plane = forms.ModelChoiceField(
+ queryset=ControlPlane.objects.all(),
+ required=False,
+ label=_("Service Provider Zone"),
+ )
+ status = forms.ChoiceField(
+ choices=(
+ ("active", _("Active")),
+ ("deleted", _("Deleted")),
+ ),
+ required=False,
+ label=_("Status"),
+ )
+
+ def filter_queryset(self, queryset):
+ if self.is_valid():
+ data = self.cleaned_data
+ if data["name"]:
+ queryset = queryset.filter(name__icontains=data["name"])
+ if data["service"]:
+ queryset = queryset.filter(
+ context__service_definition__service=data["service"]
+ )
+ if data["provider"]:
+ queryset = queryset.filter(
+ context__service_offering__provider=data["provider"]
+ )
+ if data["control_plane"]:
+ queryset = queryset.filter(context__control_plane=data["control_plane"])
+ if data["status"]:
+ if data["status"] == "active":
+ queryset = queryset.filter(is_deleted=False)
+ else:
+ queryset = queryset.filter(is_deleted=True)
+ return queryset
diff --git a/src/servala/frontend/templates/frontend/organizations/service_instances.html b/src/servala/frontend/templates/frontend/organizations/service_instances.html
index d335049..e5c7c0e 100644
--- a/src/servala/frontend/templates/frontend/organizations/service_instances.html
+++ b/src/servala/frontend/templates/frontend/organizations/service_instances.html
@@ -5,41 +5,59 @@
{% translate "Instances" %}
{% endblock page_title %}
{% endblock html_title %}
-{% block card_content %}
-
-
-
- {% translate "Name" %} |
- {% translate "Service" %} |
- {% translate "Service Provider" %} |
- {% translate "Service Provider Zone" %} |
- {% translate "Created At" %} |
- {% translate "Status" %} |
-
-
-
- {% for instance in instances %}
-
-
- {{ instance.name }}
- |
- {{ instance.context.service_definition.service.name }} |
- {{ instance.context.service_offering.provider.name }} |
- {{ instance.context.control_plane.name }} |
- {{ instance.created_at|date:"SHORT_DATETIME_FORMAT" }} |
-
- {% if instance.is_deleted %}
- {% translate "Deleted" %}
- {% else %}
- {% translate "Active" %}
- {% endif %}
- |
-
- {% empty %}
-
- {% translate "No service instances found." %} |
-
- {% endfor %}
-
-
+{% block content %}
+
+
+
+
+
+
+
+
+ {% translate "Name" %} |
+ {% translate "Service" %} |
+ {% translate "Service Provider" %} |
+ {% translate "Service Provider Zone" %} |
+ {% translate "Created At" %} |
+ {% translate "Status" %} |
+
+
+
+ {% for instance in instances %}
+
+
+ {{ instance.name }}
+ |
+ {{ instance.context.service_definition.service.name }} |
+ {{ instance.context.service_offering.provider.name }} |
+ {{ instance.context.control_plane.name }} |
+ {{ instance.created_at|date:"SHORT_DATETIME_FORMAT" }} |
+
+ {% if instance.is_deleted %}
+ {% translate "Deleted" %}
+ {% else %}
+ {% translate "Active" %}
+ {% endif %}
+ |
+
+ {% empty %}
+
+ {% translate "No service instances found." %} |
+
+ {% endfor %}
+
+
+
+
+
+
+
{% endblock %}
diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py
index c955cde..380f393 100644
--- a/src/servala/frontend/views/service.py
+++ b/src/servala/frontend/views/service.py
@@ -10,7 +10,11 @@ from servala.core.models import (
ServiceInstance,
ServiceOffering,
)
-from servala.frontend.forms.service import ControlPlaneSelectForm, ServiceFilterForm
+from servala.frontend.forms.service import (
+ ControlPlaneSelectForm,
+ ServiceFilterForm,
+ ServiceInstanceFilterForm,
+)
from servala.frontend.views.mixins import HtmxViewMixin, OrganizationViewMixin
@@ -151,11 +155,21 @@ class ServiceInstanceListView(OrganizationViewMixin, ListView):
model = ServiceInstance
permission_type = "view"
+ @cached_property
+ def filter_form(self):
+ return ServiceInstanceFilterForm(data=self.request.GET or None)
+
def get_queryset(self):
- """Return all service instances for the current organization."""
- return ServiceInstance.objects.filter(organization=self.request.organization)
+ """Return all service instances for the current organization with filtering."""
+ queryset = ServiceInstance.objects.filter(
+ organization=self.request.organization
+ )
+ if self.filter_form.is_valid():
+ queryset = self.filter_form.filter_queryset(queryset)
+ return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["organization"] = self.request.organization
+ context["filter_form"] = self.filter_form
return context