Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bulk actions on report overview #3777

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions rocky/assets/js/grabSelectionOnModalOpen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { onDomReady } from "./imports/utils.js";
import {
renderRenameSelection,
renderDeleteSelection,
renderRerunSelection,
} from "./reportActionForms.js";

onDomReady(function () {
if (getSelection().length > 0) {
openDialogFromUrl(getAnchor());
} else {
closeDialog(getAnchor());
}
});

export function openDialogFromUrl(anchor) {
// If ID is present in the URL on DomReady, open the dialog immediately.
let id = window.location.hash.slice(1);

if (id) {
let modal = document.querySelector("#" + id);

if (anchor == "rename-modal") {
renderRenameSelection(modal, getSelection());
}
if (anchor == "delete-modal") {
renderDeleteSelection(modal, getSelection());
}
if (anchor == "rerun-modal") {
renderRerunSelection(modal, getSelection());
}
}
}

export function closeDialog(anchor) {
// If ID is present in the URL on DomReady, open the dialog immediately.
let id = window.location.hash.slice(1);

if (id) {
let modal = document.querySelector("#" + id);
modal.close();
}

let baseUrl = window.location.toString().split("#")[0];
window.history.pushState("", "Base URL", baseUrl);
}

export function getSelection() {
let checkedItems = document.querySelectorAll(".report-checkbox:checked");
return checkedItems;
}

addEventListener("hashchange", function () {
if (getSelection().length > 0) {
openDialogFromUrl(getAnchor());
} else {
closeDialog(getAnchor());
}
});

function getAnchor() {
let currentUrl = document.URL;
let urlParts = currentUrl.split("#");

return urlParts.length > 1 ? urlParts[1] : null;
}
155 changes: 155 additions & 0 deletions rocky/assets/js/reportActionForms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
export function renderRenameSelection(modal, selection) {
let report_names = getReportNames(selection);
let references = [];

selection.forEach((input_element) => {
references.push(input_element.value);
});

let table_element = document.getElementById("rename-table");
let table_body = table_element.querySelector("tbody");
let table_row = table_element.querySelector("tr.rename-table-row");

table_body.innerHTML = "";

for (let i = 0; i < references.length; i++) {
let table_row_copy = table_row.cloneNode(true);

let type_td = table_row_copy.querySelector("td.type");
let name_input_element = table_row_copy.querySelector(".report-name-input");
let reference_input_element = table_row_copy.querySelector(
".report-reference-input",
);
let date_td = table_row_copy.querySelector("td.date");

name_input_element.setAttribute("value", report_names[i]);
reference_input_element.setAttribute("value", references[i]);

type_td.innerText = "type";
date_td.innerText = "date";

table_body.appendChild(table_row_copy);
}
}

export function renderDeleteSelection(modal, selection) {
let report_names = getReportNames(selection);
let references = [];

selection.forEach((input_element) => {
references.push(input_element.value);
});

let table_element = document.getElementById("delete-table");
let table_body = table_element.querySelector("tbody");
let table_row = table_element.querySelector("tr.delete-table-row");

table_body.innerHTML = "";

for (let i = 0; i < references.length; i++) {
let table_row_copy = table_row.cloneNode(true);

let reference_input_element = table_row_copy.querySelector(
".report-reference-input",
);

// let type_td = table_row_copy.querySelector("td.type");
// let date_td = table_row_copy.querySelector("td.date");
let name_span = table_row_copy.querySelector("td.name span.name-holder");

name_span.innerText = report_names[i];
reference_input_element.setAttribute("value", references[i]);

// type_td.innerText = "type";
// date_td.innerText = "date";

table_body.appendChild(table_row_copy);
}
}

export function renderRerunSelection(modal, selection) {
let report_names = getReportNames(selection);
let references = [];

selection.forEach((input_element) => {
references.push(input_element.value);
});

let table_element = document.getElementById("rerun-table");
let table_body = table_element.querySelector("tbody");
let table_row = table_element.querySelector("tr.rerun-table-row");

table_body.innerHTML = "";

for (let i = 0; i < references.length; i++) {
let table_row_copy = table_row.cloneNode(true);

let reference_input_element = table_row_copy.querySelector(
".report-reference-input",
);

// let type_td = table_row_copy.querySelector("td.type");
// let date_td = table_row_copy.querySelector("td.date");
let name_span = table_row_copy.querySelector("td.name span.name-holder");

name_span.innerText = report_names[i];
reference_input_element.setAttribute("value", references[i]);

// type_td.innerText = "type";
// date_td.innerText = "date";

table_body.appendChild(table_row_copy);
}
}

// export function renderDeleteSelection(modal, selection) {
// let form_element = document.getElementById("delete-form");
// let csrf_token_element = form_element.querySelector(
// "input[name='csrfmiddlewaretoken']",
// );
// let report_names = getReportNames(selection);

// let content_element = modal.querySelector(".content");
// content_element.innerHTML = "";

// let header_element = document.createElement("h3");
// header_element.innerText =
// "Are you sure you want to permanently delete the following report(s):";

// report_names.forEach((report_name) => {
// let name_input_element = document.createElement("input");
// name_input_element.setAttribute("type", "text");
// name_input_element.setAttribute("value", report_name);
// name_input_element.setAttribute("readonly", "true");

// let reference_input_element = document.createElement("input");
// reference_input_element.setAttribute("type", "hidden");
// reference_input_element.setAttribute("value", report_name);
// reference_input_element.setAttribute("name", "report_reference");

// form_element.appendChild(reference_input_element);
// form_element.appendChild(name_input_element);
// });

// content_element.appendChild(csrf_token_element);
// content_element.appendChild(header_element);
// content_element.appendChild(form_element);
// }

export function getReportNames(selection) {
let report_names = [];

for (let i = 0; i < selection.length; i++) {
let report_name = selection[i]
.closest("tr")
?.querySelector("td.report_name a")?.innerText;

if (!report_name) {
continue;
}

report_names.push(report_name);
}

return report_names;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{% load i18n %}

{% component 'modal' size='dialog-large' modal_id='delete-modal' %}
{% fill 'header' %}{% translate "Delete the following report(s):" %}{% endfill %}
{% fill 'content' %}
<p>
{% blocktranslate %}
Deleted reports are removed in the view from the moment of deletion. The report can still be accessed on timestamps before the deletion. Only the report is removed from the view, not the data it is based on.
{% endblocktranslate %}
</p>
<p>
{% blocktranslate %}
It is still possible to generate a new report for same date. If the report is part of a combined report, it will remain available in the combined report.
{% endblocktranslate %}
</p>
<form id="delete-form" class="inline layout-wide" method="post">
{% csrf_token %}
<table id="delete-table">
<thead>
<tr>
{% comment %} <th>{% translate "Report type" %}</th> {% endcomment %}
<th>{% translate "Name" %}</th>
{% comment %} <th>{% translate "Reference date" %}</th> {% endcomment %}
</tr>
</thead>
<tbody>
<tr class="delete-table-row">
{% comment %} <td class="type"></td> {% endcomment %}
<td class="name">
<span class="name-holder"></span>
<input type="hidden" name="report_reference" class="report-reference-input" />
</td>
{% comment %} <td class="date"></td> {% endcomment %}
</tr>
</tbody>
</table>
</form>
{% endfill %}
{% fill "footer_buttons" %}
<button type="submit"
form="delete-form"
class="destructive"
name="action"
value="delete">{% translate "Delete" %}</button>
{% endfill %}
{% endcomponent %}
{% component_css_dependencies %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{% load i18n %}

{% component "modal" size="dialog-large" modal_id="rename-modal" %}
{% fill "header" %}
{% translate "Rename the following report(s):" %}
{% endfill %}
{% fill "content" %}
<form id="rename-form" class="inline layout-wide" method="post">
{% csrf_token %}
<table id="rename-table">
<thead>
<tr>
<th>{% translate "Report type" %}</th>
<th>{% translate "Name" %}</th>
<th>{% translate "Reference date" %}</th>
</tr>
</thead>
<tbody>
<tr class="rename-table-row">
<td class="type"></td>
<td class="name">
<input type="text" name="report_name" class="report-name-input">
<input type="hidden" name="report_reference" class="report-reference-input">
</td>
<td class="date"></td>
</tr>
</tbody>
</table>
</form>
{% endfill %}
{% fill "footer_buttons" %}
<button type="submit"
form="rename-form"
class="submit"
name="action"
value="rename">{% translate "Rename" %}</button>
{% endfill %}
{% endcomponent %}
{% component_css_dependencies %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% load i18n %}

{% component 'modal' size='dialog-large' modal_id='rerun-modal' %}
{% fill 'header' %}{% translate "Rerun the following report(s):" %}{% endfill %}
{% fill 'content' %}
<p>
{% blocktranslate %}
By submitting you're generating the selected reports again, using the current data.
{% endblocktranslate %}
</p>
<form id="rerun-form" class="inline layout-wide" method="post">
{% csrf_token %}
<table id="rerun-table">
<thead>
<tr>
{% comment %} <th>{% translate "Report type" %}</th> {% endcomment %}
<th>{% translate "Name" %}</th>
{% comment %} <th>{% translate "Reference date" %}</th> {% endcomment %}
</tr>
</thead>
<tbody>
<tr class="rerun-table-row">
{% comment %} <td class="type"></td> {% endcomment %}
<td class="name">
<span class="name-holder"></span>
<input type="hidden" name="report_reference" class="report-reference-input" />
</td>
{% comment %} <td class="date"></td> {% endcomment %}
</tr>
</tbody>
</table>
</form>
{% endfill %}
{% fill "footer_buttons" %}
<button type="submit"
form="rerun-form"
class="submit"
name="action"
value="rerun">{% translate "Rerun" %}</button>
{% endfill %}
{% endcomponent %}
{% component_css_dependencies %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{% load i18n %}

{% component 'modal' size='dialog-large' modal_id='delete-modal' %}
{% fill 'header' %}{% translate "Delete the following report(s):" %}{% endfill %}
{% fill 'content' %}
<p>
{% blocktranslate %}
Deleted reports are removed in the view from the moment of deletion. The report can still be accessed on timestamps before the deletion. Only the report is removed from the view, not the data it is based on.
{% endblocktranslate %}
</p>
<p>
{% blocktranslate %}
It is still possible to generate a new report for same date. If the report is part of a combined report, it will remain available in the combined report.
{% endblocktranslate %}
</p>
<form id="delete-form" class="inline layout-wide" method="post">
{% csrf_token %}
<table id="delete-table">
<thead>
<tr>
{% comment %} <th>{% translate "Report type" %}</th> {% endcomment %}
<th>{% translate "Name" %}</th>
{% comment %} <th>{% translate "Reference date" %}</th> {% endcomment %}
</tr>
</thead>
<tbody>
<tr class="delete-table-row">
{% comment %} <td class="type"></td> {% endcomment %}
<td class="name">
<span class="name-holder"></span>
<input type="hidden" name="report_reference" class="report-reference-input" />
</td>
{% comment %} <td class="date"></td> {% endcomment %}
</tr>
</tbody>
</table>
</form>
{% endfill %}
{% fill "footer_buttons" %}
<input type="submit" form="delete-form" class="destructive" value="Delete" />
{% endfill %}
{% endcomponent %}
{% component_css_dependencies %}
Loading
Loading