From 2433c079e11825109dcf22aadddec8f97db9b0dc Mon Sep 17 00:00:00 2001 From: Jacob O'Mara Date: Thu, 30 Oct 2025 12:03:43 +0000 Subject: [PATCH] Bug 17387: add modal for restoring biblios with item selection --- .../prog/en/modules/tools/restore-records.tt | 235 ++++++++++++++++-- 1 file changed, 210 insertions(+), 25 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/restore-records.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/restore-records.tt index c0b48b85070..134f1e6bef7 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/restore-records.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/restore-records.tt @@ -105,6 +105,49 @@ + + + [% MACRO jsinclude BLOCK %] [% Asset.js("js/tools-menu.js") | $raw %] [% INCLUDE 'datatables.inc' %] @@ -126,6 +169,7 @@ ajax: { url: "/api/v1/deleted/biblios", }, + embed: "items", order: [[3, "desc"]], columns: [ { @@ -274,41 +318,100 @@ }); var items_table_api = items_table.DataTable(); + // Initialize the modal items table as kohaTable + var modal_items_table = null; + var modal_items_table_api = null; + // Restore biblio handler $("#deleted_biblios_table").on("click", ".restore-biblio", function (e) { e.preventDefault(); var button = $(this); var biblio_id = button.data("biblio-id"); var title = button.data("title"); + var row = biblios_table_api.row(button.closest("tr")).data(); - if (!confirm(_("Are you sure you want to restore bibliographic record %s '%s'?").format(biblio_id, title))) { - return; + // Populate modal with biblio info + $("#restore-modal-biblio-id").text(biblio_id); + $("#restore-modal-biblio-title").text(title || _("(No title)")); + $("#restore-modal-biblio-author").text(row.author || _("(No author)")); + + // Check if there are deleted items + var items = row.items || []; + if (items.length > 0) { + $("#items-section").show(); + + // Destroy existing DataTable if it exists + if (modal_items_table_api) { + modal_items_table_api.destroy(); + } + + // Initialize kohaTable with the items data + modal_items_table = $("#deleted-items-list").kohaTable({ + data: items, + paging: false, + info: false, + columns: [ + { + data: function (row, type) { + if (type === "display") { + return ''; + } + return ""; + }, + searchable: false, + orderable: false, + }, + { + data: "item_id", + searchable: true, + orderable: true, + }, + { + data: "external_id", + searchable: true, + orderable: true, + render: function (data, type, row) { + if (type === "display") { + return data ? $("
").text(data).html() : _("(No barcode)"); + } + return data || ""; + }, + }, + { + data: "callnumber", + searchable: true, + orderable: true, + render: function (data, type, row) { + if (type === "display") { + return data ? $("
").text(data).html() : ""; + } + return data || ""; + }, + }, + { + data: "home_library_id", + searchable: true, + orderable: true, + render: function (data, type, row) { + if (type === "display") { + return data ? $("
").text(data).html() : ""; + } + return data || ""; + }, + }, + ], + }); + modal_items_table_api = modal_items_table.DataTable(); + } else { + $("#items-section").hide(); } - button.prop("disabled", true); + // Store biblio data + $("#restore-biblio-with-items-button").data("biblio-id", biblio_id); + $("#restore-biblio-with-items-button").data("restore-button", button); - $.ajax({ - url: "/api/v1/deleted/biblios/" + biblio_id, - type: "POST", - headers: { - "x-koha-request-id": Math.random(), - }, - success: function (data) { - $("#messages").append( - '
' + '' + _("Bibliographic record %s restored successfully").format(biblio_id) + "
" - ); - biblios_table_api.ajax.reload(); - items_table_api.ajax.reload(); - }, - error: function (xhr) { - var error_msg = _("Error restoring bibliographic record %s").format(biblio_id); - if (xhr.responseJSON && xhr.responseJSON.error) { - error_msg += ": " + xhr.responseJSON.error; - } - $("#messages").append('
' + '' + error_msg + "
"); - button.prop("disabled", false); - }, - }); + var modal = new bootstrap.Modal(document.getElementById("restoreBiblioModal")); + modal.show(); }); // Restore item handler @@ -395,6 +498,88 @@ }, }); }); + + // Select all items checkbox + $("#select-all-items").on("change", function () { + var checked = $(this).prop("checked"); + $(".item-checkbox").prop("checked", checked); + }); + + // Restore biblio with items + $("#restore-biblio-with-items-button").on("click", function () { + var button = $(this); + var biblio_id = button.data("biblio-id"); + var restore_button = button.data("restore-button"); + + button.prop("disabled", true); + + $.ajax({ + url: "/api/v1/deleted/biblios/" + biblio_id, + type: "PUT", + headers: { + "x-koha-request-id": Math.random(), + }, + success: function (data) { + showMessage(_("Bibliographic record %s restored successfully").format(biblio_id), "success"); + + var selected_items = []; + $(".item-checkbox:checked").each(function () { + selected_items.push($(this).data("item-id")); + }); + + if (selected_items.length > 0) { + var items_restored = 0; + var items_failed = 0; + + selected_items.forEach(function (item_id) { + $.ajax({ + url: "/api/v1/deleted/items/" + item_id, + type: "PUT", + headers: { + "x-koha-request-id": Math.random(), + }, + success: function (data) { + items_restored++; + if (items_restored + items_failed === selected_items.length) { + if (items_restored > 0) { + showMessage(_("%s item(s) restored successfully").format(items_restored), "success"); + } + if (items_failed > 0) { + showMessage(_("%s item(s) failed to restore").format(items_failed), "danger"); + } + items_table_api.ajax.reload(); + } + }, + error: function (xhr) { + items_failed++; + if (items_restored + items_failed === selected_items.length) { + if (items_restored > 0) { + showMessage(_("%s item(s) restored successfully").format(items_restored), "success"); + } + if (items_failed > 0) { + showMessage(_("%s item(s) failed to restore").format(items_failed), "danger"); + } + items_table_api.ajax.reload(); + } + }, + }); + }); + } + + bootstrap.Modal.getInstance(document.getElementById("restoreBiblioModal")).hide(); + biblios_table_api.ajax.reload(); + button.prop("disabled", false); + }, + error: function (xhr) { + var error_msg = _("Error restoring bibliographic record %s").format(biblio_id); + if (xhr.responseJSON && xhr.responseJSON.error) { + error_msg += ": " + xhr.responseJSON.error; + } + showMessage(error_msg, "danger"); + button.prop("disabled", false); + }, + }); + }); }); [% END %] -- 2.39.5