Skip to content

Commit

Permalink
#9416: cleanup & widget improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremystretch committed Mar 22, 2023
1 parent a098c3b commit e176c7d
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 20 deletions.
72 changes: 67 additions & 5 deletions netbox/extras/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,73 @@

# Dashboard
DEFAULT_DASHBOARD = [
{
'widget': 'extras.ObjectCountsWidget',
'width': 4,
'height': 2,
'title': 'Organization',
'config': {
'models': [
'dcim.site',
'tenancy.tenant',
'tenancy.contact',
]
}
},
{
'widget': 'extras.ObjectCountsWidget',
'width': 4,
'height': 3,
'title': 'IPAM',
'config': {
'models': [
'ipam.vrf',
'ipam.aggregate',
'ipam.prefix',
'ipam.iprange',
'ipam.ipaddress',
'ipam.vlan',
]
}
},
{
'widget': 'extras.NoteWidget',
'width': 4,
'height': 2,
'title': 'Welcome!',
'color': 'green',
'config': {
'content': (
'This is your personal dashboard. Feel free to customize it by rearranging, resizing, or removing '
'widgets. You can also add new widgets using the "add widget" button below. Any changes affect only '
'_your_ dashboard, so feel free to experiment!'
)
}
},
{
'widget': 'extras.ObjectCountsWidget',
'width': 4,
'height': 2,
'title': 'Circuits',
'config': {
'models': [
'circuits.provider',
'circuits.circuit',
'circuits.providernetwork',
]
}
},
{
'widget': 'extras.RSSFeedWidget',
'width': 4,
'height': 4,
'title': 'NetBox News',
'config': {
'feed_url': 'http://netbox.dev/rss/',
'max_entries': 10,
'cache_timeout': 14400,
}
},
{
'widget': 'extras.ObjectCountsWidget',
'width': 4,
Expand All @@ -41,25 +95,33 @@
'models': [
'dcim.site',
'dcim.rack',
'dcim.devicetype',
'dcim.device',
]
'dcim.cable',
],
}
},
{
'widget': 'extras.NoteWidget',
'widget': 'extras.ObjectCountsWidget',
'width': 4,
'height': 3,
'height': 2,
'title': 'Virtualization',
'config': {
'content': 'Welcome to **NetBox**!'
'models': [
'virtualization.cluster',
'virtualization.virtualmachine',
]
}
},
{
'widget': 'extras.ObjectListWidget',
'width': 12,
'height': 6,
'height': 5,
'title': 'Change Log',
'color': 'blue',
'config': {
'model': 'extras.objectchange',
'page_size': 25,
}
},
]
4 changes: 3 additions & 1 deletion netbox/extras/dashboard/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django import forms
from django.urls import reverse_lazy
from django.utils.translation import gettext as _

from netbox.registry import registry
from utilities.forms import BootstrapMixin, add_blank_choice
Expand Down Expand Up @@ -33,6 +34,7 @@ class DashboardWidgetAddForm(DashboardWidgetForm):
'hx-get': reverse_lazy('extras:dashboardwidget_add'),
'hx-target': '#widget_add_form',
}
)
),
label=_('Widget type')
)
field_order = ('widget_class', 'title', 'color')
6 changes: 2 additions & 4 deletions netbox/extras/dashboard/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ def get_dashboard(user):

def get_default_dashboard():
from extras.models import Dashboard
dashboard = Dashboard(
layout=[],
config={}
)
dashboard = Dashboard()
for widget in DEFAULT_DASHBOARD:
id = str(uuid.uuid4())
dashboard.layout.append({
Expand All @@ -70,6 +67,7 @@ def get_default_dashboard():
dashboard.config[id] = {
'class': widget['widget'],
'title': widget.get('title'),
'color': widget.get('color'),
'config': widget.get('config', {}),
}

Expand Down
13 changes: 13 additions & 0 deletions netbox/extras/dashboard/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.template.loader import render_to_string
from django.urls import NoReverseMatch, reverse
from django.utils.translation import gettext as _

from utilities.forms import BootstrapMixin
Expand Down Expand Up @@ -126,14 +127,26 @@ class ConfigForm(BootstrapMixin, forms.Form):
model = forms.ChoiceField(
choices=get_content_type_labels
)
page_size = forms.IntegerField(
required=False,
min_value=1,
max_value=100,
help_text=_('The default number of objects to display')
)

def render(self, request):
app_label, model_name = self.config['model'].split('.')
content_type = ContentType.objects.get_by_natural_key(app_label, model_name)
viewname = get_viewname(content_type.model_class(), action='list')
try:
htmx_url = reverse(viewname)
except NoReverseMatch:
htmx_url = None

return render_to_string(self.template_name, {
'viewname': viewname,
'htmx_url': htmx_url,
'page_size': self.config.get('page_size'),
})


Expand Down
4 changes: 2 additions & 2 deletions netbox/extras/migrations/0087_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class Migration(migrations.Migration):
name='Dashboard',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
('layout', models.JSONField()),
('config', models.JSONField()),
('layout', models.JSONField(default=list)),
('config', models.JSONField(default=dict)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='dashboard', to=settings.AUTH_USER_MODEL)),
],
),
Expand Down
8 changes: 6 additions & 2 deletions netbox/extras/models/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ class Dashboard(models.Model):
on_delete=models.CASCADE,
related_name='dashboard'
)
layout = models.JSONField()
config = models.JSONField()
layout = models.JSONField(
default=list
)
config = models.JSONField(
default=dict
)

class Meta:
pass
Expand Down
1 change: 1 addition & 0 deletions netbox/extras/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ def get(self, request, id):
config_form = widget.ConfigForm(initial=widget.form_data.get('config'), prefix='config')

return render(request, self.template_name, {
'widget_class': widget.__class__,
'widget_form': widget_form,
'config_form': config_form,
'form_url': reverse('extras:dashboardwidget_config', kwargs={'id': id})
Expand Down
3 changes: 2 additions & 1 deletion netbox/templates/extras/dashboard/widget_config.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
<form hx-post="{{ form_url }}">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title">Widget Configuration</h5>
<h5 class="modal-title">{{ widget_class }} Configuration</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>{{ widget_class.description }}</p>
{% block form %}
{% render_form widget_form %}
{% render_form config_form %}
Expand Down
11 changes: 7 additions & 4 deletions netbox/templates/extras/dashboard/widgets/objectlist.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<div class="htmx-container"
hx-get="{% url viewname %}"
hx-trigger="load"
></div>
{% if htmx_url %}
<div class="htmx-container" hx-get="{{ htmx_url }}{% if page_size %}?per_page={{ page_size }}{% endif %}" hx-trigger="load"></div>
{% else %}
<div class="text-danger text-center">
<i class="mdi mdi-alert"></i> Unable to load content. Invalid view name: <span class="font-monospace">{{ viewname }}</span>
</div>
{% endif %}
2 changes: 1 addition & 1 deletion netbox/templates/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h6 class="alert-heading">
<i class="mdi mdi-plus"></i> Add Widget
</a>
<button id="save_dashboard" class="btn btn-primary btn-sm" data-url="{% url 'extras-api:dashboard' %}">
<i class="mdi mdi-content-save-outline"></i> Save
<i class="mdi mdi-content-save-outline"></i> Save Layout
</button>
</div>
{% endblock content-wrapper %}
Expand Down

0 comments on commit e176c7d

Please sign in to comment.