1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #9416: Dashboard widgets (#11823)

* Replace masonry with gridstack

* Initial work on dashboard widgets

* Implement function to save dashboard layout

* Define a default dashboard

* Clean up widgets

* Implement widget configuration views & forms

* Permit merging dict value with existing dict in user config

* Add widget deletion view

* Enable HTMX for widget configuration

* Implement view to add dashboard widgets

* ObjectCountsWidget: Identify models by app_label & name

* Add color customization to dashboard widgets

* Introduce Dashboard model to store user dashboard layout & config

* Clean up utility functions

* Remove hard-coded API URL

* Use fixed grid cell height

* Add modal close button

* Clean up dashboard views

* Rebuild JS
This commit is contained in:
Jeremy Stretch
2023-02-24 16:04:00 -05:00
committed by GitHub
parent 36771e821c
commit 084a2cc52c
40 changed files with 788 additions and 310 deletions

View File

@@ -34,6 +34,7 @@ __all__ = (
'ContentTypeSerializer',
'CustomFieldSerializer',
'CustomLinkSerializer',
'DashboardSerializer',
'ExportTemplateSerializer',
'ImageAttachmentSerializer',
'JobResultSerializer',
@@ -563,3 +564,13 @@ class ContentTypeSerializer(BaseModelSerializer):
class Meta:
model = ContentType
fields = ['id', 'url', 'display', 'app_label', 'model']
#
# User dashboard
#
class DashboardSerializer(serializers.ModelSerializer):
class Meta:
model = Dashboard
fields = ('layout', 'config')

View File

@@ -1,3 +1,5 @@
from django.urls import include, path
from netbox.api.routers import NetBoxRouter
from . import views
@@ -22,4 +24,7 @@ router.register('job-results', views.JobResultViewSet)
router.register('content-types', views.ContentTypeViewSet)
app_name = 'extras-api'
urlpatterns = router.urls
urlpatterns = [
path('dashboard/', views.DashboardView.as_view(), name='dashboard'),
path('', include(router.urls)),
]

View File

@@ -4,6 +4,7 @@ from django_rq.queues import get_connection
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
@@ -423,3 +424,15 @@ class ContentTypeViewSet(ReadOnlyModelViewSet):
queryset = ContentType.objects.order_by('app_label', 'model')
serializer_class = serializers.ContentTypeSerializer
filterset_class = filtersets.ContentTypeFilterSet
#
# User dashboard
#
class DashboardView(RetrieveUpdateDestroyAPIView):
queryset = Dashboard.objects.all()
serializer_class = serializers.DashboardSerializer
def get_object(self):
return Dashboard.objects.filter(user=self.request.user).first()