Add service offering detail view

This commit is contained in:
Tobias Kunze 2025-03-24 16:16:23 +01:00 committed by Tobias Brunner
parent ccdc7bd425
commit b7b5e30e7a
No known key found for this signature in database
6 changed files with 65 additions and 8 deletions

View file

@ -298,3 +298,8 @@ class ServiceOffering(models.Model):
class Meta:
verbose_name = _("Service offering")
verbose_name_plural = _("Service offerings")
def __str__(self):
return _("{service_name} at {provider_name}").format(
service_name=self.service.name, provider_name=self.provider.name
)

View file

@ -51,7 +51,7 @@
</div>
<div class="card-footer d-flex justify-content-between">
<span></span>
<a href="{{ offering.pk }}/" class="btn btn-light-primary">{% translate "Read More" %}</a>
<a href="offering/{{ offering.pk }}/" class="btn btn-light-primary">{% translate "Read More" %}</a>
</div>
</div>
{% empty %}

View file

@ -0,0 +1,40 @@
{% extends "frontend/base.html" %}
{% load i18n %}
{% load static %}
{% block html_title %}
{% block page_title %}
{{ offering }}
{% endblock page_title %}
{% endblock html_title %}
{% block content %}
<section class="section">
<div class="card">
<div class="card-header d-flex align-items-center">
{% if service.logo %}
<img src="{{ service.logo.url }}"
alt="{{ service.name }}"
class="me-3"
style="max-width: 48px;
max-height: 48px">
{% endif %}
<div class="d-flex flex-column">
<h4 class="mb-0">{{ offering }}</h4>
<small class="text-muted">{{ offering.service.category }}</small>
</div>
</div>
<div class="card-body">
<div class="row">
{% if offering.control_planes.all.count > 1 %}
<p>{% translate "Please choose your zone." %}</p>
{% else %}
<p>
{% blocktranslate trimmed with zone=offering.control_planes.all.first.name %}
Your zone will be <strong>{{ zone }}</strong>.
{% endblocktranslate %}
</p>
{% endif %}
</div>
</div>
</div>
</section>
{% endblock content %}

View file

@ -28,7 +28,12 @@ urlpatterns = [
path(
"services/<slug:slug>/",
views.ServiceDetailView.as_view(),
name="organization.services",
name="organization.service",
),
path(
"services/<slug:slug>/offering/<int:pk>/",
views.ServiceOfferingDetailView.as_view(),
name="organization.offering",
),
path(
"",

View file

@ -5,7 +5,7 @@ from .organization import (
OrganizationDashboardView,
OrganizationUpdateView,
)
from .service import ServiceDetailView, ServiceListView
from .service import ServiceDetailView, ServiceListView, ServiceOfferingDetailView
__all__ = [
"IndexView",
@ -15,5 +15,6 @@ __all__ = [
"OrganizationUpdateView",
"ServiceDetailView",
"ServiceListView",
"ServiceOfferingDetailView",
"ProfileView",
]

View file

@ -1,7 +1,7 @@
from django.utils.functional import cached_property
from django.views.generic import DetailView, ListView
from servala.core.models import Service
from servala.core.models import Service, ServiceOffering
from servala.frontend.forms.service import ServiceFilterForm
from servala.frontend.views.mixins import OrganizationViewMixin
@ -32,8 +32,6 @@ class ServiceListView(OrganizationViewMixin, ListView):
class ServiceDetailView(OrganizationViewMixin, DetailView):
"""View to display details of a specific service and its offerings."""
template_name = "frontend/organizations/service_detail.html"
context_object_name = "service"
model = Service
@ -46,5 +44,13 @@ class ServiceDetailView(OrganizationViewMixin, DetailView):
)
class ServiceOfferingDetailView:
pass
class ServiceOfferingDetailView(OrganizationViewMixin, DetailView):
template_name = "frontend/organizations/service_offering_detail.html"
context_object_name = "offering"
model = ServiceOffering
permission_type = "view"
def get_queryset(self):
return ServiceOffering.objects.all().select_related(
"service", "service__category", "provider"
)