Skip to content

Commit

Permalink
Merge pull request #665 from opensafely-core/datatable-csv
Browse files Browse the repository at this point in the history
Create a custom datatable component for Airlock
  • Loading branch information
tomodwyer authored Sep 12, 2024
2 parents 8160145 + 8ac805a commit f0a156e
Show file tree
Hide file tree
Showing 19 changed files with 391 additions and 259 deletions.
1 change: 0 additions & 1 deletion airlock/static/assets/activity.js

This file was deleted.

41 changes: 0 additions & 41 deletions airlock/static/assets/datatable-loader.js

This file was deleted.

26 changes: 0 additions & 26 deletions airlock/static/assets/datatable.css

This file was deleted.

14 changes: 0 additions & 14 deletions airlock/static/assets/file_browser/dir.css

This file was deleted.

10 changes: 4 additions & 6 deletions airlock/static/assets/file_browser/dir.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// ensure datatable is initialised when loading over HTMX
window.initCustomTable ? window.initCustomTable() : null;

// implement select all checkbox
function toggleSelectAll(elem, event) {
function toggleSelectAll(elem) {
const form = document.querySelector("#multiselect_form");

const checkboxes = form.querySelectorAll('input[type="checkbox"]');
/** @type {NodeListOf<HTMLInputElement>|undefined} */
const checkboxes = form?.querySelectorAll('input[type="checkbox"]');

checkboxes.forEach(function(checkbox) {
checkboxes?.forEach(function(checkbox) {
checkbox.checked = elem.checked;
});
}
13 changes: 13 additions & 0 deletions airlock/templates/_components/datatable.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div class="table-container">
<p class="spinner p-4" data-datatable-spinner>Loading table data...</p>
<table
class="{{ class }} hidden"
data-datatable
{% if per_page %}
data-per-page="{{ per_page }}"
{% endif %}
{% attrs id data-column-filter=column_filter data-sortable=sortable data-searchable=searchable %}
>
{{ children }}
</table>
</div>
130 changes: 55 additions & 75 deletions airlock/templates/activity.html
Original file line number Diff line number Diff line change
@@ -1,88 +1,68 @@
{% load airlock %}
{% load django_vite %}
{% load static %}

<link rel="stylesheet" href="{% static 'assets/datatable.css' %}">

{% #card title="Recent activity" %}
{% #card title="Recent activity" class="mt-5" %}
{% if activity %}
<div id="airlock-table">
<p class="spinner">Loading table data...</p>
<table class="datatable hidden" id="customTable">
<thead>
{% #datatable per_page="10" column_filter searchable sortable %}
<thead>
<tr>
<th>
<div class="flex flex-row gap-2 items-center">
Time
<span class="sort-icon h-4 w-4 [&_img]:h-4 [&_img]:w-4">
{% datatable_sort_icon %}
</span>
</div>
</th>
<th>
<div class="flex flex-row gap-2 items-center">
User
<span class="sort-icon h-4 w-4 [&_img]:h-4 [&_img]:w-4">
{% datatable_sort_icon %}
</span>
</div>
</th>
<th>
<div class="flex flex-row gap-2 items-center">
Action
<span class="sort-icon h-4 w-4 [&_img]:h-4 [&_img]:w-4">
{% datatable_sort_icon %}
</span>
</div>
</th>
<th>
<div class="flex flex-row gap-2 items-center">
Details
<span class="sort-icon h-4 w-4 [&_img]:h-4 [&_img]:w-4">
{% datatable_sort_icon %}
</span>
</div>
</th>
</tr>
</thead>
<tbody>
{% for log in activity %}
<tr>
<th><div class="flex flex-row gap-2">Time{% datatable_sort_icon %}</div></th>
<th><div class="flex flex-row gap-2">User{% datatable_sort_icon %}</div></th>
<th><div class="flex flex-row gap-2">Action{% datatable_sort_icon %}</div></th>
<th><div class="flex flex-row gap-2">Details{% datatable_sort_icon %}</div></th>
<td>{{ log.created_at|date:'Y-m-d H:i' }}</td>
<td>{{ log.user }}</td>
<td>{{ log.description }}</td>
<td>
<ul>
{% if log.path %}<li><b>path:</b> {{ log.path }}</li>{% endif %}
{% for k,v in log.extra.items %}
<li><b>{{ k }}:</b> {{ v }}</li>
{% endfor %}
</ul>
</td>
</tr>
</thead>
<tbody>
{% for log in activity %}
<tr>
<td>{{ log.created_at|date:'Y-m-d H:i' }}</td>
<td>{{ log.user }}</td>
<td>{{ log.description }}</td>
<td>
<ul>
{% if log.path %}<li><b>path:</b> {{ log.path }}</li>{% endif %}
{% for k,v in log.extra.items %}
<li><b>{{ k }}:</b> {{ v }}</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</table>

<nav id="pagination-nav" class="hidden flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3" aria-label="Pagination">
<div class="sm:block">
<p class="text-sm text-gray-700">
Page
<strong data-table-pagination="page-number">#</strong>
of
<strong data-table-pagination="total-pages">#</strong>
</p>
</div>
<div class="flex flex-1 justify-between gap-4 sm:justify-end">
<button
data-table-pagination="previous-page"
class="
px-4 py-2 text-sm font-medium
inline-flex items-center justify-center border rounded-md shadow-sm transition-buttons duration-200
border border-slate-400/75 text-slate-700 !shadow-none
hover:bg-slate-200
focus:bg-slate-200 focus:ring-slate-500 focus:ring-offset-white
hover:shadow-lg
focus:outline-none focus:ring-2 focus:ring-offset-2"
>
Previous
</button>
<button
data-table-pagination="next-page"
class="
px-4 py-2 text-sm font-medium
inline-flex items-center justify-center border rounded-md shadow-sm transition-buttons duration-200
border border-slate-400/75 text-slate-700 !shadow-none
hover:bg-slate-200
focus:bg-slate-200 focus:ring-slate-500 focus:ring-offset-white
hover:shadow-lg
focus:outline-none focus:ring-2 focus:ring-offset-2"
>
Next
</button>
</div>
</nav>
</div>
{% endfor %}
</tbody>
{% /datatable %}
{% else %}
{% #list_group %}
{% list_group_empty title="No activity" description="There has been no recent activity on this workspace" %}
{% /list_group %}
{% endif %}
{% /card %}

{% vite_asset "assets/src/scripts/components.js" app="job_server" %}
<script defer src="{% static 'assets/activity.js' %}"></script>
<script defer src="{% static 'assets/datatable-loader.js' %}"></script>
{% vite_asset "assets/src/scripts/datatable.js" %}
88 changes: 53 additions & 35 deletions airlock/templates/file_browser/file_content/csv.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,70 @@
{% load static %}

<!DOCTYPE html>
<html lang="en">
<html lang="en" class="min-h-screen">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

{% vite_hmr_client %}
{% vite_asset "assets/src/scripts/base.js" app="job_server" %}
{% vite_asset "assets/src/scripts/components.js" app="job_server" %}
<link rel="stylesheet" href="{% static 'assets/datatable.css' %}">
<link rel="stylesheet" href="{% static 'assets/icons.css' %}">
{% vite_asset "assets/src/scripts/main.js" %}
{% vite_asset "assets/src/scripts/datatable.js" %}
</head>

<body>

<div id="airlock-table">
{% if use_datatables %}
<p class="spinner">Loading table data...</p>
<table class="datatable hidden" id="customTable">
{% #datatable column_filter searchable sortable %}
<thead>
<tr>
{% for header in headers %}
<th>
<div class="flex flex-row gap-2 items-center">
{{ header }}
<span class="sort-icon h-4 w-4 [&_img]:h-4 [&_img]:w-4">
{% datatable_sort_icon %}
</span>
</div>
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% for cell in row %}
<td data-order="{{ cell }}">{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
{% /datatable %}
{% else %}
<table>
{% endif %}
<thead>
<tr>
{% for header in headers %}
<th>
<div class="flex flex-row gap-2">
{{ header }}
{% if use_datatables %}
<span class="sort-icon">{% datatable_sort_icon %}</span>
{% endif %}
</dir>
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% for cell in row %}
<td data-order="{{ cell }}">{{ cell }}</td>
<thead>
<tr>
{% for header in headers %}
<th>
{{ header }}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>

</div>
</tbody>
</table>
{% endif %}

<script src="{% static 'assets/datatable-loader.js' %}"></script>
</body>
</div>
</body>

</html>
Loading

0 comments on commit f0a156e

Please sign in to comment.