mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
* 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:
@ -1,6 +1,7 @@
|
||||
from .change_logging import ObjectChange
|
||||
from .configs import *
|
||||
from .customfields import CustomField
|
||||
from .dashboard import *
|
||||
from .models import *
|
||||
from .search import *
|
||||
from .staging import *
|
||||
@ -15,6 +16,7 @@ __all__ = (
|
||||
'ConfigTemplate',
|
||||
'CustomField',
|
||||
'CustomLink',
|
||||
'Dashboard',
|
||||
'ExportTemplate',
|
||||
'ImageAttachment',
|
||||
'JobResult',
|
||||
|
70
netbox/extras/models/dashboard.py
Normal file
70
netbox/extras/models/dashboard.py
Normal file
@ -0,0 +1,70 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
|
||||
from extras.dashboard.utils import get_widget_class
|
||||
|
||||
__all__ = (
|
||||
'Dashboard',
|
||||
)
|
||||
|
||||
|
||||
class Dashboard(models.Model):
|
||||
user = models.OneToOneField(
|
||||
to=get_user_model(),
|
||||
on_delete=models.CASCADE,
|
||||
related_name='dashboard'
|
||||
)
|
||||
layout = models.JSONField()
|
||||
config = models.JSONField()
|
||||
|
||||
class Meta:
|
||||
pass
|
||||
|
||||
def get_widget(self, id):
|
||||
"""
|
||||
Instantiate and return a widget by its ID
|
||||
"""
|
||||
id = str(id)
|
||||
config = dict(self.config[id]) # Copy to avoid mutating instance data
|
||||
widget_class = get_widget_class(config.pop('class'))
|
||||
return widget_class(id=id, **config)
|
||||
|
||||
def get_layout(self):
|
||||
"""
|
||||
Return the dashboard's configured layout, suitable for rendering with gridstack.js.
|
||||
"""
|
||||
widgets = []
|
||||
for grid_item in self.layout:
|
||||
widget = self.get_widget(grid_item['id'])
|
||||
widget.set_layout(grid_item)
|
||||
widgets.append(widget)
|
||||
return widgets
|
||||
|
||||
def add_widget(self, widget, x=None, y=None):
|
||||
"""
|
||||
Add a widget to the dashboard, optionally specifying its X & Y coordinates.
|
||||
"""
|
||||
id = str(widget.id)
|
||||
self.config[id] = {
|
||||
'class': widget.name,
|
||||
'title': widget.title,
|
||||
'color': widget.color,
|
||||
'config': widget.config,
|
||||
}
|
||||
self.layout.append({
|
||||
'id': id,
|
||||
'h': widget.height,
|
||||
'w': widget.width,
|
||||
'x': x,
|
||||
'y': y,
|
||||
})
|
||||
|
||||
def delete_widget(self, id):
|
||||
"""
|
||||
Delete a widget from the dashboard.
|
||||
"""
|
||||
id = str(id)
|
||||
del self.config[id]
|
||||
self.layout = [
|
||||
item for item in self.layout if item['id'] != id
|
||||
]
|
Reference in New Issue
Block a user