diff --git a/src/servala/core/crd.py b/src/servala/core/crd.py deleted file mode 100644 index bf22bcc..0000000 --- a/src/servala/core/crd.py +++ /dev/null @@ -1,125 +0,0 @@ -import re - -from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator -from django.db import models -from django.forms.models import ModelForm, ModelFormMetaclass -from django.utils.translation import gettext_lazy as _ - - -def generate_django_model(schema, group, version, kind): - """ - Generates a virtual Django model from a Kubernetes CRD's OpenAPI v3 schema. - """ - spec = schema["properties"].get("spec") or {} - # defaults = {"apiVersion": f"{group}/{version}", "kind": kind} - - model_fields = {"__module__": "crd_models"} - model_fields.update(build_object_fields(spec, "spec")) - - meta_class = type("Meta", (), {"app_label": "crd_models"}) - model_fields["Meta"] = meta_class - - # create the model class - model_name = kind - model_class = type(model_name, (models.Model,), model_fields) - return model_class - - -def build_object_fields(schema, name, verbose_name_prefix=None): - required_fields = schema.get("required", []) - properties = schema.get("properties", {}) - fields = {} - - for field_name, field_schema in properties.items(): - is_required = field_name in required_fields - full_name = f"{name}.{field_name}" - result = get_django_field( - field_schema, - is_required, - field_name, - full_name, - verbose_name_prefix=verbose_name_prefix, - ) - if isinstance(result, dict): - fields.update(result) - else: - fields[full_name] = result - return fields - - -def deslugify(title): - if "_" in title: - title.replace("_", " ") - return title.title() - return re.sub(r"(? - {% translate "Oops! Something went wrong with the service form generation. Please try again later." %} - - {% else %} - {% include "includes/form.html" with form=service_form %} - {% endif %} -{% endif %} -{% endpartialdef %} {% block content %}
@@ -35,16 +23,17 @@
- {% if offering.control_planes.all.count == 0 %} -

{% translate "We currently cannot offer this service, sorry!" %}

- {% else %} -
- {{ select_form }} -
-
{% partial service-form %}
- {% endif %} +
+ {% if offering.control_planes.all.count > 1 %} +

{% translate "Please choose your zone." %}

+ {% else %} +

+ {% blocktranslate trimmed with zone=offering.control_planes.all.first.name %} + Your zone will be {{ zone }}. + {% endblocktranslate %} +

+ {% endif %} +
diff --git a/src/servala/frontend/views/mixins.py b/src/servala/frontend/views/mixins.py index fd5a494..f304e42 100644 --- a/src/servala/frontend/views/mixins.py +++ b/src/servala/frontend/views/mixins.py @@ -5,30 +5,13 @@ from rules.contrib.views import AutoPermissionRequiredMixin, PermissionRequiredM from servala.core.models import Organization -class HtmxViewMixin: +class HtmxUpdateView(AutoPermissionRequiredMixin, UpdateView): fragments = [] @cached_property def is_htmx(self): return self.request.headers.get("HX-Request") - def _get_fragment(self): - if self.request.method == "POST": - fragment = self.request.POST.get("fragment") - else: - fragment = self.request.GET.get("fragment") - if fragment and fragment in self.fragments: - return fragment - - def get_template_names(self): - template_names = super().get_template_names() - if self.is_htmx and (fragment := self._get_fragment()): - return [f"{template_names[0]}#{fragment}"] - return template_names - - -class HtmxUpdateView(AutoPermissionRequiredMixin, HtmxViewMixin, UpdateView): - @property def permission_type(self): if self.request.method == "POST" or getattr( @@ -48,6 +31,20 @@ class HtmxUpdateView(AutoPermissionRequiredMixin, HtmxViewMixin, UpdateView): result["has_change_permission"] = self.has_change_permission() return result + def _get_fragment(self): + if self.request.method == "POST": + fragment = self.request.POST.get("fragment") + else: + fragment = self.request.GET.get("fragment") + if fragment and fragment in self.fragments: + return fragment + + def get_template_names(self): + template_names = super().get_template_names() + if self.is_htmx and (fragment := self._get_fragment()): + return [f"{template_names[0]}#{fragment}"] + return template_names + def get_form_kwargs(self): result = super().get_form_kwargs() if self.is_htmx: @@ -85,8 +82,8 @@ class OrganizationViewMixin(PermissionRequiredMixin): def get_permission_object(self): return self.organization - def has_organization_permission(self): - return self.request.user.has_perm("core.view_organization", self.organization) - def has_permission(self): - return self.has_organization_permission() and super().has_permission() + return ( + self.request.user.has_perm("core.view_organization", self.organization) + and super().has_permission() + ) diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index faead0f..f5c33f0 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -1,9 +1,9 @@ from django.utils.functional import cached_property from django.views.generic import DetailView, ListView -from servala.core.models import Service, ServiceOffering, ServiceOfferingControlPlane -from servala.frontend.forms.service import ControlPlaneSelectForm, ServiceFilterForm -from servala.frontend.views.mixins import HtmxViewMixin, OrganizationViewMixin +from servala.core.models import Service, ServiceOffering +from servala.frontend.forms.service import ServiceFilterForm +from servala.frontend.views.mixins import OrganizationViewMixin class ServiceListView(OrganizationViewMixin, ListView): @@ -44,43 +44,13 @@ class ServiceDetailView(OrganizationViewMixin, DetailView): ) -class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView): +class ServiceOfferingDetailView(OrganizationViewMixin, DetailView): template_name = "frontend/organizations/service_offering_detail.html" context_object_name = "offering" model = ServiceOffering permission_type = "view" - fragments = ("service-form",) - - def has_permission(self): - return self.has_organization_permission() def get_queryset(self): return ServiceOffering.objects.all().select_related( "service", "service__category", "provider" ) - - @cached_property - def planes(self): - return self.object.control_planes.all() - - @cached_property - def select_form(self): - data = None - if "control_plane" in self.request.GET: - data = self.request.GET - return ControlPlaneSelectForm(data=data, planes=self.planes) - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["select_form"] = self.select_form - if "control_plane" in self.request.GET: - if self.select_form.is_valid(): - so_cp = ServiceOfferingControlPlane.objects.filter( - control_plane=self.select_form.cleaned_data["control_plane"], - service_offering=self.object, - ).first() - if not so_cp: - context["form_error"] = True - else: - context["service_form"] = so_cp.model_form_class() - return context