diff --git a/netbox/extras/dashboard/widgets.py b/netbox/extras/dashboard/widgets.py index 4a5078a93..74e8390c9 100644 --- a/netbox/extras/dashboard/widgets.py +++ b/netbox/extras/dashboard/widgets.py @@ -39,6 +39,9 @@ class DashboardWidget: self.height = height self.x, self.y = x, y + def __str__(self): + return self.title or self.__class__.__name__ + def set_layout(self, grid_item): self.width = grid_item['w'] self.height = grid_item['h'] diff --git a/netbox/extras/urls.py b/netbox/extras/urls.py index 78483d419..6d15038c4 100644 --- a/netbox/extras/urls.py +++ b/netbox/extras/urls.py @@ -88,7 +88,8 @@ urlpatterns = [ path('changelog//', include(get_model_urls('extras', 'objectchange'))), # User dashboard - path('dashboard/widgets/', views.DashboardWidgetConfigView.as_view(), name='dashboardwidget_edit'), + path('dashboard/widgets//configure/', views.DashboardWidgetConfigView.as_view(), name='dashboardwidget_config'), + path('dashboard/widgets//delete/', views.DashboardWidgetDeleteView.as_view(), name='dashboardwidget_delete'), # Reports path('reports/', views.ReportListView.as_view(), name='report_list'), diff --git a/netbox/extras/views.py b/netbox/extras/views.py index 8a9d62709..9e67aa0de 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -12,6 +12,7 @@ from rq import Worker from extras.dashboard.forms import DashboardWidgetForm from extras.dashboard.utils import get_widget_class_and_config from netbox.views import generic +from utilities.forms import ConfirmationForm 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 @@ -674,8 +675,8 @@ class JournalEntryBulkDeleteView(generic.BulkDeleteView): class DashboardWidgetConfigView(LoginRequiredMixin, View): template_name = 'extras/dashboardwidget_edit.html' - def get(self, request): - widget_class, config = get_widget_class_and_config(request.user, request.GET['id']) + def get(self, request, id): + widget_class, config = get_widget_class_and_config(request.user, id) widget_form = DashboardWidgetForm(initial=config) config_form = widget_class.ConfigForm(initial=config.get('config'), prefix='config') @@ -684,8 +685,7 @@ class DashboardWidgetConfigView(LoginRequiredMixin, View): 'config_form': config_form, }) - def post(self, request): - id = request.GET['id'] + def post(self, request, id): widget_class, config = get_widget_class_and_config(request.user, id) widget_form = DashboardWidgetForm(request.POST) config_form = widget_class.ConfigForm(request.POST, prefix='config') @@ -703,6 +703,44 @@ class DashboardWidgetConfigView(LoginRequiredMixin, View): }) +class DashboardWidgetDeleteView(LoginRequiredMixin, View): + template_name = 'generic/object_delete.html' + + def get(self, request, id): + widget_class, config = get_widget_class_and_config(request.user, id) + widget = widget_class(**config) + form = ConfirmationForm(initial=request.GET) + + # If this is an HTMX request, return only the rendered deletion form as modal content + if is_htmx(request): + return render(request, 'htmx/delete_form.html', { + 'object_type': widget_class.__name__, + 'object': widget, + 'form': form, + 'form_url': reverse('extras:dashboardwidget_delete', kwargs={'id': id}) + }) + + return render(request, self.template_name, { + 'form': form, + }) + + def post(self, request, id): + form = ConfirmationForm(request.POST) + + if form.is_valid(): + config = request.user.config + config.clear(f'dashboard.widgets.{id}') + config.set('dashboard.layout', [ + item for item in config.get('dashboard.layout') if item['id'] != str(id) + ]) + config.save() + messages.success(request, f'Deleted widget {id}') + else: + messages.error(request, f'Error deleting widget: {form.errors[0]}') + + return redirect(reverse('home')) + + # # Reports # diff --git a/netbox/templates/extras/dashboard/widget.html b/netbox/templates/extras/dashboard/widget.html index eefa7f0df..f2104e740 100644 --- a/netbox/templates/extras/dashboard/widget.html +++ b/netbox/templates/extras/dashboard/widget.html @@ -11,10 +11,15 @@
- +
- +
{% if widget.title %} {{ widget.title }} diff --git a/netbox/templates/home.html b/netbox/templates/home.html index bf20c1f2c..cd4761f87 100644 --- a/netbox/templates/home.html +++ b/netbox/templates/home.html @@ -35,3 +35,7 @@
{% endblock content-wrapper %} + +{% block modals %} + {% include 'inc/htmx_modal.html' %} +{% endblock modals %}