Implement view to add dashboard widgets

This commit is contained in:
jeremystretch 2023-02-23 14:55:34 -05:00
parent b6e17448ff
commit 98732f05aa
5 changed files with 103 additions and 2 deletions

View File

@ -1,13 +1,33 @@
from django import forms
from django.urls import reverse_lazy
from netbox.registry import registry
from utilities.forms import BootstrapMixin
__all__ = (
'DashboardWidgetAddForm',
'DashboardWidgetForm',
)
def get_widget_choices():
return registry['widgets'].items()
class DashboardWidgetForm(BootstrapMixin, forms.Form):
title = forms.CharField(
required=False
)
class DashboardWidgetAddForm(DashboardWidgetForm):
widget_class = forms.ChoiceField(
choices=get_widget_choices,
widget=forms.Select(
attrs={
'hx-get': reverse_lazy('extras:dashboardwidget_add'),
'hx-target': '#widget_add_form',
}
)
)
field_order = ('widget_class', 'title')

View File

@ -88,6 +88,7 @@ urlpatterns = [
path('changelog/<int:pk>/', include(get_model_urls('extras', 'objectchange'))),
# User dashboard
path('dashboard/widgets/add/', views.DashboardWidgetAddView.as_view(), name='dashboardwidget_add'),
path('dashboard/widgets/<uuid:id>/configure/', views.DashboardWidgetConfigView.as_view(), name='dashboardwidget_config'),
path('dashboard/widgets/<uuid:id>/delete/', views.DashboardWidgetDeleteView.as_view(), name='dashboardwidget_delete'),

View File

@ -9,10 +9,11 @@ from django.views.generic import View
from django_rq.queues import get_connection
from rq import Worker
from extras.dashboard.forms import DashboardWidgetForm
from extras.dashboard.forms import DashboardWidgetAddForm, DashboardWidgetForm
from extras.dashboard.utils import get_widget_class_and_config
from netbox.registry import registry
from netbox.views import generic
from utilities.forms import ConfirmationForm
from utilities.forms import ConfirmationForm, get_field_value
from utilities.htmx import is_htmx
from utilities.utils import copy_safe_request, count_related, get_viewname, normalize_querydict, shallow_compare_dict
from utilities.views import ContentTypePermissionRequiredMixin, register_model_view
@ -672,6 +673,57 @@ class JournalEntryBulkDeleteView(generic.BulkDeleteView):
# Dashboard widgets
#
class DashboardWidgetAddView(LoginRequiredMixin, View):
template_name = 'extras/dashboard/widget_add.html'
def get(self, request):
initial = request.GET or {
'widget_class': 'extras.NoteWidget',
}
widget_form = DashboardWidgetAddForm(initial=initial)
widget_name = get_field_value(widget_form, 'widget_class')
widget_class = registry['widgets'][widget_name]
config_form = widget_class.ConfigForm(prefix='config')
if not is_htmx(request):
return redirect('home')
return render(request, self.template_name, {
'widget_form': widget_form,
'config_form': config_form,
})
def post(self, request):
widget_form = DashboardWidgetAddForm(request.POST)
if widget_form.is_valid():
widget_class = registry['widgets'][widget_form.cleaned_data['widget_class']]
config_form = widget_class.ConfigForm(request.POST, prefix='config')
if config_form.is_valid():
data = widget_form.cleaned_data
class_name = data.pop('widget_class')
data['config'] = config_form.cleaned_data
widget = widget_class(**data)
data['class'] = class_name
request.user.config.set(f'dashboard.widgets.{widget.id}', data)
request.user.config.get(f'dashboard.layout').append({
'h': widget.height,
'w': widget.width,
'id': str(widget.id),
})
request.user.config.save()
response = HttpResponse()
response['HX-Redirect'] = reverse('home')
return response
return render(request, self.template_name, {
'widget_form': widget_form,
'config_form': config_form,
})
class DashboardWidgetConfigView(LoginRequiredMixin, View):
template_name = 'extras/dashboard/widget_config.html'

View File

@ -0,0 +1,19 @@
{% load form_helpers %}
<form hx-post="{% url 'extras:dashboardwidget_add' %}" id="widget_add_form">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title">Add a Widget</h5>
</div>
<div class="modal-body">
{% block form %}
{% render_form widget_form %}
{% render_form config_form %}
{% endblock form %}
</div>
<div class="modal-footer">
{% block buttons %}
<button class="btn btn-primary">Save</button>
{% endblock buttons %}
</div>
</form>

View File

@ -30,6 +30,15 @@
{% endfor %}
</div>
<div class="text-end px-2">
<a href="#"
hx-get="{% url 'extras:dashboardwidget_add' %}"
hx-target="#htmx-modal-content"
data-bs-toggle="modal"
data-bs-target="#htmx-modal"
class="btn btn-success btn-sm"
>
<i class="mdi mdi-plus"></i> Add Widget
</a>
<button id="save_dashboard" class="btn btn-primary btn-sm">
<i class="mdi mdi-content-save-outline"></i> Save
</button>