Add widget deletion view

This commit is contained in:
jeremystretch 2023-02-21 21:29:49 -05:00
parent 289836f9f6
commit f521268a28
5 changed files with 58 additions and 7 deletions

View File

@ -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']

View File

@ -88,7 +88,8 @@ urlpatterns = [
path('changelog/<int:pk>/', include(get_model_urls('extras', 'objectchange'))),
# User dashboard
path('dashboard/widgets/', views.DashboardWidgetConfigView.as_view(), name='dashboardwidget_edit'),
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'),
# Reports
path('reports/', views.ReportListView.as_view(), name='report_list'),

View File

@ -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
#

View File

@ -11,10 +11,15 @@
<div class="card grid-stack-item-content">
<div class="card-header text-center text-light bg-secondary p-1">
<div class="float-start ps-1">
<a href="{% url 'extras:dashboardwidget_edit' %}?id={{ widget.id }}"><i class="mdi mdi-cog text-gray"></i></a>
<a href="{% url 'extras:dashboardwidget_config' id=widget.id %}"><i class="mdi mdi-cog text-gray"></i></a>
</div>
<div class="float-end pe-1">
<a href="#"><i class="mdi mdi-close text-gray"></i></a>
<a href="#"
hx-get="{% url 'extras:dashboardwidget_delete' id=widget.id %}"
hx-target="#htmx-modal-content"
data-bs-toggle="modal"
data-bs-target="#htmx-modal"
><i class="mdi mdi-close text-gray"></i></a>
</div>
{% if widget.title %}
<strong>{{ widget.title }}</strong>

View File

@ -35,3 +35,7 @@
</button>
</div>
{% endblock content-wrapper %}
{% block modals %}
{% include 'inc/htmx_modal.html' %}
{% endblock modals %}