578 lines
36 KiB
HTML
578 lines
36 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}System Notifications{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Breadcrumb -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="page-title-box d-sm-flex align-items-center justify-content-between">
|
|
<h4 class="mb-sm-0">System Notifications</h4>
|
|
<div class="page-title-right">
|
|
<ol class="breadcrumb m-0">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item active">System Notifications</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters and Actions -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="d-flex flex-wrap gap-3">
|
|
<!-- Search Form -->
|
|
<div class="flex-grow-1">
|
|
<form method="get" class="d-flex gap-2">
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
|
<input type="text" class="form-control" name="search" placeholder="Search notifications..." value="{{ request.GET.search|default:'' }}">
|
|
</div>
|
|
<button type="submit" class="btn btn-primary">Search</button>
|
|
{% if request.GET.search or request.GET.status or request.GET.priority or request.GET.category %}
|
|
<a href="{% url 'core:system_notification_list' %}" class="btn btn-outline-secondary">Clear</a>
|
|
{% endif %}
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="d-flex gap-2">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fas fa-filter me-1"></i>
|
|
Filter
|
|
</button>
|
|
<div class="dropdown-menu p-3" style="min-width: 250px;">
|
|
<form method="get">
|
|
<div class="mb-3">
|
|
<label class="form-label">Status</label>
|
|
<select name="status" class="form-select">
|
|
<option value="">All</option>
|
|
<option value="active" {% if request.GET.status == 'active' %}selected{% endif %}>Active</option>
|
|
<option value="inactive" {% if request.GET.status == 'inactive' %}selected{% endif %}>Inactive</option>
|
|
<option value="scheduled" {% if request.GET.status == 'scheduled' %}selected{% endif %}>Scheduled</option>
|
|
<option value="expired" {% if request.GET.status == 'expired' %}selected{% endif %}>Expired</option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Priority</label>
|
|
<select name="priority" class="form-select">
|
|
<option value="">All</option>
|
|
<option value="LOW" {% if request.GET.priority == 'LOW' %}selected{% endif %}>Low</option>
|
|
<option value="MEDIUM" {% if request.GET.priority == 'MEDIUM' %}selected{% endif %}>Medium</option>
|
|
<option value="HIGH" {% if request.GET.priority == 'HIGH' %}selected{% endif %}>High</option>
|
|
<option value="CRITICAL" {% if request.GET.priority == 'CRITICAL' %}selected{% endif %}>Critical</option>
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Category</label>
|
|
<select name="category" class="form-select">
|
|
<option value="">All</option>
|
|
{% for category in categories %}
|
|
<option value="{{ category }}" {% if request.GET.category == category %}selected{% endif %}>{{ category }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="d-grid">
|
|
<button type="submit" class="btn btn-primary">Apply Filters</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fas fa-sort me-1"></i>
|
|
Sort
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="?{% if request.GET.search %}search={{ request.GET.search }}&{% endif %}sort=priority">Priority</a></li>
|
|
<li><a class="dropdown-item" href="?{% if request.GET.search %}search={{ request.GET.search }}&{% endif %}sort=start_date">Start Date</a></li>
|
|
<li><a class="dropdown-item" href="?{% if request.GET.search %}search={{ request.GET.search }}&{% endif %}sort=end_date">End Date</a></li>
|
|
<li><a class="dropdown-item" href="?{% if request.GET.search %}search={{ request.GET.search }}&{% endif %}sort=created_at">Created Date</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fas fa-cog me-1"></i>
|
|
Actions
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="#" onclick="bulkActivate()">Activate Selected</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="bulkDeactivate()">Deactivate Selected</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="bulkDelete()">Delete Selected</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item" href="#" onclick="exportNotifications()">Export Notifications</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<a href="{% url 'core:system_notification_create' %}" class="btn btn-success">
|
|
<i class="fas fa-plus me-1"></i>
|
|
New Notification
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- View Toggle -->
|
|
<div class="row mb-3">
|
|
<div class="col-12">
|
|
<div class="btn-group" role="group">
|
|
<input type="radio" class="btn-check" name="viewMode" id="tableView" autocomplete="off" checked>
|
|
<label class="btn btn-outline-primary" for="tableView">
|
|
<i class="fas fa-table me-1"></i>
|
|
Table View
|
|
</label>
|
|
|
|
<input type="radio" class="btn-check" name="viewMode" id="cardView" autocomplete="off">
|
|
<label class="btn btn-outline-primary" for="cardView">
|
|
<i class="fas fa-th-large me-1"></i>
|
|
Card View
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Table View -->
|
|
<div class="row" id="tableViewContent">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<form id="bulkActionForm" method="post" action="">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="action" id="bulkAction" value="">
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-hover align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 30px;">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="selectAll">
|
|
</div>
|
|
</th>
|
|
<th>Title</th>
|
|
<th>Priority</th>
|
|
<th>Category</th>
|
|
<th>Status</th>
|
|
<th>Period</th>
|
|
<th style="width: 150px;">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for notification in notifications %}
|
|
<tr>
|
|
<td>
|
|
<div class="form-check">
|
|
<input class="form-check-input notification-checkbox" type="checkbox" name="selected_ids" value="{{ notification.pk }}">
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-shrink-0">
|
|
<div class="avatar-xs me-2">
|
|
<span class="avatar-title rounded-circle bg-{% if notification.priority == 'LOW' %}success{% elif notification.priority == 'MEDIUM' %}info{% elif notification.priority == 'HIGH' %}warning{% elif notification.priority == 'CRITICAL' %}danger{% else %}secondary{% endif %} text-white">
|
|
<i class="fas fa-{% if notification.priority == 'LOW' %}info{% elif notification.priority == 'MEDIUM' %}exclamation{% elif notification.priority == 'HIGH' %}exclamation-triangle{% elif notification.priority == 'CRITICAL' %}radiation{% else %}bell{% endif %}"></i>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<a href="{% url 'core:system_notification_detail' notification.pk %}" class="text-reset fw-medium">{{ notification.title }}</a>
|
|
<p class="text-muted mb-0 small">{{ notification.message|truncatechars:50 }}</p>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-{% if notification.priority == 'LOW' %}success{% elif notification.priority == 'MEDIUM' %}info{% elif notification.priority == 'HIGH' %}warning{% elif notification.priority == 'CRITICAL' %}danger{% else %}secondary{% endif %}">
|
|
{{ notification.get_priority_display }}
|
|
</span>
|
|
</td>
|
|
<td>{{ notification.category }}</td>
|
|
<td>
|
|
{% if notification.is_active %}
|
|
{% if notification.start_date <= now and notification.end_date >= now %}
|
|
<span class="badge bg-success">Active</span>
|
|
{% elif notification.start_date > now %}
|
|
<span class="badge bg-info">Scheduled</span>
|
|
{% elif notification.end_date < now %}
|
|
<span class="badge bg-secondary">Expired</span>
|
|
{% endif %}
|
|
{% else %}
|
|
<span class="badge bg-danger">Inactive</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<small class="d-block">From: {{ notification.start_date|date:"M d, Y" }}</small>
|
|
<small class="d-block">To: {{ notification.end_date|date:"M d, Y" }}</small>
|
|
</td>
|
|
<td>
|
|
<div class="dropdown">
|
|
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
Actions
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="{% url 'core:system_notification_detail' notification.pk %}">
|
|
<i class="fas fa-eye me-2"></i>View
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="{% url 'core:system_notification_update' notification.pk %}">
|
|
<i class="fas fa-edit me-2"></i>Edit
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="{% url 'core:system_notification_delete' notification.pk %}">
|
|
<i class="fas fa-trash me-2"></i>Delete
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
{% if notification.is_active %}
|
|
<li><a class="dropdown-item" href="{% url 'core:deactivate_notification' notification.pk %}">
|
|
<i class="fas fa-power-off me-2"></i>Deactivate
|
|
</a></li>
|
|
{% else %}
|
|
<li><a class="dropdown-item" href="{% url 'core:activate_notification' notification.pk %}">
|
|
<i class="fas fa-power-off me-2"></i>Activate
|
|
</a></li>
|
|
{% endif %}
|
|
|
|
</ul>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="7" class="text-center py-4">
|
|
<div class="d-flex flex-column align-items-center">
|
|
<i class="fas fa-bell-slash fa-3x text-muted mb-3"></i>
|
|
<h5>No notifications found</h5>
|
|
<p class="text-muted">No system notifications match your criteria.</p>
|
|
<a href="{% url 'core:system_notification_create' %}" class="btn btn-primary mt-2">
|
|
<i class="fas fa-plus me-1"></i>
|
|
Create New Notification
|
|
</a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Pagination -->
|
|
{% if is_paginated %}
|
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
|
<div>
|
|
Showing {{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ paginator.count }} notifications
|
|
</div>
|
|
<nav>
|
|
<ul class="pagination mb-0">
|
|
{% if page_obj.has_previous %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page=1{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-double-left"></i>
|
|
</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-left"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for num in paginator.page_range %}
|
|
{% if page_obj.number == num %}
|
|
<li class="page-item active">
|
|
<span class="page-link">{{ num }}</span>
|
|
</li>
|
|
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ num }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">{{ num }}</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if page_obj.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-right"></i>
|
|
</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ paginator.num_pages }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-double-right"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Card View -->
|
|
<div class="row" id="cardViewContent" style="display: none;">
|
|
{% for notification in notifications %}
|
|
<div class="col-md-6 col-lg-4 col-xl-3">
|
|
<div class="card">
|
|
<div class="card-header bg-{% if notification.priority == 'LOW' %}success{% elif notification.priority == 'MEDIUM' %}info{% elif notification.priority == 'HIGH' %}warning{% elif notification.priority == 'CRITICAL' %}danger{% else %}secondary{% endif %} bg-opacity-25">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-shrink-0">
|
|
<div class="avatar-sm me-2">
|
|
<span class="avatar-title rounded-circle bg-{% if notification.priority == 'LOW' %}success{% elif notification.priority == 'MEDIUM' %}info{% elif notification.priority == 'HIGH' %}warning{% elif notification.priority == 'CRITICAL' %}danger{% else %}secondary{% endif %} text-white">
|
|
<i class="fas fa-{% if notification.priority == 'LOW' %}info{% elif notification.priority == 'MEDIUM' %}exclamation{% elif notification.priority == 'HIGH' %}exclamation-triangle{% elif notification.priority == 'CRITICAL' %}radiation{% else %}bell{% endif %}"></i>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<h5 class="card-title mb-0">{{ notification.title|truncatechars:30 }}</h5>
|
|
<small class="text-muted">{{ notification.category }}</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="card-text">{{ notification.message|truncatechars:100 }}</p>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<span class="badge bg-{% if notification.priority == 'LOW' %}success{% elif notification.priority == 'MEDIUM' %}info{% elif notification.priority == 'HIGH' %}warning{% elif notification.priority == 'CRITICAL' %}danger{% else %}secondary{% endif %}">
|
|
{{ notification.get_priority_display }}
|
|
</span>
|
|
|
|
{% if notification.is_active %}
|
|
{% if notification.start_date <= now and notification.end_date >= now %}
|
|
<span class="badge bg-success">Active</span>
|
|
{% elif notification.start_date > now %}
|
|
<span class="badge bg-info">Scheduled</span>
|
|
{% elif notification.end_date < now %}
|
|
<span class="badge bg-secondary">Expired</span>
|
|
{% endif %}
|
|
{% else %}
|
|
<span class="badge bg-danger">Inactive</span>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="small text-muted mb-3">
|
|
<div><i class="fas fa-calendar-alt me-1"></i> From: {{ notification.start_date|date:"M d, Y" }}</div>
|
|
<div><i class="fas fa-calendar-check me-1"></i> To: {{ notification.end_date|date:"M d, Y" }}</div>
|
|
</div>
|
|
|
|
<div class="d-grid gap-2">
|
|
<a href="{% url 'core:system_notification_detail' notification.pk %}" class="btn btn-sm btn-outline-primary">
|
|
<i class="fas fa-eye me-1"></i>
|
|
View Details
|
|
</a>
|
|
<div class="btn-group" role="group">
|
|
<a href="{% url 'core:system_notification_update' notification.pk %}" class="btn btn-sm btn-outline-secondary">
|
|
<i class="fas fa-edit"></i>
|
|
</a>
|
|
{% if notification.is_active %}
|
|
<a href="{% url 'core:deactivate_notification' notification.pk %}" class="btn btn-sm btn-outline-secondary">
|
|
<i class="fas fa-power-off"></i>
|
|
</a>
|
|
{% else %}
|
|
<a href="{% url 'core:activate_notification' notification.pk %}" class="btn btn-sm btn-outline-secondary">
|
|
<i class="fas fa-power-off"></i>
|
|
</a>
|
|
{% endif %}
|
|
<a href="{% url 'core:system_notification_delete' notification.pk %}" class="btn btn-sm btn-outline-danger">
|
|
<i class="fas fa-trash"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-footer text-muted">
|
|
<small>Created: {{ notification.created_at|date:"M d, Y" }}</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-body text-center py-5">
|
|
<i class="fas fa-bell-slash fa-3x text-muted mb-3"></i>
|
|
<h5>No notifications found</h5>
|
|
<p class="text-muted">No system notifications match your criteria.</p>
|
|
<a href="{% url 'core:system_notification_create' %}" class="btn btn-primary mt-2">
|
|
<i class="fas fa-plus me-1"></i>
|
|
Create New Notification
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
<!-- Pagination for Card View -->
|
|
{% if is_paginated %}
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
Showing {{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ paginator.count }} notifications
|
|
</div>
|
|
<nav>
|
|
<ul class="pagination mb-0">
|
|
{% if page_obj.has_previous %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page=1{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-double-left"></i>
|
|
</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-left"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for num in paginator.page_range %}
|
|
{% if page_obj.number == num %}
|
|
<li class="page-item active">
|
|
<span class="page-link">{{ num }}</span>
|
|
</li>
|
|
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ num }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">{{ num }}</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if page_obj.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-right"></i>
|
|
</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ paginator.num_pages }}{% if request.GET.search %}&search={{ request.GET.search }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.priority %}&priority={{ request.GET.priority }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.sort %}&sort={{ request.GET.sort }}{% endif %}">
|
|
<i class="fas fa-angle-double-right"></i>
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// View toggle
|
|
const tableView = document.getElementById('tableView');
|
|
const cardView = document.getElementById('cardView');
|
|
const tableViewContent = document.getElementById('tableViewContent');
|
|
const cardViewContent = document.getElementById('cardViewContent');
|
|
|
|
tableView.addEventListener('change', function() {
|
|
if (this.checked) {
|
|
tableViewContent.style.display = 'flex';
|
|
cardViewContent.style.display = 'none';
|
|
localStorage.setItem('notificationViewMode', 'table');
|
|
}
|
|
});
|
|
|
|
cardView.addEventListener('change', function() {
|
|
if (this.checked) {
|
|
tableViewContent.style.display = 'none';
|
|
cardViewContent.style.display = 'flex';
|
|
localStorage.setItem('notificationViewMode', 'card');
|
|
}
|
|
});
|
|
|
|
// Load saved view preference
|
|
const savedViewMode = localStorage.getItem('notificationViewMode');
|
|
if (savedViewMode === 'card') {
|
|
cardView.checked = true;
|
|
tableViewContent.style.display = 'none';
|
|
cardViewContent.style.display = 'flex';
|
|
} else {
|
|
tableView.checked = true;
|
|
}
|
|
|
|
// Select all checkboxes
|
|
const selectAll = document.getElementById('selectAll');
|
|
const checkboxes = document.querySelectorAll('.notification-checkbox');
|
|
|
|
selectAll.addEventListener('change', function() {
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.checked = this.checked;
|
|
});
|
|
});
|
|
|
|
checkboxes.forEach(checkbox => {
|
|
checkbox.addEventListener('change', function() {
|
|
const allChecked = Array.from(checkboxes).every(c => c.checked);
|
|
const anyChecked = Array.from(checkboxes).some(c => c.checked);
|
|
|
|
selectAll.checked = allChecked;
|
|
selectAll.indeterminate = anyChecked && !allChecked;
|
|
});
|
|
});
|
|
});
|
|
|
|
function bulkActivate() {
|
|
if (confirmBulkAction('activate')) {
|
|
document.getElementById('bulkAction').value = 'activate';
|
|
document.getElementById('bulkActionForm').submit();
|
|
}
|
|
}
|
|
|
|
function bulkDeactivate() {
|
|
if (confirmBulkAction('deactivate')) {
|
|
document.getElementById('bulkAction').value = 'deactivate';
|
|
document.getElementById('bulkActionForm').submit();
|
|
}
|
|
}
|
|
|
|
function bulkDelete() {
|
|
if (confirmBulkAction('delete')) {
|
|
document.getElementById('bulkAction').value = 'delete';
|
|
document.getElementById('bulkActionForm').submit();
|
|
}
|
|
}
|
|
|
|
function confirmBulkAction(action) {
|
|
const checkboxes = document.querySelectorAll('.notification-checkbox:checked');
|
|
|
|
if (checkboxes.length === 0) {
|
|
alert('Please select at least one notification.');
|
|
return false;
|
|
}
|
|
|
|
let message = '';
|
|
switch (action) {
|
|
case 'activate':
|
|
message = `Are you sure you want to activate ${checkboxes.length} notification(s)?`;
|
|
break;
|
|
case 'deactivate':
|
|
message = `Are you sure you want to deactivate ${checkboxes.length} notification(s)?`;
|
|
break;
|
|
case 'delete':
|
|
message = `Are you sure you want to delete ${checkboxes.length} notification(s)? This action cannot be undone.`;
|
|
break;
|
|
}
|
|
|
|
return confirm(message);
|
|
}
|
|
|
|
{#function exportNotifications() {#}
|
|
{# window.open('{% url "core:export_notifications" %}', '_blank');#}
|
|
{# }#}
|
|
</script>
|
|
{% endblock %}
|
|
|