mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 09:16:10 -06:00
Implement view to add dashboard widgets
This commit is contained in:
parent
b6e17448ff
commit
98732f05aa
@ -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')
|
||||
|
@ -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'),
|
||||
|
||||
|
@ -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'
|
||||
|
||||
|
19
netbox/templates/extras/dashboard/widget_add.html
Normal file
19
netbox/templates/extras/dashboard/widget_add.html
Normal 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>
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user