From 0669c7b86910599cffc6e25890ef099e9232de60 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Fri, 27 Feb 2026 19:03:27 +0000 Subject: [PATCH] Bug 35104: Add 'Mark resolved' button for nonxml_stripped errors in edit form Adds a REST DELETE endpoint and UI button so cataloguers can explicitly dismiss nonxml_stripped data-quality warnings without needing to re-save the record. - DELETE /api/v1/biblios/{biblio_id}/metadata/errors/{error_id} deletes the specific error row; requires edit_catalogue permission. - Koha::REST::V1::Biblios::MetadataErrors controller handles the request, verifying the error belongs to the given biblio before deleting. - The edit form's warning banner now shows a 'Mark resolved' button next to each error. Clicking it fires an AJAX DELETE; on success the row is removed from the DOM and the entire banner is hidden when no errors remain. --- Koha/REST/V1/Biblios/MetadataErrors.pm | 63 +++++++++++++++++++ .../paths/biblios_metadata_errors.yaml | 48 ++++++++++++++ api/v1/swagger/swagger.yaml | 2 + .../prog/en/modules/cataloguing/addbiblio.tt | 25 +++++++- 4 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 Koha/REST/V1/Biblios/MetadataErrors.pm create mode 100644 api/v1/swagger/paths/biblios_metadata_errors.yaml diff --git a/Koha/REST/V1/Biblios/MetadataErrors.pm b/Koha/REST/V1/Biblios/MetadataErrors.pm new file mode 100644 index 00000000000..6f193672f93 --- /dev/null +++ b/Koha/REST/V1/Biblios/MetadataErrors.pm @@ -0,0 +1,63 @@ +package Koha::REST::V1::Biblios::MetadataErrors; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::Biblio::Metadata::Errors; +use Koha::Biblios; + +use Try::Tiny; + +=head1 NAME + +Koha::REST::V1::Biblios::MetadataErrors - REST controller for biblio metadata errors + +=head1 API + +=head2 Methods + +=head3 delete + +Delete (resolve) a single biblio metadata error row. + +=cut + +sub delete { + my $c = shift->openapi->valid_input or return; + + my $biblio = Koha::Biblios->find( $c->param('biblio_id') ); + return $c->render_resource_not_found("Biblio") unless $biblio; + + my $error = Koha::Biblio::Metadata::Errors->find( + { + id => $c->param('error_id'), + metadata_id => $biblio->metadata->id, + } + ); + return $c->render_resource_not_found("Metadata error") unless $error; + + return try { + $error->delete; + return $c->render_resource_deleted; + } catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/api/v1/swagger/paths/biblios_metadata_errors.yaml b/api/v1/swagger/paths/biblios_metadata_errors.yaml new file mode 100644 index 00000000000..a8252831b70 --- /dev/null +++ b/api/v1/swagger/paths/biblios_metadata_errors.yaml @@ -0,0 +1,48 @@ +--- +"/biblios/{biblio_id}/metadata/errors/{error_id}": + delete: + x-mojo-to: Biblios::MetadataErrors#delete + operationId: deleteBiblioMetadataError + tags: + - biblios + summary: Delete a biblio metadata error + description: Deletes a specific metadata error record, marking it as resolved. + parameters: + - name: biblio_id + in: path + description: Internal identifier for the bibliographic record + required: true + type: integer + - name: error_id + in: path + description: Internal identifier for the metadata error + required: true + type: integer + produces: + - application/json + responses: + '204': + description: Metadata error deleted + '401': + description: Authentication required + schema: + "$ref": "../swagger.yaml#/definitions/error" + '403': + description: Access forbidden + schema: + "$ref": "../swagger.yaml#/definitions/error" + '404': + description: Metadata error not found + schema: + "$ref": "../swagger.yaml#/definitions/error" + '500': + description: Internal error + schema: + "$ref": "../swagger.yaml#/definitions/error" + '503': + description: Under maintenance + schema: + "$ref": "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + editcatalogue: edit_catalogue diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 9a9b7af7565..7b6cfcf00d9 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -299,6 +299,8 @@ paths: $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items" "/biblios/{biblio_id}/item_groups/{item_group_id}/items/{item_id}": $ref: "./paths/biblios_item_groups.yaml#/~1biblios~1{biblio_id}~1item_groups~1{item_group_id}~1items~1{item_id}" + "/biblios/{biblio_id}/metadata/errors/{error_id}": + $ref: "./paths/biblios_metadata_errors.yaml#/~1biblios~1{biblio_id}~1metadata~1errors~1{error_id}" "/biblios/{biblio_id}/merge": $ref: "./paths/biblios_merge.yaml#/~1biblios~1{biblio_id}~1merge" /cash_registers: diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt index dea2d4911ad..9614bf5ff3f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/addbiblio.tt @@ -208,6 +208,26 @@ window.scrollTo(0, getScrollto($li.attr("id"), "toolbar")); }); + $("body").on("click", ".nonxml-resolve", function(e){ + e.preventDefault(); + var errorId = $(this).data("error-id"); + var biblioId = $(this).data("biblio-id"); + var $item = $("#nonxml-error-" + errorId); + $.ajax({ + url: "/api/v1/biblios/" + biblioId + "/metadata/errors/" + errorId, + method: "DELETE", + success: function(){ + $item.remove(); + if ( $("#nonxml-error-list li").length === 0 ) { + $("#nonxml-errors-notice").remove(); + } + }, + error: function(){ + alert( _("Failed to mark error as resolved. Please try again.") ); + } + }); + }); + }); function selectTab( tablink ){ @@ -817,9 +837,9 @@

Data quality warnings

Non-XML characters were automatically stripped from this record when it was last saved. Please review the affected fields and correct or confirm the data.

-
    +
      [% FOREACH err IN existing_nonxml_errors %] -
    • +
    • [% IF err.tag %] @@ -827,6 +847,7 @@ [% END %] [% err.message | html %] +
    • [% END %]
    -- 2.53.0