672 lines
35 KiB
HTML
672 lines
35 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}Imaging Studies{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- BEGIN breadcrumb -->
|
|
<ol class="breadcrumb float-xl-end">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'radiology:dashboard' %}">Radiology</a></li>
|
|
<li class="breadcrumb-item active">Imaging Studies</li>
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
Imaging Studies
|
|
<small>Manage and monitor imaging studies</small>
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<!-- BEGIN row -->
|
|
<div class="row">
|
|
<div class="col-xl-12">
|
|
<!-- Statistics Cards -->
|
|
<div class="row mb-3">
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="widget widget-stats bg-blue">
|
|
<div class="stats-icon"><i class="fa fa-camera"></i></div>
|
|
<div class="stats-info">
|
|
<h4>{{ total_studies|default:0 }}</h4>
|
|
<p>Total Studies</p>
|
|
</div>
|
|
<div class="stats-link">
|
|
<a href="javascript:;" onclick="filterByStatus('all')">View All <i class="fa fa-arrow-alt-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="widget widget-stats bg-info">
|
|
<div class="stats-icon"><i class="fa fa-play-circle"></i></div>
|
|
<div class="stats-info">
|
|
<h4>{{ in_progress_studies|default:0 }}</h4>
|
|
<p>In Progress</p>
|
|
</div>
|
|
<div class="stats-link">
|
|
<a href="javascript:;" onclick="filterByStatus('in_progress')">View Details <i class="fa fa-arrow-alt-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="widget widget-stats bg-orange">
|
|
<div class="stats-icon"><i class="fa fa-clock"></i></div>
|
|
<div class="stats-info">
|
|
<h4>{{ pending_studies|default:0 }}</h4>
|
|
<p>Pending</p>
|
|
</div>
|
|
<div class="stats-link">
|
|
<a href="javascript:;" onclick="filterByStatus('pending')">View Details <i class="fa fa-arrow-alt-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="widget widget-stats bg-red">
|
|
<div class="stats-icon"><i class="fa fa-exclamation-triangle"></i></div>
|
|
<div class="stats-info">
|
|
<h4>{{ overdue_studies|default:0 }}</h4>
|
|
<p>Overdue</p>
|
|
</div>
|
|
<div class="stats-link">
|
|
<a href="javascript:;" onclick="filterByStatus('overdue')">View Details <i class="fa fa-arrow-alt-circle-right"></i></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters and Search -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<i class="fa fa-filter me-2"></i>Filters & Search
|
|
</h4>
|
|
<div class="panel-heading-btn">
|
|
<button type="button" class="btn btn-xs btn-icon btn-circle btn-default" onclick="resetFilters()">
|
|
<i class="fa fa-undo"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-xs btn-icon btn-circle btn-default" data-toggle="panel-collapse">
|
|
<i class="fa fa-minus"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<form method="get" id="filterForm" class="row g-3">
|
|
<div class="col-md-3">
|
|
<label for="search" class="form-label">Search</label>
|
|
<input type="text" class="form-control" id="search" name="search"
|
|
value="{{ request.GET.search }}"
|
|
placeholder="Study ID, patient name, MRN...">
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label for="status" class="form-label">Status</label>
|
|
<select class="form-select" id="status" name="status">
|
|
<option value="">All Statuses</option>
|
|
<option value="pending" {% if request.GET.status == 'pending' %}selected{% endif %}>Pending</option>
|
|
<option value="in_progress" {% if request.GET.status == 'in_progress' %}selected{% endif %}>In Progress</option>
|
|
<option value="completed" {% if request.GET.status == 'completed' %}selected{% endif %}>Completed</option>
|
|
<option value="cancelled" {% if request.GET.status == 'cancelled' %}selected{% endif %}>Cancelled</option>
|
|
<option value="on_hold" {% if request.GET.status == 'on_hold' %}selected{% endif %}>On Hold</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label for="modality" class="form-label">Modality</label>
|
|
<select class="form-select" id="modality" name="modality">
|
|
<option value="">All Modalities</option>
|
|
<option value="CT" {% if request.GET.modality == 'CT' %}selected{% endif %}>CT</option>
|
|
<option value="MRI" {% if request.GET.modality == 'MRI' %}selected{% endif %}>MRI</option>
|
|
<option value="X-Ray" {% if request.GET.modality == 'X-Ray' %}selected{% endif %}>X-Ray</option>
|
|
<option value="Ultrasound" {% if request.GET.modality == 'Ultrasound' %}selected{% endif %}>Ultrasound</option>
|
|
<option value="Nuclear" {% if request.GET.modality == 'Nuclear' %}selected{% endif %}>Nuclear Medicine</option>
|
|
<option value="Mammography" {% if request.GET.modality == 'Mammography' %}selected{% endif %}>Mammography</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label for="priority" class="form-label">Priority</label>
|
|
<select class="form-select" id="priority" name="priority">
|
|
<option value="">All Priorities</option>
|
|
<option value="stat" {% if request.GET.priority == 'stat' %}selected{% endif %}>STAT</option>
|
|
<option value="urgent" {% if request.GET.priority == 'urgent' %}selected{% endif %}>Urgent</option>
|
|
<option value="routine" {% if request.GET.priority == 'routine' %}selected{% endif %}>Routine</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label for="date_range" class="form-label">Date Range</label>
|
|
<select class="form-select" id="date_range" name="date_range">
|
|
<option value="">All Dates</option>
|
|
<option value="today" {% if request.GET.date_range == 'today' %}selected{% endif %}>Today</option>
|
|
<option value="yesterday" {% if request.GET.date_range == 'yesterday' %}selected{% endif %}>Yesterday</option>
|
|
<option value="this_week" {% if request.GET.date_range == 'this_week' %}selected{% endif %}>This Week</option>
|
|
<option value="last_week" {% if request.GET.date_range == 'last_week' %}selected{% endif %}>Last Week</option>
|
|
<option value="this_month" {% if request.GET.date_range == 'this_month' %}selected{% endif %}>This Month</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<label class="form-label"> </label>
|
|
<div class="d-grid">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Studies List -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<i class="fa fa-list me-2"></i>Imaging Studies
|
|
{% if object_list %}
|
|
<span class="badge bg-primary ms-2">{{ object_list|length }}</span>
|
|
{% endif %}
|
|
</h4>
|
|
<div class="panel-heading-btn">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-xs btn-primary dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fa fa-download me-1"></i>Export
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="?{{ request.GET.urlencode }}&export=csv">
|
|
<i class="fa fa-file-csv me-2"></i>CSV
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="?{{ request.GET.urlencode }}&export=excel">
|
|
<i class="fa fa-file-excel me-2"></i>Excel
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="?{{ request.GET.urlencode }}&export=pdf">
|
|
<i class="fa fa-file-pdf me-2"></i>PDF
|
|
</a></li>
|
|
</ul>
|
|
</div>
|
|
<button type="button" class="btn btn-xs btn-success" onclick="refreshStudies()">
|
|
<i class="fa fa-refresh"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
{% if object_list %}
|
|
<!-- Bulk Actions -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="d-flex align-items-center">
|
|
<div class="form-check me-3">
|
|
<input class="form-check-input" type="checkbox" id="selectAll">
|
|
<label class="form-check-label" for="selectAll">
|
|
Select All
|
|
</label>
|
|
</div>
|
|
<div class="btn-group" id="bulkActions" style="display: none;">
|
|
<button type="button" class="btn btn-sm btn-outline-primary" onclick="bulkAction('start')">
|
|
<i class="fa fa-play me-1"></i>Start Selected
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-outline-success" onclick="bulkAction('complete')">
|
|
<i class="fa fa-check me-1"></i>Complete Selected
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-outline-warning" onclick="bulkAction('hold')">
|
|
<i class="fa fa-pause me-1"></i>Put on Hold
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-outline-danger" onclick="bulkAction('cancel')">
|
|
<i class="fa fa-times me-1"></i>Cancel Selected
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 text-end">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="toggleView('table')" id="tableViewBtn">
|
|
<i class="fa fa-table me-1"></i>Table
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="toggleView('cards')" id="cardsViewBtn">
|
|
<i class="fa fa-th-large me-1"></i>Cards
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Table View -->
|
|
<div id="tableView">
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-hover" id="studiesTable">
|
|
<thead>
|
|
<tr>
|
|
<th width="30">
|
|
<input type="checkbox" id="selectAllTable">
|
|
</th>
|
|
<th>Study ID</th>
|
|
<th>Patient</th>
|
|
<th>Study Type</th>
|
|
<th>Modality</th>
|
|
<th>Priority</th>
|
|
<th>Status</th>
|
|
<th>Technologist</th>
|
|
<th>Start Time</th>
|
|
<th>Duration</th>
|
|
<th width="120">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for study in object_list %}
|
|
<tr data-study-id="{{ study.id }}">
|
|
<td>
|
|
<input type="checkbox" class="study-checkbox" value="{{ study.id }}">
|
|
</td>
|
|
<td>
|
|
<a href="{% url 'radiology:imaging_study_detail' study.pk %}" class="text-decoration-none">
|
|
{{ study.study_id }}
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<strong>{{ study.patient.get_full_name }}</strong><br>
|
|
<small class="text-muted">MRN: {{ study.patient.medical_record_number }}</small>
|
|
</div>
|
|
</td>
|
|
<td>{{ study.study_type }}</td>
|
|
<td>
|
|
<span class="badge bg-secondary">{{ study.modality }}</span>
|
|
</td>
|
|
<td>
|
|
{% if study.priority == 'stat' %}
|
|
<span class="badge bg-danger">STAT</span>
|
|
{% elif study.priority == 'urgent' %}
|
|
<span class="badge bg-warning text-dark">Urgent</span>
|
|
{% else %}
|
|
<span class="badge bg-success">Routine</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if study.status == 'pending' %}
|
|
<span class="badge bg-secondary">Pending</span>
|
|
{% elif study.status == 'in_progress' %}
|
|
<span class="badge bg-info">In Progress</span>
|
|
{% elif study.status == 'completed' %}
|
|
<span class="badge bg-success">Completed</span>
|
|
{% elif study.status == 'cancelled' %}
|
|
<span class="badge bg-danger">Cancelled</span>
|
|
{% elif study.status == 'on_hold' %}
|
|
<span class="badge bg-warning text-dark">On Hold</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if study.technologist %}
|
|
{{ study.technologist.get_full_name }}
|
|
{% else %}
|
|
<span class="text-muted">Not assigned</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if study.start_time %}
|
|
{{ study.start_time|date:"M d, Y g:i A" }}
|
|
{% else %}
|
|
<span class="text-muted">Not started</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if study.duration %}
|
|
{{ study.duration }} min
|
|
{% else %}
|
|
<span class="text-muted">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="btn-group">
|
|
<a href="{% url 'radiology:imaging_study_detail' study.pk %}"
|
|
class="btn btn-xs btn-outline-primary" title="View Details">
|
|
<i class="fa fa-eye"></i>
|
|
</a>
|
|
{% if study.status == 'pending' %}
|
|
<button type="button" class="btn btn-xs btn-outline-success"
|
|
onclick="startStudy('{{ study.id }}')" title="Start Study">
|
|
<i class="fa fa-play"></i>
|
|
</button>
|
|
{% elif study.status == 'in_progress' %}
|
|
<button type="button" class="btn btn-xs btn-outline-info"
|
|
onclick="completeStudy('{{ study.id }}')" title="Complete Study">
|
|
<i class="fa fa-check"></i>
|
|
</button>
|
|
{% endif %}
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-xs btn-outline-secondary dropdown-toggle"
|
|
data-bs-toggle="dropdown" title="More Actions">
|
|
<i class="fa fa-ellipsis-h"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="{% url 'radiology:imaging_study_update' study.pk %}">
|
|
<i class="fa fa-edit me-2"></i>Edit
|
|
</a></li>
|
|
{% if study.dicom_files.exists %}
|
|
<li><a class="dropdown-item" href="{% url 'radiology:dicom_viewer' study.pk %}">
|
|
<i class="fa fa-image me-2"></i>View Images
|
|
</a></li>
|
|
{% endif %}
|
|
<li><hr class="dropdown-divider"></li>
|
|
{# <li><a class="dropdown-item text-danger" href="{% url 'radiology:im' study.pk %}">#}
|
|
{# <i class="fa fa-trash me-2"></i>Delete#}
|
|
{# </a></li>#}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cards View -->
|
|
<div id="cardsView" style="display: none;">
|
|
<div class="row">
|
|
{% for study in object_list %}
|
|
<div class="col-xl-4 col-lg-6 mb-3">
|
|
<div class="card study-card" data-study-id="{{ study.id }}">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<input type="checkbox" class="study-checkbox me-2" value="{{ study.id }}">
|
|
<strong>{{ study.study_id }}</strong>
|
|
</div>
|
|
<div>
|
|
{% if study.priority == 'stat' %}
|
|
<span class="badge bg-danger">STAT</span>
|
|
{% elif study.priority == 'urgent' %}
|
|
<span class="badge bg-warning text-dark">Urgent</span>
|
|
{% else %}
|
|
<span class="badge bg-success">Routine</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<h6 class="card-title">{{ study.patient.get_full_name }}</h6>
|
|
<p class="card-text">
|
|
<small class="text-muted">MRN: {{ study.patient.medical_record_number }}</small><br>
|
|
<strong>Study:</strong> {{ study.study_type }}<br>
|
|
<strong>Modality:</strong> <span class="badge bg-secondary">{{ study.modality }}</span><br>
|
|
<strong>Status:</strong>
|
|
{% if study.status == 'pending' %}
|
|
<span class="badge bg-secondary">Pending</span>
|
|
{% elif study.status == 'in_progress' %}
|
|
<span class="badge bg-info">In Progress</span>
|
|
{% elif study.status == 'completed' %}
|
|
<span class="badge bg-success">Completed</span>
|
|
{% elif study.status == 'cancelled' %}
|
|
<span class="badge bg-danger">Cancelled</span>
|
|
{% elif study.status == 'on_hold' %}
|
|
<span class="badge bg-warning text-dark">On Hold</span>
|
|
{% endif %}
|
|
</p>
|
|
{% if study.technologist %}
|
|
<p class="card-text">
|
|
<strong>Technologist:</strong> {{ study.technologist.get_full_name }}
|
|
</p>
|
|
{% endif %}
|
|
{% if study.start_time %}
|
|
<p class="card-text">
|
|
<strong>Started:</strong> {{ study.start_time|date:"M d, Y g:i A" }}
|
|
</p>
|
|
{% endif %}
|
|
</div>
|
|
<div class="card-footer">
|
|
<div class="btn-group w-100">
|
|
<a href="{% url 'radiology:imaging_study_detail' study.pk %}"
|
|
class="btn btn-sm btn-outline-primary">
|
|
<i class="fa fa-eye me-1"></i>View
|
|
</a>
|
|
{% if study.status == 'pending' %}
|
|
<button type="button" class="btn btn-sm btn-outline-success"
|
|
onclick="startStudy('{{ study.id }}')">
|
|
<i class="fa fa-play me-1"></i>Start
|
|
</button>
|
|
{% elif study.status == 'in_progress' %}
|
|
<button type="button" class="btn btn-sm btn-outline-info"
|
|
onclick="completeStudy('{{ study.id }}')">
|
|
<i class="fa fa-check me-1"></i>Complete
|
|
</button>
|
|
{% endif %}
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle"
|
|
data-bs-toggle="dropdown">
|
|
<i class="fa fa-ellipsis-h"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="{% url 'radiology:imaging_study_update' study.pk %}">
|
|
<i class="fa fa-edit me-2"></i>Edit
|
|
</a></li>
|
|
{% if study.dicom_files.exists %}
|
|
<li><a class="dropdown-item" href="{% url 'radiology:dicom_viewer' study.pk %}">
|
|
<i class="fa fa-image me-2"></i>View Images
|
|
</a></li>
|
|
{% endif %}
|
|
<li><hr class="dropdown-divider"></li>
|
|
{# <li><a class="dropdown-item text-danger" href="{% url 'radiology:imaging_study_delete' study.pk %}">#}
|
|
{# <i class="fa fa-trash me-2"></i>Delete#}
|
|
{# </a></li>#}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{% if is_paginated %}
|
|
<nav aria-label="Studies pagination">
|
|
<ul class="pagination justify-content-center">
|
|
{% if page_obj.has_previous %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?{{ request.GET.urlencode }}&page=1">First</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?{{ request.GET.urlencode }}&page={{ page_obj.previous_page_number }}">Previous</a>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for num in page_obj.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="?{{ request.GET.urlencode }}&page={{ num }}">{{ num }}</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if page_obj.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?{{ request.GET.urlencode }}&page={{ page_obj.next_page_number }}">Next</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?{{ request.GET.urlencode }}&page={{ page_obj.paginator.num_pages }}">Last</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
{% else %}
|
|
<div class="text-center py-5">
|
|
<i class="fa fa-camera fa-3x text-muted mb-3"></i>
|
|
<h5 class="text-muted">No imaging studies found</h5>
|
|
<p class="text-muted">No studies match your current filters.</p>
|
|
<button type="button" class="btn btn-primary" onclick="resetFilters()">
|
|
<i class="fa fa-undo me-1"></i>Reset Filters
|
|
</button>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END row -->
|
|
|
|
<!-- Quick Action Modals -->
|
|
<div class="modal fade" id="startStudyModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Start Study</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<!-- Start study form content -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="completeStudyModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Complete Study</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<!-- Complete study form content -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Auto-refresh every 30 seconds
|
|
setInterval(function() {
|
|
if ($('#auto-refresh').is(':checked')) {
|
|
refreshStudies();
|
|
}
|
|
}, 30000);
|
|
|
|
// Handle select all checkboxes
|
|
$('#selectAll, #selectAllTable').change(function() {
|
|
var isChecked = $(this).is(':checked');
|
|
$('.study-checkbox').prop('checked', isChecked);
|
|
toggleBulkActions();
|
|
});
|
|
|
|
// Handle individual checkboxes
|
|
$(document).on('change', '.study-checkbox', function() {
|
|
toggleBulkActions();
|
|
updateSelectAllState();
|
|
});
|
|
|
|
// Initialize DataTable for better sorting and searching
|
|
$('#studiesTable').DataTable({
|
|
"pageLength": 25,
|
|
"order": [[ 8, "desc" ]], // Sort by start time
|
|
"columnDefs": [
|
|
{ "orderable": false, "targets": [0, 10] } // Disable sorting for checkbox and actions
|
|
]
|
|
});
|
|
});
|
|
|
|
function filterByStatus(status) {
|
|
$('#status').val(status);
|
|
$('#filterForm').submit();
|
|
}
|
|
|
|
function resetFilters() {
|
|
$('#filterForm')[0].reset();
|
|
window.location.href = window.location.pathname;
|
|
}
|
|
|
|
function toggleView(viewType) {
|
|
if (viewType === 'table') {
|
|
$('#tableView').show();
|
|
$('#cardsView').hide();
|
|
$('#tableViewBtn').addClass('active');
|
|
$('#cardsViewBtn').removeClass('active');
|
|
} else {
|
|
$('#tableView').hide();
|
|
$('#cardsView').show();
|
|
$('#tableViewBtn').removeClass('active');
|
|
$('#cardsViewBtn').addClass('active');
|
|
}
|
|
localStorage.setItem('studiesViewType', viewType);
|
|
}
|
|
|
|
function toggleBulkActions() {
|
|
var checkedCount = $('.study-checkbox:checked').length;
|
|
if (checkedCount > 0) {
|
|
$('#bulkActions').show();
|
|
} else {
|
|
$('#bulkActions').hide();
|
|
}
|
|
}
|
|
|
|
function updateSelectAllState() {
|
|
var totalCheckboxes = $('.study-checkbox').length;
|
|
var checkedCheckboxes = $('.study-checkbox:checked').length;
|
|
|
|
$('#selectAll, #selectAllTable').prop('checked', totalCheckboxes === checkedCheckboxes);
|
|
}
|
|
|
|
function bulkAction(action) {
|
|
var selectedStudies = $('.study-checkbox:checked').map(function() {
|
|
return $(this).val();
|
|
}).get();
|
|
|
|
if (selectedStudies.length === 0) {
|
|
alert('Please select at least one study.');
|
|
return;
|
|
}
|
|
|
|
var actionText = {
|
|
'start': 'start',
|
|
'complete': 'complete',
|
|
'hold': 'put on hold',
|
|
'cancel': 'cancel'
|
|
};
|
|
|
|
if (confirm(`Are you sure you want to ${actionText[action]} ${selectedStudies.length} selected studies?`)) {
|
|
// Perform bulk action via AJAX
|
|
$.ajax({
|
|
url: '',
|
|
method: 'POST',
|
|
data: {
|
|
'action': action,
|
|
'study_ids': selectedStudies,
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
location.reload();
|
|
} else {
|
|
alert('Error: ' + response.message);
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('An error occurred while processing the request.');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function startStudy(studyId) {
|
|
// Load start study modal
|
|
$('#startStudyModal').modal('show');
|
|
}
|
|
|
|
function completeStudy(studyId) {
|
|
// Load complete study modal
|
|
$('#completeStudyModal').modal('show');
|
|
}
|
|
|
|
function refreshStudies() {
|
|
location.reload();
|
|
}
|
|
|
|
// Load saved view preference
|
|
$(document).ready(function() {
|
|
var savedView = localStorage.getItem('studiesViewType') || 'table';
|
|
toggleView(savedView);
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|