Skip to content

Commit

Permalink
[Enhancement] Add service details page
Browse files Browse the repository at this point in the history
  • Loading branch information
elias-boulharts committed Nov 20, 2023
1 parent f5a7144 commit 3cb5657
Show file tree
Hide file tree
Showing 26 changed files with 235 additions and 196 deletions.
19 changes: 2 additions & 17 deletions service_catalog/forms/operation_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,10 @@
from service_catalog.models import Operation


class ServiceOperationForm(SquestModelForm):
def __init__(self, *args, **kwargs):
self.service = kwargs.pop("service")
super(ServiceOperationForm, self).__init__(*args, **kwargs)
choice_type = [('CREATE', 'Create'), ('UPDATE', 'Update'), ('DELETE', 'Delete')]
# Default behavior
self.fields['type'].choices = choice_type
self.fields['type'].initial = self.fields['type'].choices[0]

def save(self, commit=True):
new_operation = super(ServiceOperationForm, self).save(commit=False)
new_operation.service = self.service
new_operation.save()
return new_operation


class OperationForm(SquestModelForm):
class Meta:
model = Operation
fields = ["name", "description", "job_template", "type", "process_timeout_second",
fields = ["service", "name", "description", "job_template", "type", "process_timeout_second",
"auto_accept", "auto_process", "enabled", "is_admin_operation", "extra_vars", "default_inventory_id",
"default_limits", "default_tags", "default_skip_tags", "default_credentials_ids", "default_verbosity",
"default_diff_mode", "default_job_type"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.6 on 2023-11-20 11:01

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('service_catalog', '0031_service_attribute_definitions'),
]

operations = [
migrations.AlterField(
model_name='operation',
name='name',
field=models.CharField(max_length=100),
),
migrations.AlterField(
model_name='operation',
name='type',
field=models.CharField(choices=[('CREATE', 'Create'), ('UPDATE', 'Update'), ('DELETE', 'Delete')], default='CREATE', max_length=10),
),
]
5 changes: 2 additions & 3 deletions service_catalog/models/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@


class Operation(SquestModel):
name = CharField(max_length=100, verbose_name="Operation name")
name = CharField(max_length=100)
description = CharField(max_length=500, blank=True, null=True)
type = CharField(
max_length=10,
choices=OperationType.choices,
default=OperationType.CREATE,
verbose_name="Operation type"
)
service = ForeignKey(Service, on_delete=CASCADE, related_name="operations",
related_query_name="operation")
Expand Down Expand Up @@ -55,7 +54,7 @@ def __str__(self):
return f"{self.name} ({self.service})"

def get_absolute_url(self):
return reverse(f"service_catalog:operation_details", args=[self.service.id, self.pk])
return reverse(f"service_catalog:operation_details", args=[self.pk])

def clean(self):
if self.extra_vars is None or not isinstance(self.extra_vars, dict):
Expand Down
4 changes: 0 additions & 4 deletions service_catalog/models/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from django.db.models import CharField, ImageField, BooleanField, ForeignKey, SET_NULL, JSONField, ManyToManyField
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _

from Squest.utils.squest_model import SquestModel
Expand Down Expand Up @@ -39,9 +38,6 @@ class Meta:
help_text="List of attributes linked to the service, they could be used on operation fields.",
)

def get_absolute_url(self):
return reverse_lazy('service_catalog:operation_list', kwargs={"service_id": self.id})

def can_be_enabled(self):
operation_create_list = self.operations.filter(type=OperationType.CREATE, enabled=True)
if operation_create_list.exists():
Expand Down
2 changes: 1 addition & 1 deletion service_catalog/tables/operation_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Meta:
auto_accept = TemplateColumn(template_name='generics/custom_columns/generic_boolean.html')
auto_process = TemplateColumn(template_name='generics/custom_columns/generic_boolean.html')
is_admin_operation = TemplateColumn(template_name='generics/custom_columns/generic_boolean.html')
actions = TemplateColumn(template_name='service_catalog/custom_columns/operation_actions.html', orderable=False)
actions = TemplateColumn(template_name='generics/custom_columns/generic_actions.html', orderable=False)


class OperationTableFromInstanceDetails(SquestTable):
Expand Down
3 changes: 2 additions & 1 deletion service_catalog/tables/service_tables.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django_tables2 import TemplateColumn
from django_tables2 import TemplateColumn, LinkColumn

from Squest.utils.squest_table import SquestTable
from service_catalog.models import Service
Expand All @@ -9,6 +9,7 @@ class ServiceTable(SquestTable):
enabled = TemplateColumn(template_name='generics/custom_columns/generic_boolean_check.html')
operations = TemplateColumn(template_name='service_catalog/custom_columns/service_operations.html',
verbose_name="Operations", orderable=False)
name = LinkColumn()

class Meta:
model = Service
Expand Down
13 changes: 7 additions & 6 deletions service_catalog/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@
path('service/create/', views.ServiceCreateView.as_view(), name='service_create'),
path('service/<int:pk>/edit/', views.ServiceEditView.as_view(), name='service_edit'),
path('service/<int:pk>/delete/', views.ServiceDeleteView.as_view(), name='service_delete'),
path('service/<int:pk>/', views.ServiceDetailView.as_view(), name='service_details'),

# Operation CRUD
path('service/<int:service_id>/operation/', views.OperationListView.as_view(), name='operation_list'),
path('service/<int:service_id>/operation/create/', views.OperationCreateView.as_view(), name='operation_create'),
path('service/<int:service_id>/operation/<int:pk>/delete/', views.OperationDeleteView.as_view(), name='operation_delete'),
path('service/<int:service_id>/operation/<int:pk>/edit/', views.OperationEditView.as_view(), name='operation_edit'),
path('service/<int:service_id>/operation/<int:pk>/', views.OperationDetailView.as_view(), name='operation_details'),
path('operation/', views.OperationListView.as_view(), name='operation_list'),
path('operation/create/', views.OperationCreateView.as_view(), name='operation_create'),
path('operation/<int:pk>/delete/', views.OperationDeleteView.as_view(), name='operation_delete'),
path('operation/<int:pk>/edit/', views.OperationEditView.as_view(), name='operation_edit'),
path('operation/<int:pk>/', views.OperationDetailView.as_view(), name='operation_details'),

# Request operation endpoints
path('service/<int:service_id>/operation/<int:operation_id>/request/',
Expand All @@ -63,7 +64,7 @@
name='create_operation_list'),

# Edit operation survey endpoint
path('service/<int:service_id>/operation/<int:pk>/survey/', views.operation_edit_survey, name='operation_edit_survey'),
path('operation/<int:pk>/survey/', views.operation_edit_survey, name='operation_edit_survey'),

# Instance CRUD
path('instance/', views.InstanceListView.as_view(), name='instance_list'),
Expand Down
113 changes: 27 additions & 86 deletions service_catalog/views/operation.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,58 @@
from django.shortcuts import redirect, get_object_or_404
from django.shortcuts import redirect
from Squest.utils.squest_table import SquestRequestConfig

from Squest.utils.squest_views import *
from service_catalog.filters.operation_filter import OperationFilter, OperationFilterLimited
from service_catalog.forms import ServiceOperationForm
from service_catalog.forms import OperationForm
from service_catalog.models import Operation, Service, OperationType, ApprovalWorkflow
from service_catalog.tables.approval_workflow_table import ApprovalWorkflowTable
from service_catalog.tables.operation_tables import OperationTable, CreateOperationTable


def get_breadcrumbs_for_operation(operation):
breadcrumbs = [
{'text': 'Service catalog', 'url': reverse('service_catalog:service_catalog_list')},
{'text': 'Service', 'url': reverse('service_catalog:service_list')},
{'text': operation.service, 'url': operation.service.get_absolute_url()},
{'text': 'Operation', 'url': ''},
]
if operation is not None:
breadcrumbs.append({'text': operation, 'url': operation.get_absolute_url()})
return breadcrumbs


class OperationListView(SquestListView):
model = Operation
filterset_class = OperationFilter
table_class = OperationTable

def get_generic_url_kwargs(self):
return {'service_id': self.kwargs.get('service_id')}

def get_queryset(self):
return super().get_queryset().filter(service__id=self.kwargs.get('service_id'))

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['breadcrumbs'] = [
{'text': 'Service catalog', 'url': reverse('service_catalog:service_catalog_list')},
{'text': 'Services', 'url': reverse('service_catalog:service_list')},
{'text': Service.objects.get(id=self.kwargs.get('service_id')), 'url': ""},
{'text': 'Operations', 'url': ""},
]
return context


class OperationCreateView(SquestCreateView):
model = Operation
form_class = ServiceOperationForm
form_class = OperationForm

def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
self.service = get_object_or_404(Service, pk=self.kwargs.get('service_id'))
kwargs['service'] = self.service
return kwargs
def get_initial(self):
initial = super().get_initial()
initial["service"] = f"{self.request.GET.get('service')}"
return initial.copy()

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['breadcrumbs'] = [
{'text': 'Service catalog', 'url': reverse('service_catalog:service_catalog_list')},
{'text': 'Services', 'url': reverse('service_catalog:service_list')},
{'text': self.service, 'url': reverse('service_catalog:operation_list', args=[self.service.id])},
{'text': 'Create a new operation', 'url': ""},
{'text': 'Operation', 'url': reverse('service_catalog:operation_list')},
{'text': 'New operation', 'url': ""},
]
return context

def get_success_url(self):
return reverse("service_catalog:operation_edit_survey", kwargs={"service_id": self.service.id,
"pk": self.object.id})


class OperationDetailView(SquestDetailView):
model = Operation

def get_queryset(self):
return super().get_queryset().filter(service__id=self.kwargs.get('service_id'))

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
config = SquestRequestConfig(self.request)

context['breadcrumbs'] = [
{
'text': 'Service catalog',
'url': reverse('service_catalog:service_catalog_list')
},
{
'text': 'Service',
'url': reverse('service_catalog:service_list')
},
{
'text': self.get_object().service,
'url': reverse('service_catalog:operation_list',
args=[self.get_object().service.id])
},
{
'text': self.get_object(),
'url': ''
}
]
context['breadcrumbs'] = get_breadcrumbs_for_operation(self.get_object())
context['extra_html_button_path'] = "service_catalog/buttons/operation_survey_button.html"
if self.request.user.has_perm('service_catalog.view_approvalworkflow'):
context['workflows_table'] = ApprovalWorkflowTable(
Expand All @@ -97,49 +65,22 @@ def get_context_data(self, **kwargs):

class OperationEditView(SquestUpdateView):
model = Operation
form_class = ServiceOperationForm

def get_queryset(self):
return super().get_queryset().filter(service__id=self.kwargs.get('service_id'))

def get_success_url(self):
return self.get_object().service.get_absolute_url()

def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['service'] = self.get_object().service
return kwargs
form_class = OperationForm

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['breadcrumbs'] = [
{'text': 'Service catalog', 'url': reverse('service_catalog:service_catalog_list')},
{'text': 'Services', 'url': reverse('service_catalog:service_list')},
{'text': self.get_object().service,
'url': reverse('service_catalog:operation_list', args=[self.get_object().service.id])},
{'text': self.get_object(), 'url': ""},
]
context['breadcrumbs'] = get_breadcrumbs_for_operation(self.get_object())
context['breadcrumbs'].append({'text': 'Edit', 'url': ''})
return context


class OperationDeleteView(SquestDeleteView):
model = Operation

def get_queryset(self):
return super().get_queryset().filter(service__id=self.kwargs.get('service_id'))

def get_generic_url_kwargs(self):
return {'service_id': self.kwargs.get('service_id')}

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['breadcrumbs'] = [
{'text': 'Service catalog', 'url': reverse('service_catalog:service_catalog_list')},
{'text': 'Services', 'url': reverse('service_catalog:service_list')},
{'text': self.get_object().service,
'url': reverse('service_catalog:operation_list', args=[self.get_object().service.id])},
{'text': self.get_object(), 'url': ""},
]
context['breadcrumbs'] = get_breadcrumbs_for_operation(self.get_object())
context['breadcrumbs'].append({'text': 'Delete', 'url': ''})
return context


Expand Down
Loading

0 comments on commit 3cb5657

Please sign in to comment.