Bug 41579: suggestions - auto tidy

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Jonathan Druart 2026-01-09 13:16:33 +01:00 committed by Lucas Gass
parent 8f7e3d85f9
commit f2425666c9
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
1 changed files with 142 additions and 134 deletions

View File

@ -1256,35 +1256,35 @@
const managedby_patron_borrowernumber = "[% suggestion.manager.borrowernumber | html %]";
const op = "[% op | html %]";
</script>
<script>
function select_manager(borrowernumber, borrower) {
let tab = $('#suggestiontabs .active table').data('tab-name');
if ( tab ) {
var managedby_name = $("#managedby_name-"+tab);
var managedby = $("#managedby-"+tab);
let tab = $("#suggestiontabs .active table").data("tab-name");
if (tab) {
var managedby_name = $("#managedby_name-" + tab);
var managedby = $("#managedby-" + tab);
} else {
var managedby_name = $("#managedby_name");
var managedby = $("#managedby");
}
managedby_name.empty();
managedby.val('');
var borrowername = borrower.firstname + ' ' + borrower.surname;
managedby.val("");
var borrowername = borrower.firstname + " " + borrower.surname;
if (borrowernumber) {
var managerlink = '<a href="/cgi-bin/koha/members/moremember.pl'
+ '?borrowernumber=' + borrowernumber + '">'
+ borrowername + '</a>';
var managerlink = '<a href="/cgi-bin/koha/members/moremember.pl' + "?borrowernumber=" + borrowernumber + '">' + borrowername + "</a>";
managedby_name.html(managerlink);
managedby.val(borrowernumber);
}
if (op == "save"){
var notify = $('#notify');
if ( notify.length ) {
if ((managedby_patron_borrowernumber && (borrowernumber == logged_in_user_borrowernumber || borrowernumber == managedby_patron_borrowernumber )) || (!managedby_patron_borrowernumber && borrowernumber == logged_in_user_borrowernumber )){
$(notify).prop('checked', false).prop('disabled', true);
if (op == "save") {
var notify = $("#notify");
if (notify.length) {
if (
(managedby_patron_borrowernumber && (borrowernumber == logged_in_user_borrowernumber || borrowernumber == managedby_patron_borrowernumber)) ||
(!managedby_patron_borrowernumber && borrowernumber == logged_in_user_borrowernumber)
) {
$(notify).prop("checked", false).prop("disabled", true);
} else {
$(notify).prop('disabled', false);
$(notify).prop("disabled", false);
}
}
}
@ -1292,19 +1292,18 @@
function select_suggester(borrowernumber, borrower) {
$.ajax({
type: 'GET',
url: '/api/v1/patrons/' + borrowernumber,
type: "GET",
url: "/api/v1/patrons/" + borrowernumber,
headers: {
"x-koha-embed": "+strings"
"x-koha-embed": "+strings",
},
success: function (data) {
var suggested = '<input type="hidden" id="suggestedby" name="suggestedby" value="' + data.patron_id + '" />';
suggested += '<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=' + data.patron_id + '">';
suggested += data.surname.escapeHtml() + ', ' + data.firstname.escapeHtml() + ' (' + data.cardnumber.escapeHtml() + ')';
suggested += '</a> ';
suggested += data._strings.library_id.str.escapeHtml() + ' (' + data._strings.category_id.str.escapeHtml() + ')';
suggested += data.surname.escapeHtml() + ", " + data.firstname.escapeHtml() + " (" + data.cardnumber.escapeHtml() + ")";
suggested += "</a> ";
suggested += data._strings.library_id.str.escapeHtml() + " (" + data._strings.category_id.str.escapeHtml() + ")";
$("#tdsuggestedby").html(suggested);
},
error: function (data) {
alert(_("Cannot retrieve info for this patron."));
@ -1316,14 +1315,13 @@
//keep a copy of all budgets before removing the inactives
var budgetId = $("#budgetid");
var disabledBudgetsCopy = budgetId.html();
$('.b_inactive').remove();
$(".b_inactive").remove();
$('.showallfunds').click(function() {
$(".showallfunds").click(function () {
if ($(this).is(":checked")) {
budgetId.html(disabledBudgetsCopy); //Puts back all the funds
}
else {
$('.b_inactive').remove();
} else {
$(".b_inactive").remove();
}
});
</script>
@ -1346,13 +1344,12 @@
CAN_user_suggestions_suggestions_delete: [% CAN_user_suggestions_suggestions_delete ? 1 : 0 | html %],
});
</script>
[% INCLUDE 'datatables.inc' %]
<script>
$(document).ready(function() {
if (has_suggestions){
$(document).ready(function () {
if (has_suggestions) {
function loadDatatable(tabName) {
let tabSuggestionData = suggestionData.find(s => s.suggestiontype === `${tabName}`)
let tabSuggestionData = suggestionData.find(s => s.suggestiontype === `${tabName}`);
$("#table_" + tabName).kohaTable(
{
order: [[4, "asc"]],
@ -1372,7 +1369,7 @@
orderable: false,
render: function (data, type, row, meta) {
return '<input type="checkbox" value="%s" name="suggestionid" />'.format(row.suggestion_id);
}
},
},
{
data: "me.title",
@ -1380,20 +1377,20 @@
orderable: true,
render: function (data, type, row, meta) {
let node = '<a href="suggestion.pl?suggestionid=%s&amp;op=show" title="%s">%s'.format(row.suggestion_id, _("suggestion"), row.title);
if(row.author) node += ', by %s'.format(row.author);
node += '</a><br />';
if(row.copyright_date) node += ' &copy; <span class="suggestion_copyrightdate">%s</span>'.format(row.copyright_date);
if(row.volume_desc) node += '; <span class="suggestion_volume">%s:<em>%s</em></span>'.format(_("Volume"), row.volume_desc);
if(row.isbn) node += '; <span class="suggestion_isbn">%s:<em>%s</em></span>'.format(_("ISBN"), row.isbn);
if(row.publisher_code) node += '; <span class="suggestion_publishercode">%s %s</span>'.format(_("Published by"), row.publisher_code);
if(row.publication_year && row.publication_year != 0) node += '; <span class="suggestion_publicationyear"><em>%s</em></span>'.format(row.publication_year);
if(row.publication_place) node += '; <span class="suggestion_place"><em>%s</em></span>'.format(row.publication_place);
if(row.collection_title) node += '; <span class="suggestion_collectiontitle"><em>%s</em></span>'.format(row.collection_title);
if(row.item_type && row._strings.item_type.str) node += '; <span class="suggestion_itype"><em>%s</em></span>'.format(row._strings.item_type.str);
if(row.note) node += '<div class="suggestion_note">%s</div>'.format(row.note);
if(row.archived) node += '<br /><i class="fa fa-archive"></i> %s'.format(_("Archived"));
if (row.author) node += ", by %s".format(row.author);
node += "</a><br />";
if (row.copyright_date) node += ' &copy; <span class="suggestion_copyrightdate">%s</span>'.format(row.copyright_date);
if (row.volume_desc) node += '; <span class="suggestion_volume">%s:<em>%s</em></span>'.format(_("Volume"), row.volume_desc);
if (row.isbn) node += '; <span class="suggestion_isbn">%s:<em>%s</em></span>'.format(_("ISBN"), row.isbn);
if (row.publisher_code) node += '; <span class="suggestion_publishercode">%s %s</span>'.format(_("Published by"), row.publisher_code);
if (row.publication_year && row.publication_year != 0) node += '; <span class="suggestion_publicationyear"><em>%s</em></span>'.format(row.publication_year);
if (row.publication_place) node += '; <span class="suggestion_place"><em>%s</em></span>'.format(row.publication_place);
if (row.collection_title) node += '; <span class="suggestion_collectiontitle"><em>%s</em></span>'.format(row.collection_title);
if (row.item_type && row._strings.item_type.str) node += '; <span class="suggestion_itype"><em>%s</em></span>'.format(row._strings.item_type.str);
if (row.note) node += '<div class="suggestion_note">%s</div>'.format(row.note);
if (row.archived) node += '<br /><i class="fa fa-archive"></i> %s'.format(_("Archived"));
return node;
}
},
},
{
data: "suggester.surname:suggester.firstname:suggester.cardnumber",
@ -1401,22 +1398,22 @@
orderable: true,
render: function (data, type, row, meta) {
let suggester = row.suggester;
if(suggester) {
if (suggester) {
let node = '<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=%s">%s'.format(suggester.patron_id, suggester.surname);
if(suggester.firstname) node += ', %s'.format(suggester.firstname);
if(suggester.cardnumber) node += ' (%s)'.format(suggester.cardnumber);
node += '</a>';
if (suggester.firstname) node += ", %s".format(suggester.firstname);
if (suggester.cardnumber) node += " (%s)".format(suggester.cardnumber);
node += "</a>";
return node;
}
return ''
}
return "";
},
},
{
data: "suggester.category.name",
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.suggester ? row.suggester.category.name : '');
return escape_str(row.suggester ? row.suggester.category.name : "");
},
},
{
@ -1424,7 +1421,7 @@
searchable: false,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.suggestion_date ? $date(row.suggestion_date) : '');
return escape_str(row.suggestion_date ? $date(row.suggestion_date) : "");
},
},
{
@ -1432,7 +1429,7 @@
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row._strings.patron_reason.str ? row._strings.patron_reason.str : '');
return escape_str(row._strings.patron_reason.str ? row._strings.patron_reason.str : "");
},
},
{
@ -1440,13 +1437,13 @@
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
if(row.manager) {
if (row.manager) {
let node = '<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=%s">%s'.format(row.manager?.patron_id, row.manager?.surname);
if(row.manager?.firstname) node += ', %s'.format(row.manager?.firstname);
node += '</a>';
if (row.manager?.firstname) node += ", %s".format(row.manager?.firstname);
node += "</a>";
return node;
}
return ''
return "";
},
},
{
@ -1454,7 +1451,7 @@
searchable: false,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.managed_date ? $date(row.managed_date) : '');
return escape_str(row.managed_date ? $date(row.managed_date) : "");
},
},
{
@ -1462,13 +1459,13 @@
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
if(row.last_modifier) {
if (row.last_modifier) {
let node = '<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=%s">%s'.format(row.last_modifier?.patron_id, row.last_modifier?.surname);
if(row.last_modifier?.firstname) node += ', %s'.format(row.last_modifier?.firstname);
node += '</a>';
if (row.last_modifier?.firstname) node += ", %s".format(row.last_modifier?.firstname);
node += "</a>";
return node;
}
return ''
return "";
},
},
{
@ -1476,7 +1473,7 @@
searchable: false,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.last_status_change_date ? $date(row.last_status_change_date) : '');
return escape_str(row.last_status_change_date ? $date(row.last_status_change_date) : "");
},
},
{
@ -1484,7 +1481,7 @@
searchable: false,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.last_status_change_date ? $date(row.last_status_change_date) : '');
return escape_str(row.last_status_change_date ? $date(row.last_status_change_date) : "");
},
},
{
@ -1492,7 +1489,7 @@
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.library?.name ? row.library.name : '');
return escape_str(row.library?.name ? row.library.name : "");
},
},
{
@ -1500,7 +1497,7 @@
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.fund?.name ? row.fund.name : '');
return escape_str(row.fund?.name ? row.fund.name : "");
},
},
{
@ -1508,7 +1505,7 @@
searchable: false,
orderable: true,
render: function (data, type, row, meta) {
return escape_str(row.staff_note ? row.staff_note : '');
return escape_str(row.staff_note ? row.staff_note : "");
},
},
{
@ -1516,17 +1513,17 @@
searchable: true,
orderable: true,
render: function (data, type, row, meta) {
let node = '';
if(row.status === 'ASKED') node += '<span class="status asked">%s</span>'.format(_("Pending"));
else if(row.status === 'ACCEPTED') node += '<span class="status accepted">%s</span>'.format(_("Accepted"));
else if(row.status === 'ORDERED') node += '<span class="status ordered">%s</span>'.format(_("Ordered"));
else if(row.status === 'REJECTED') node += '<span class="status rejected">%s</span>'.format(_("Rejected"));
else if(row.status === 'CHECKED') node += '<span class="status checked">%s</span>'.format(_("Checked"));
else if(row.status === 'AVAILABLE') node += '<span class="status available">%s</span>'.format(_("Available"));
else if(row._strings.status.str) node += '<span class="status '+ row.status +'">%s</span>'.format(row._strings.status.str);
let node = "";
if (row.status === "ASKED") node += '<span class="status asked">%s</span>'.format(_("Pending"));
else if (row.status === "ACCEPTED") node += '<span class="status accepted">%s</span>'.format(_("Accepted"));
else if (row.status === "ORDERED") node += '<span class="status ordered">%s</span>'.format(_("Ordered"));
else if (row.status === "REJECTED") node += '<span class="status rejected">%s</span>'.format(_("Rejected"));
else if (row.status === "CHECKED") node += '<span class="status checked">%s</span>'.format(_("Checked"));
else if (row.status === "AVAILABLE") node += '<span class="status available">%s</span>'.format(_("Available"));
else if (row._strings.status.str) node += '<span class="status ' + row.status + '">%s</span>'.format(row._strings.status.str);
else node += '<span class="status unknown">%s</span>'.format(_("Status unknown"));
if ( row.reason ) {
node += '<div class="reason" data-reason="'+row.reason+'">('+ row.reason +')</div>';
if (row.reason) {
node += '<div class="reason" data-reason="' + row.reason + '">(' + row.reason + ")</div>";
}
return node;
},
@ -1536,54 +1533,59 @@
searchable: false,
orderable: false,
render: function (data, type, row, meta) {
if (permissions.CAN_user_suggestions_suggestions_manage){
let node = '<div class="btn-group dropup">'
node += '<a class="btn btn-default btn-xs" role="button" href="suggestion.pl?suggestionid=%s&amp;op=edit_form"><i class="fa-solid fa-pencil" aria-hidden="true"></i> %s</a>'.format(row.suggestion_id, _("Edit"))
node += '<a class="btn btn-default btn-xs dropdown-toggle" id="more_actions_%s" role="button" data-bs-toggle="dropdown" href="#"><b class="caret"></b></a>'.format(row.suggestion_id)
node += '<ul class="dropdown-menu" role="menu" aria-labelledby="more_actions_%s">'.format(row.suggestion_id)
if (permissions.CAN_user_suggestions_suggestions_delete){
node += '<li><a href="#" data-op="cud-delete" data-suggestionid="%s" class="dropdown-item trigger_action">%s</a></li>'.format(row.suggestion_id, _("Delete"))
if (permissions.CAN_user_suggestions_suggestions_manage) {
let node = '<div class="btn-group dropup">';
node += '<a class="btn btn-default btn-xs" role="button" href="suggestion.pl?suggestionid=%s&amp;op=edit_form"><i class="fa-solid fa-pencil" aria-hidden="true"></i> %s</a>'.format(
row.suggestion_id,
_("Edit")
);
node += '<a class="btn btn-default btn-xs dropdown-toggle" id="more_actions_%s" role="button" data-bs-toggle="dropdown" href="#"><b class="caret"></b></a>'.format(row.suggestion_id);
node += '<ul class="dropdown-menu" role="menu" aria-labelledby="more_actions_%s">'.format(row.suggestion_id);
if (permissions.CAN_user_suggestions_suggestions_delete) {
node += '<li><a href="#" data-op="cud-delete" data-suggestionid="%s" class="dropdown-item trigger_action">%s</a></li>'.format(row.suggestion_id, _("Delete"));
}
if (!row.archived){
node += '<li><a href="#" class="dropdown-item trigger_action" data-op="cud-archive" data-suggestionid="%s">%s</a></li>'.format(row.suggestion_id, _("Archive"))
if (!row.archived) {
node += '<li><a href="#" class="dropdown-item trigger_action" data-op="cud-archive" data-suggestionid="%s">%s</a></li>'.format(row.suggestion_id, _("Archive"));
} else {
node += '<li><a href="#" class="dropdown-item trigger_action" data-op="cud-unarchive" data-suggestionid="%s">%s</a></li>'.format(row.suggestion_id, _("Unarchive"))
node += '<li><a href="#" class="dropdown-item trigger_action" data-op="cud-unarchive" data-suggestionid="%s">%s</a></li>'.format(row.suggestion_id, _("Unarchive"));
}
node += '</ul></div>'
return node
} else if (permissions.CAN_user_suggestions_suggestions_delete){
return '<button data-op="cud-delete" data-suggestionid="%s" class="btn btn-xs btn-default trigger_action"><i class="fa fa-trash-can"></i> %s</button>'.format(row.suggestion_id, _("Delete"))
node += "</ul></div>";
return node;
} else if (permissions.CAN_user_suggestions_suggestions_delete) {
return '<button data-op="cud-delete" data-suggestionid="%s" class="btn btn-xs btn-default trigger_action"><i class="fa fa-trash-can"></i> %s</button>'.format(row.suggestion_id, _("Delete"));
}
},
createdCell: function (cell, cellData, rowData, rowIndex, colIndex) {
$(cell).find(".trigger_action").on("click", function(e) {
var id = $(this).data('suggestionid');
var op = $(this).data('op');
if ( op == 'cud-delete' && !confirm(_("Are you sure you want to delete this suggestion?")) ) {
e.preventDefault();
$(cell)
.find(".trigger_action")
.on("click", function (e) {
var id = $(this).data("suggestionid");
var op = $(this).data("op");
if (op == "cud-delete" && !confirm(_("Are you sure you want to delete this suggestion?"))) {
e.preventDefault();
return false;
}
$('#action_form input[name="op"]').val(op);
$('#action_form input[name="suggestionid"]').val(id);
$("#action_form").submit();
return false;
}
$('#action_form input[name="op"]').val(op);
$('#action_form input[name="suggestionid"]').val(id);
$('#action_form').submit();
return false;
})
}
});
},
},
]
],
},
suggestions_table_settings
);
}
if( $("#suggestiontabs .tab-pane.active").length < 1 ){
if ($("#suggestiontabs .tab-pane.active").length < 1) {
$("#suggestiontabs a:first").tab("show");
loadDatatable($("#suggestiontabs a:first").data("tabname"))
$("#suggestiontabs a:first").attr("data-table_loaded", 'true')
loadDatatable($("#suggestiontabs a:first").data("tabname"));
$("#suggestiontabs a:first").attr("data-table_loaded", "true");
}
suggestionData.forEach(suggestion => {
$(`#suggestiontabs #${suggestion.suggestiontype}-tab`).on("click", function() {
if(!$(this).data("table_loaded")) {
$(`#suggestiontabs #${suggestion.suggestiontype}-tab`).on("click", function () {
if (!$(this).data("table_loaded")) {
loadDatatable(`${suggestion.suggestiontype}`);
$(this).attr("data-table_loaded", "true");
}
@ -1591,65 +1593,71 @@
});
}
$("#branchcode").on('change',function(){
$("#branchcode").on("change", function () {
// Modify the hidden input in the filters block from the library
// dropdown list at the top of suggestion list
let branchcode = $(this).val();
$('input[name="branchcode"]').val( branchcode );
$('input[name="branchcode"]').val(branchcode);
$('form[name="suggestionfilter"]').submit();
});
$(".checkall").click(function(e){
$(".checkall").click(function (e) {
e.preventDefault();
$(this).parents('form').find("input:checkbox").each(function(){
$(this).prop("checked", true);
});
$(this)
.parents("form")
.find("input:checkbox")
.each(function () {
$(this).prop("checked", true);
});
});
$(".uncheckall").click(function(e){
$(".uncheckall").click(function (e) {
e.preventDefault();
$(this).parents('form').find("input:checkbox").each(function(){
$(this).prop("checked", false);
});
$(this)
.parents("form")
.find("input:checkbox")
.each(function () {
$(this).prop("checked", false);
});
});
$(".other_reason").hide();
$("select[name='reason']").change(function(){
if($(this).val() == "other"){
$("select[name='reason']").change(function () {
if ($(this).val() == "other") {
$(this).hide();
$(this).siblings(".other_reason").show();
}
});
$("a.cancel_note").click(function(e) {
$(this).parent().siblings("select").show().find("option[value='']").attr("selected","selected");
$("a.cancel_note").click(function (e) {
$(this).parent().siblings("select").show().find("option[value='']").attr("selected", "selected");
$(this).siblings("input[name='other_reason']").hide();
e.preventDefault();
});
$("h4.local_collapse a").on("click", function(e){
$("h4.local_collapse a").on("click", function (e) {
e.preventDefault();
const target = $(this).data("target");
$("." + target).toggle();
});
$("form.update_suggestions button[type='submit']").on("click", function(e) {
$("form.update_suggestions button[type='submit']").on("click", function (e) {
var submit_button = this;
var op = $(submit_button).data('op');
var selected_suggestions = $('form.update_suggestions').find("input[type='checkbox'][name='suggestionid']:checked");
var op = $(submit_button).data("op");
var selected_suggestions = $("form.update_suggestions").find("input[type='checkbox'][name='suggestionid']:checked");
if ( selected_suggestions.length == 0 ) {
if (selected_suggestions.length == 0) {
alert(_("Please select at least one suggestion"));
e.preventDefault();
return false;
}
if ( op === "cud-delete" ) {
if ( ! confirm(_("Are you sure you want to delete these suggestions?")) ) {
if (op === "cud-delete") {
if (!confirm(_("Are you sure you want to delete these suggestions?"))) {
e.preventDefault();
return false;
}
} else if ( op === "cud-update_manager" ) {
} else if (op === "cud-update_manager") {
var managedby = $(submit_button).siblings("suggestion_managedby");
if ( managedby.val() == "" ) {
if (managedby.val() == "") {
alert(_("Please select a manager to assign to the selected suggestions"));
e.preventDefault();
return false;