Implement view logic
This commit is contained in:
parent
ef4f76b290
commit
2a63677539
1 changed files with 87 additions and 6 deletions
|
|
@ -14,6 +14,7 @@ from servala.core.models import (
|
|||
ServiceOffering,
|
||||
)
|
||||
from servala.frontend.forms.service import (
|
||||
ComputePlanSelectionForm,
|
||||
ControlPlaneSelectForm,
|
||||
ServiceFilterForm,
|
||||
ServiceInstanceDeleteForm,
|
||||
|
|
@ -152,6 +153,13 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
|||
control_plane=self.selected_plane, service_offering=self.object
|
||||
).first()
|
||||
|
||||
@cached_property
|
||||
def plan_form(self):
|
||||
data = self.request.POST if self.request.method == "POST" else None
|
||||
return ComputePlanSelectionForm(
|
||||
data=data, control_plane_crd=self.context_object, prefix="plans"
|
||||
)
|
||||
|
||||
def get_instance_form_kwargs(self, ignore_data=False):
|
||||
return {
|
||||
"initial": {
|
||||
|
|
@ -205,6 +213,7 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
|||
context["select_form"] = self.select_form
|
||||
context["has_control_planes"] = self.planes.exists()
|
||||
context["selected_plane"] = self.selected_plane
|
||||
context["context_object"] = self.context_object
|
||||
context["hide_expert_mode"] = self.hide_expert_mode
|
||||
if self.request.method == "POST":
|
||||
if self.is_custom_form:
|
||||
|
|
@ -222,6 +231,17 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
|||
if self.selected_plane and self.selected_plane.wildcard_dns:
|
||||
context["wildcard_dns"] = self.selected_plane.wildcard_dns
|
||||
context["organization_namespace"] = self.request.organization.namespace
|
||||
|
||||
if self.context_object:
|
||||
context["plan_form"] = self.plan_form
|
||||
context["has_available_plans"] = self.plan_form.fields[
|
||||
"compute_plan_assignment"
|
||||
].queryset.exists()
|
||||
if self.context_object.control_plane.storage_plan_price_per_gib:
|
||||
context["storage_plan"] = {
|
||||
"price_per_gib": self.context_object.control_plane.storage_plan_price_per_gib,
|
||||
}
|
||||
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
|
@ -232,6 +252,9 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
|||
context["form_error"] = True
|
||||
return self.render_to_response(context)
|
||||
|
||||
if not self.plan_form.is_valid():
|
||||
return self.render_to_response(context)
|
||||
|
||||
if self.is_custom_form:
|
||||
form = self.get_custom_instance_form()
|
||||
else:
|
||||
|
|
@ -245,7 +268,11 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
|||
)
|
||||
return self.render_to_response(context)
|
||||
|
||||
if form.is_valid():
|
||||
if form.is_valid() and self.plan_form.is_valid():
|
||||
compute_plan_assignment = self.plan_form.cleaned_data[
|
||||
"compute_plan_assignment"
|
||||
]
|
||||
|
||||
try:
|
||||
service_instance = ServiceInstance.create_instance(
|
||||
organization=self.request.organization,
|
||||
|
|
@ -253,16 +280,22 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
|||
context=self.context_object,
|
||||
created_by=request.user,
|
||||
spec_data=form.get_nested_data().get("spec"),
|
||||
compute_plan_assignment=compute_plan_assignment,
|
||||
)
|
||||
return redirect(service_instance.urls.base)
|
||||
except ValidationError as e:
|
||||
form.add_error(None, e.message or str(e))
|
||||
except Exception as e:
|
||||
error_message = self.organization.add_support_message(
|
||||
_(f"Error creating instance: {str(e)}.")
|
||||
_("Error creating instance: {error}.").format(error=str(e))
|
||||
)
|
||||
form.add_error(None, error_message)
|
||||
|
||||
if self.is_custom_form:
|
||||
context["custom_service_form"] = form
|
||||
else:
|
||||
context["service_form"] = form
|
||||
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
|
|
@ -332,6 +365,18 @@ class ServiceInstanceDetailView(
|
|||
context["has_delete_permission"] = self.request.user.has_perm(
|
||||
ServiceInstance.get_perm("delete"), self.object
|
||||
)
|
||||
|
||||
if self.object.compute_plan_assignment:
|
||||
context["compute_plan_assignment"] = self.object.compute_plan_assignment
|
||||
|
||||
if (
|
||||
self.object.context
|
||||
and self.object.context.control_plane.storage_plan_price_per_gib
|
||||
):
|
||||
context["storage_plan"] = {
|
||||
"price_per_gib": self.object.context.control_plane.storage_plan_price_per_gib,
|
||||
}
|
||||
|
||||
return context
|
||||
|
||||
def get_nested_spec(self):
|
||||
|
|
@ -475,6 +520,17 @@ class ServiceInstanceUpdateView(
|
|||
kwargs.pop("data", None)
|
||||
return cls(**kwargs)
|
||||
|
||||
@cached_property
|
||||
def plan_form(self):
|
||||
data = self.request.POST if self.request.method == "POST" else None
|
||||
initial = self.object.compute_plan_assignment if self.object else None
|
||||
return ComputePlanSelectionForm(
|
||||
data=data,
|
||||
control_plane_crd=self.object.context if self.object else None,
|
||||
prefix="plans",
|
||||
initial={"compute_plan_assignment": initial} if initial else None,
|
||||
)
|
||||
|
||||
@property
|
||||
def is_custom_form(self):
|
||||
# Note: "custom form" = user-friendly, subset of fields
|
||||
|
|
@ -489,7 +545,7 @@ class ServiceInstanceUpdateView(
|
|||
else:
|
||||
form = self.get_form()
|
||||
|
||||
if form.is_valid():
|
||||
if form.is_valid() and self.plan_form.is_valid():
|
||||
return self.form_valid(form)
|
||||
return self.form_invalid(form)
|
||||
|
||||
|
|
@ -506,14 +562,29 @@ class ServiceInstanceUpdateView(
|
|||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["hide_expert_mode"] = self.hide_expert_mode
|
||||
|
||||
# Check if a form was passed (e.g., from form_invalid)
|
||||
form_from_kwargs = kwargs.get("form")
|
||||
|
||||
if self.request.method == "POST":
|
||||
if self.is_custom_form:
|
||||
context["custom_form"] = self.get_custom_form()
|
||||
# Use the form with errors if passed, otherwise create new
|
||||
context["custom_form"] = form_from_kwargs or self.get_custom_form()
|
||||
context["form"] = self.get_form(ignore_data=True)
|
||||
else:
|
||||
# Use the form with errors if passed, otherwise create new
|
||||
context["form"] = form_from_kwargs or self.get_form()
|
||||
context["custom_form"] = self.get_custom_form(ignore_data=True)
|
||||
else:
|
||||
context["custom_form"] = self.get_custom_form()
|
||||
|
||||
if self.object and self.object.context:
|
||||
context["plan_form"] = self.plan_form
|
||||
if self.object.context.control_plane.storage_plan_price_per_gib:
|
||||
context["storage_plan"] = {
|
||||
"price_per_gib": self.object.context.control_plane.storage_plan_price_per_gib,
|
||||
}
|
||||
|
||||
return context
|
||||
|
||||
def _deep_merge(self, base, update):
|
||||
|
|
@ -533,7 +604,17 @@ class ServiceInstanceUpdateView(
|
|||
current_spec = dict(self.object.spec) if self.object.spec else {}
|
||||
spec_data = self._deep_merge(current_spec, spec_data)
|
||||
|
||||
self.object.update_spec(spec_data=spec_data, updated_by=self.request.user)
|
||||
compute_plan_assignment = None
|
||||
if self.plan_form.is_valid():
|
||||
compute_plan_assignment = self.plan_form.cleaned_data.get(
|
||||
"compute_plan_assignment"
|
||||
)
|
||||
|
||||
self.object.update_spec(
|
||||
spec_data=spec_data,
|
||||
updated_by=self.request.user,
|
||||
compute_plan_assignment=compute_plan_assignment,
|
||||
)
|
||||
messages.success(
|
||||
self.request,
|
||||
_("Service instance '{name}' updated successfully.").format(
|
||||
|
|
@ -546,7 +627,7 @@ class ServiceInstanceUpdateView(
|
|||
return self.form_invalid(form)
|
||||
except Exception as e:
|
||||
error_message = self.organization.add_support_message(
|
||||
_(f"Error updating instance: {str(e)}.")
|
||||
_("Error updating instance: {error}.").format(error=str(e))
|
||||
)
|
||||
form.add_error(None, error_message)
|
||||
return self.form_invalid(form)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue